ClientException in io_client.dart - flutter

The code below works started giving trouble when the back-end server is switched from HTTP to HTTPS. The back-end application is written in .NET and runs on IIS 10.0
response = await http.post(
Uri.encodeFull("https://_____________/api/account/login"),
body: json.encode(body),
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
// ignore: missing_return
}).timeout(Duration(seconds: 10), onTimeout: () {
throw ('You seem to be offline');
});
if (response.statusCode == 500) {
.......
See the screenshot below for exact exception. Interestingly, there's no exception message.
The code works well on other HTTPS back-end such as MS Azure hosted APIs. The API call works well in the Postman.
Can anyone help ?
EDIT : Found a related github issue

Related

CORS error: Request header field authorization is not allowed by Access-Control-Allow-Headers in preflight response

I'm trying to fetch an image resource that's part of a conversation message.
I've tried both FETCH as well as using AXIOS but I'm getting the same error message.
Here's an example of my FETCH request
const token = `${accountSid}:${authToken}`;
const encodedToken = Buffer.from(token).toString('base64');
let response = await fetch('https://mcs.us1.twilio.com/v1/Services/<SERVICE_SID>/Media/<MEDIA_SID>',
{
method:'GET',
headers: {
'Authorization': `Basic ${encodedToken}`,
}
});
let data = await response.json();
console.log(data);
And here's what Axios looked like
let config = {
method: 'get',
crossdomain: true,
url: 'https://mcs.us1.twilio.com/v1/Services/<SERVICE_SID>/Media/<MEDIA_SID>',
headers: {
'Authorization': `Basic ${encodedToken}`,
},
};
try {
const media = await axios(config);
console.dir(media);
} catch(err) {
console.error(err);
}
Both ways are NOT working.
After looking into it more, I found out that Chrome makes a pre-flight request and as part of that requests the allowed headers from the server.
The response that came back was this
as you can see, in the "Response Headers" I don't see the Access-Control-Allow-Headers which should have been set to Authorization
What am I missing here?
I have made sure that my id/password as well as the URL i'm using are fine. In fact, I've ran this request through POSTMAN on my local machine and that returned the results just fine. The issue is ONLY happening when I do it in my code and run it in the browser.
I figured it out.
I don't have to make an http call to get the URL. It can be retrieved by simply
media.getContentTemporaryUrl();

How correctly is the request sent from the locale?

I used strapi to write queries. I checked it on postman, using "localhost" instead of IP, everything is fine. However, when I sent a request from flutter, I got an error, which I managed to avoid by using my ip instead of "localhost". But also through postman now error 502, the same error if sent via flutter
ElevatedButton(onPressed: () async {
var url = 'http://мой.айпи.43/api/pelargoniums';
Map<String,String> headers = {
'Content-Type':'application/json',
'Accept': 'application/json'
};
final response = await http.get(
Uri.parse(url),
headers: headers
);
if (response.statusCode == 200) {
print(response.body);
print('yep');
} else {
print(response.statusCode);
}
}, child: Text('wewewewew'))
Please tell me what is my problem and how to fix it?
When testing on a mobile device (Android , iOS) , you must connect within the same Wi-Fi network to use IP communication. If it is used as a web, Windows, or mac program, it can be used.

How to remove Authorization header on redirect on any Flutter/Dart http client

I'm currently working on a project which like a lot of other projects works with s3 storage. In this case the storage is linked via the back-end.
The situation is like this, I can get the 'attachment' via an URL, lets say example.com/api/attachments/{uuid}. If the user is authorized (via the header Authorization) it should return a 302 statuscode and redirect to the s3 url. The problem is that after the redirect the Authorization header persists and the http client return a 400 response and it's because of the persisting Authorization header. Is there any way I can remove the Authorization header after redirect without catching the first request and firing a new one?
My http client code currently looks like this:
#override
Future get({
String url,
Map<String, dynamic> data,
Map<String, String> parameters,
}) async {
await _refreshClient();
try {
final response = await dio.get(
url,
data: json.encode(data),
queryParameters: parameters,
);
return response.data;
} on DioError catch (e) {
throw ServerException(
statusCode: e.response.statusCode,
message: e.response.statusMessage,
);
}
}
Future<void> _refreshClient() async {
final token = await auth.token;
dio.options.baseUrl = config.baseUrl;
dio.options.headers.addAll({
'Authorization': 'Bearer $token',
'Accept': 'application/json',
});
dio.options.contentType = 'application/json';
}
Good news! This has been fixed recently with Dart 2.16 / Flutter v2.10!
Related bugs in dart issue tracker:
https://github.com/dart-lang/sdk/issues/47246
https://github.com/dart-lang/sdk/issues/45410
Official announcement:
https://medium.com/dartlang/dart-2-16-improved-tooling-and-platform-handling-dd87abd6bad1
TLDR: upgrade to Flutter v2.10!
Looking at the Dio docs, it seems like this is intentional behaviour.
All headers added to the request will be added to the redirection request(s). However, any body send with the request will not be part of the redirection request(s).
https://api.flutter.dev/flutter/dart-io/HttpClientRequest/followRedirects.html
However, I understand (and agree!) that this is generally undesirable behaviour. My solution is to manually follow the redirects myself, which is not very nice but works in a pinch.
Response<String> response;
try {
response = await dio.get(
url,
options: Options(
// Your headers here, which might be your auth headers
headers: ...,
// This is the key - avoid following redirects automatically and handle it ourselves
followRedirects: false,
),
);
} on DioError catch (e) {
final initialResponse = e.response;
// You can modify this to understand other kinds of redirects like 301 or 307
if (initialResponse != null && initialResponse.statusCode == 302) {
response = await dio.get(
initialResponse.headers.value("location")!, // We must get a location header if we got a redirect
),
);
} else {
// Rethrow here in all other cases
throw e;
}
}

Fetch works but when I use Axios I get CORS error

So I am using a Third-party API called graphhopper API.
First I used fetch() to call the API and it works but when I use the Axios I get a CORS error.
// THIS WORKS OKAY :)
const response = await fetch(`${graphHopperUrl}/optimize?key=${graphHopperApiKey}`, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(problem)
})
// DOESN'T WORK :(
const response = await this.$axios.post(
`${graphHopperUrl}/optimize?key=${graphHopperApiKey}`,
problem,
)

Flutter: Http Request has no body

I am trying to send a http request using the http plugin on version ^0.12.0+4 (the latest one).
http.Response response = await http.post(
http://localhost:8085,
body: jsonEncode({"test": "test"}),
headers: {
"accept": "application/json",
"content-type": "application/json"
},
);
I have a SpringBoot backend running which stated, that the request body is empty. Debug attempts with Postman worked fine.
I tried the Dio package as well with the same result.