-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement automatic redirects for requests regardless of the HttpClient
#2214
Labels
s: feature
This issue indicates a feature request
Comments
My solution: import 'package:dio/dio.dart';
typedef RedirectCallback = bool Function(
Response response, ResponseInterceptorHandler handler);
class RedirectInterceptor extends Interceptor {
final Dio _dio;
RedirectCallback? _redirectCallback;
static const String followRedirects = "followRedirects";
static const String rawUri = "rawUri";
static const String rawRequestOption = "rawRequestOption";
static const String redirectCount = "redirectCount";
RedirectInterceptor(this._dio, {RedirectCallback? onRedirect})
: _redirectCallback = onRedirect;
@override
Future<void> onResponse(
Response response, ResponseInterceptorHandler handler) async {
final isFollowRedirects =
response.requestOptions.extra[followRedirects] as bool? ?? true;
if (!isFollowRedirects) {
handler.next(response);
return;
}
final rawUriValue = response.requestOptions.extra[rawUri] as Uri?;
if (rawUriValue == null) {
response.requestOptions.extra[rawUri] = response.requestOptions.uri;
}
final rawRequestOptionValue = response.requestOptions.extra[rawRequestOption];
if (rawRequestOptionValue == null){
response.requestOptions.extra[rawRequestOption] = response.requestOptions;
}
if (_isRedirect(response.statusCode ?? 0)) {
try {
final redirectCountValue =
response.requestOptions.extra[redirectCount] ?? 0;
if (redirectCountValue >= 5) {
handler.next(response);
return;
}
if (_redirectCallback != null &&
!_redirectCallback!.call(response, handler)) {
return;
}
final location = response.headers.value('location');
if (location == null) throw Exception("Redirect location is null");
final requestOptions = response.requestOptions;
final rawUri = requestOptions.uri.toString();
final newUri = Uri.parse(_parseHttpLocation(rawUri, location));
response.requestOptions.extra[redirectCount] = redirectCountValue + 1;
final option = Options(
sendTimeout: requestOptions.sendTimeout,
receiveTimeout: requestOptions.receiveTimeout,
extra: requestOptions.extra,
// headers: requestOptions.headers
// ..removeWhere((key, value) {
// return key.toLowerCase() == "cookie" || key.toLowerCase() == 'content-length';
// }),
responseType: requestOptions.responseType,
validateStatus: requestOptions.validateStatus,
receiveDataWhenStatusError: requestOptions.receiveDataWhenStatusError,
followRedirects: requestOptions.followRedirects,
maxRedirects: requestOptions.maxRedirects,
persistentConnection: requestOptions.persistentConnection,
requestEncoder: requestOptions.requestEncoder,
responseDecoder: requestOptions.responseDecoder,
listFormat: requestOptions.listFormat,
);
final redirectResponse = await _dio.getUri(
newUri,
options: option,
);
return handler.next(redirectResponse);
} on DioException catch (e) {
return handler.reject(e);
}
}
return handler.next(response);
}
bool _isRedirect(int statusCode) {
return statusCode == 301 ||
statusCode == 302 ||
statusCode == 303 ||
statusCode == 307 ||
statusCode == 308;
}
String _parseHttpLocation(final String rawUri, final String location) {
var location1 = location;
String uri;
if (!location1.contains("://")) {
final schemaEndIndex = rawUri.indexOf("://") + 3;
var index = location1.startsWith("/")
? rawUri.indexOf("/", schemaEndIndex)
: rawUri.substring(schemaEndIndex).lastIndexOf("/") + schemaEndIndex;
if (index == -1) index = rawUri.length - 1;
var baseUrl = rawUri.substring(0, index + 1);
if (baseUrl.endsWith("/")) {
baseUrl = baseUrl.substring(0, baseUrl.length - 1);
}
if (location1.startsWith("/")) {
location1 = location1.substring(1);
}
uri = baseUrl + "/" + location1;
} else {
uri = location1;
}
return uri;
}
}
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Request Statement
As Dart doc stated:
The redirections will only happen in these circumstances.
But it might be great if other requests could follow redirections too.
Solution Brainstorm
Pseudo implementation:
The text was updated successfully, but these errors were encountered: