dio icon indicating copy to clipboard operation
dio copied to clipboard

Is it WAI that dio.post throws DioError on 302?

Open tallinn1960 opened this issue 2 years ago • 1 comments

New Issue Checklist

  • [x] I have searched for a similar issue in the project and found none

Issue Info

Info Value
Platform Name dart vm
Platform Version dart 2.14.4
Dio Version 4.0.4
Android Studio / Xcode Version n.a.
Repro rate 100%
Repro with our demo prj not checked
Demo project link n.a

Issue Description and Steps

The call

response = await Dio().post('some url that returns 302', data: Map.from({'somedata': 'moredata'}));

throws a DioError as of the HTTP status code 302. However it is perfectly valid to return a 302 with a new location on a POST request. The POST request should act accordingly and follow the redirect.

I tried setting followRedirects to false but that doesn't help.

Here is a full sample code to demonstrate the 302 behaviour:

import 'dart:io';

import 'package:test/test.dart';
import 'package:dio/dio.dart';
import 'package:http_mock_adapter/http_mock_adapter.dart';

void main() async {
  final dio = Dio();
  final dioAdapter = DioAdapter(dio: dio);

  dioAdapter.onPost("https://originallocation", (server) {
    return server.reply(302, '', headers: { HttpHeaders.locationHeader : ['https://newlocation']});
  });
  dioAdapter.onPost("https://newlocation", (server) {
    return server.reply(200, "data");
  });

  final response = await dio.post("https://originallocation");
  // not reached as post throws DioError
  expect(response.data, "data");
}

Result expected: no output Result received:

Unhandled exception:
DioError [DioErrorType.response]: Http status error [302]
Source stack:
#0      DioMixin.fetch (package:dio/src/dio_mixin.dart:473:35)
#1      DioMixin.request (package:dio/src/dio_mixin.dart:468:12)
#2      DioMixin.post (package:dio/src/dio_mixin.dart:91:12)
#3      main (file:///Users/tallinn/IdeaProjects/diopost302/bin/diopost302.dart:18:30)
...

tallinn1960 avatar Nov 30 '21 14:11 tallinn1960

same problem.

Andromeda606 avatar Aug 29 '22 09:08 Andromeda606

Dio post redirection is not available by default, you can turn off redirection and status code verification, and then manually process the location request header

extension DioExt on Dio {
  Dio setFollowRedirects(bool followRedirects) {
    options.followRedirects = followRedirects;
    if (followRedirects) {
      options.validateStatus =
          (int? status) => status != null && status >= 200 && status < 300;
    } else {
      options.validateStatus =
          (int? status) => status != null && status >= 200 && status < 400;
    }
    return this;
  }
}

wilinz avatar Feb 24 '23 11:02 wilinz