-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # 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;
}
}
|
# for free
to join this conversation on GitHub.
Already have an account?
# 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: