Santosh Kumar
Santosh Kumar

Reputation: 196

how to use a new MultipartFile each time when I retry

actually I am posting this question again due to some disturbance and miss communication with other developer. actually I am using http_interceptor package where I want to retry the request upon 401 response using this package but when I am retrying I am facing following exception because I am retrying multipart/request from previous answer I got to know that it is a Stream/MultipartFile I can use it only once therefore I want to create new MultipartFile each time when I retry. please check this image following is my interceptor where I am updating headers on retry

class AuthorizationInterceptor extends InterceptorContract {
  @override
  Future<BaseRequest> interceptRequest({required BaseRequest request}) async {
    final prefs = await SharedPreferences.getInstance();

    final extractData =
        json.decode(prefs.getString('userData')!) as Map<String, dynamic>;

    final Map<String, String> headers = Map.from(request.headers);
    headers['Authorization'] = await extractData['accessToken'];
    print(
        'this is from AuthorizationInterceptor: ${extractData['accessToken']}');
    // TODO: implement interceptRequest

    return request.copyWith(
      headers: headers,
    );
  }

following is my ExpiredTokenRetryPolicy where I am restoring access token on 401 response

class ExpiredTokenRetryPolicy extends RetryPolicy {
  BuildContext context;
  ExpiredTokenRetryPolicy(this.context);
  @override
  // TODO: implement maxRetryAttempts
  int get maxRetryAttempts => 2;

  @override
  Future<bool> shouldAttemptRetryOnResponse(BaseResponse response) async {
    if (response.statusCode == 401) {
      print('retry token started');
      //perform token refresh,get the new token and update it in the secure storage

      await Provider.of<Auth>(context, listen: false).restoreAccessToken();
      return true;
    }
    return false;
  }
}

following is my client where I am using this 2 classes

ApiCalls repository = ApiCalls(
      client: InterceptedClient.build(
        retryPolicy: ExpiredTokenRetryPolicy(context),
        interceptors: [
          AuthorizationInterceptor(),
        ],
      ),
    );

in the above code ExpiredTokenRetryPolicy will retry on response 401 help is appreciated thank you in advance

Upvotes: 0

Views: 363

Answers (1)

Santosh Kumar
Santosh Kumar

Reputation: 196

I had found solution....I found a bug in this package after a long research so I had shifted my package to http following is my code its works perfect

first import 'package:http/retry.dart'; from http package

      var response = http.MultipartRequest("POST", Uri.parse(url))
        ..files.add(await http.MultipartFile.fromPath(
            "imagefile", flutterFunctions.imageFile!.path,
            contentType: MediaType("image", "jpg")))
        ..headers['Authorization'] = token!
        ..fields.addAll(obj);
      final client = RetryClient(
        http.Client(),
        retries: 1,
        when: (response) {
          return response.statusCode == 401 ? true : false;
        },
        onRetry: (req, res, retryCount) {
          if (retryCount == 0 && res?.statusCode == 401) {
            // Only this block can run (once) until done
            Provider.of<Auth>(context, listen: false).restoreAccessToken();
            req.headers['Authorization'] = token!;
          }
        },
      );
      final send = await client.send(response);
      final res = await http.Response.fromStream(send);
    

Upvotes: 1

Related Questions