flutter http request/response details including headers? - flutter

while http request details can easily be inspected in browser dev tools(for web app), I tried to explore, where I can find the same for requests sent in flutter App, but couldn't locate it.
like for example - I can see the actual response from api by print(response), but I am talking about complete request response including headers.
I am using VScode IDE for Flutter.
update:
I want to view the headers sent like response.header. reason for the same is like I am using flutter cahe manager and the issue I am facing is like I have set the -cache control max-age=1.
so the flutter should try to fetch the same every time I access the page, which it is doing, but it is serving the page from the cache and then fetching the request. so if there is any change is on server side, it doesn't reflect when first open the page, but shows the change on every second visit.
so what I want is like if the flutter gets 304 response from server, it will serve from the cache else it should serve from the fetched data. but it is not happening.
also the response.header is not showing response code like it is 200 or 304, so that flutter can fetch or serve from cache.
Actual code being used is like this:
Future<MyUserProfile> fetchMyUserProfile() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
final userid = prefs.getString('user_id');
var userProfile = await DefaultCacheManager().getSingleFile("url");
final response = await userProfile.readAsString();
if (response != '') {
print(userProfile);
// If the server did return a 200 OK response,
// then parse the JSON.
return MyUserProfile.fromJson(json.decode(response));
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
throw Exception('Failed to load Profile');
}
}

Don't wanna be rude, but the information you are looking for is quite easy to find... That is if you look in the right place, like official documentation.
https://api.flutter.dev/flutter/dart-io/HttpResponse-class.html
HttpResponse class ... headers → HttpHeaders Returns the response
headers. [...] read-only
http.Response response = await http.get(url...
print(response.headers);
EDIT: Answering the sub-question that was added to the original question.
To check what the status code is you simply access it via response.statusCode
Example:
http.Response response = await http.get(url...
if (response.statusCode == 200) {
// do something
} else if (response.statusCode == 304) {
// do something else
} else {
// handle this
}

Related

How to get the content of a bin file from url in Flutter

I would like to be able to read the content of a .bin file stored at a url of the form https://something/file.bin.
I tried with the http package, but the http.get doesn't work, the exception "XMLHttpRequest error." is thrown :
try {
String url = '${constants.backPrefix}${file.gpxFilePath}';
final response = await http.get(Uri.parse(url));
if(response.statusCode == 200) {
debugPrint(response.body);
} else {
debugPrint("Incorrect statusCode : ${response.statusCode}");
}
} catch (e) {
debugPrint("Exception : $e");
}
When I run this code I have :
Exception : XMLHttpRequest error.
I have no problem to access the rest of the back end (images and JSONs). I'm sure it's the correct url because when I write the url in my browser I can access to the file. The person who develops the back end told me that it could be a CORS problem.
I'm new to flutter and mobile/web development in general so maybe there's something I'm misunderstanding.
Thank you !

is there a way to check is URL is existing or not in http request?

is there a way to check is URL is existing or not in http request?
I am working on an accounting app it should sold for many company, so in Sign in page each ueser has to add hes own domain to connect with his company api and data, my question is here if user add worng domain or typing somthing else that is not kind of URL, how can handle it?
is there any way to definde that url is not working or not existing?
and in postman if typing anything insted of url, it say could not sed request. no response no error nothing.
Future _checkUrl(String url) async {
http.Response _urlResponse = await http.get(Uri.parse(url));
if (_urlResponse.statusCode == 200) {
return true;
}
else {
return false;
}
}
_checkUrl("https://stackoverf").then((value) => {
print(value)
});

http.get returns 404 "Route not found"

I am trying to use a public API to search movie titles via my Flutter/Dart app.
A minimal code snippet is this
static Future<AnimeSearchResult> fetchSearchResults(String searchTerm) async {
final response = await http.get(
Uri.https("kitsu.io", "/api/edge/anime?filter[text]=cowboy%20bebop"));
// https://kitsu.io/api/edge/anime?filter[text]=cowboy%20bebop
if (response.statusCode == 200) {
// If the server did return a 200 OK response,
// then parse the JSON.
return animeSearchResultsFromMap(response.body);
} else {
// If the server did not return a 200 OK response,
// then throw an exception.
print(response.body);
throw Exception('Failed to load search results');
}
}
This will search and return an object back to a FutureBuilder Widget which then displays the results. (I have tested the UI and it is working on sample data)
Running the code, I get 404 error in my console
{"errors":[{"status":404,"title":"Route Not Found"}]}
Opening the link in my browser, it gives a JSON file as its supposed to do.
Trying to access the trending collection link using
final response = await http.get(Uri.https("kitsu.io", "/api/edge/trending/anime")); also works perfectly fine.
So I am suspecting there is some error in the way my URI is written for the search code. Precisely speaking, this line is at fault
final response = await http.get(Uri.https("kitsu.io", "/api/edge/anime?filter[text]=cowboy%20bebop"));
However I don't know what exactly is the problem.
Any help is appreciated!
Thank You!
I tried it this way, and it worked:
final response = await http.get(Uri.parse("https://kitsu.io/api/edge/anime?filter[text]=cowboy%20bebop"));
But await http.get(Uri.https resulted in the same error you are having.

RedirectException: Redirect loop detected

I'm testing a request to get data from an URL using dio in my Dart code.
import 'package:dio/dio.dart';
class Api {
Dio dio = Dio();
var path = 'https://jsonplaceholder.typicode.com/users';
void getHttp() async {
try {
Response response = await dio.get(path);
print(response.data);
} catch (e) {
print(e);
}
}
}
In this case it brings the result correctly.
But, I actually need get data from this URL:
http://loterias.caixa.gov.br/wps/portal/loterias/landing/megasena/!ut/p/a1/04_Sj9CPykssy0xPLMnMz0vMAfGjzOLNDH0MPAzcDbwMPI0sDBxNXAOMwrzCjA0sjIEKIoEKnN0dPUzMfQwMDEwsjAw8XZw8XMwtfQ0MPM2I02-AAzgaENIfrh-FqsQ9wNnUwNHfxcnSwBgIDUyhCvA5EawAjxsKckMjDDI9FQE-F4ca/dl5/d5/L2dBISEvZ0FBIS9nQSEh/pw/Z7_HGK818G0KO6H80AU71KG7J0072/res/id=buscaResultado/c=cacheLevelPage/=/?timestampAjax=1588600763910
Using Postman I can access the data:
So, the problem is that, if I try to get data from that URL in my code, I get the following exception error:
I/flutter (23393): DioError [DioErrorType.DEFAULT]: RedirectException: Redirect loop detected
If this URL is redirecting, why is it working when using Postman? Anyway, how could I handle this redirected request in order to access data?
After a while, I noticed that the response to this request is coming as HTML and not as Json. So I needed to create a way to get DOM coming from the request, removing HTML tags and encoding string to Json.

Flutter http Maintain PHP session

I'm new to flutter. Basically I'm using code Igniter framework for my web application. I created REST API for my web app, after user login using API all the methods check for the session_id if it exists then it proceeds, and if it doesn't then it gives
{ ['status'] = false, ['message'] = 'unauthorized access' }
I'm creating app with flutter, when i use the http method of flutter it changes session on each request. I mean, it doesn't maintain the session. I think it destroys and creates new connection each time. Here is thr class method which i use for api calls get and post request.
class ApiCall {
static Map data;
static List keys;
static Future<Map> getData(url) async {
http.Response response = await http.get(url);
Map body = JSON.decode(response.body);
data = body;
return body;
}
static Future postData(url, data) async {
Map result;
http.Response response = await http.post(url, body: data).then((response) {
result = JSON.decode(response.body);
}).catchError((error) => print(error.toString()));
data = result;
keys = result.keys.toList();
return result;
}
I want to make API request and then store session_id,
And is it possible to maintain session on the server so i can manage authentication on the web app it self.?
HTTP is a stateless protocol, so servers need some way to identify clients on the second, third and subsequent requests they make to the server. In your case you might authenticate using the first request, so you want the server to remember you on subsequent requests, so that it knows you are already authenticated. A common way to do this is with cookies.
Igniter sends a cookie with the session id. You need to gather this from each response and send it back in the next request. (Servers sometimes change the session id (to reduce things like clickjacking that we don't need to consider yet), so you need to keep extracting the cookie from every response.)
The cookie arrives as an HTTP response header called set-cookie (there may be more than one, though hopefully not for simplicity). To send the cookie back you add a HTTP request header to your subsequent requests called cookie, copying across some of the information you extracted from the set-cookie header.
Hopefully, Igniter only sends one set-cookie header, but for debugging purposes you may find it useful to print them all by using response.headers.forEach((a, b) => print('$a: $b'));. You should find Set-Cookie: somename=abcdef; optional stuff. We need to extract the string up to, but excluding the ;, i.e. somename=abcdef
On the next, and subsequent requests, add a request header to your next request of {'Cookie': 'somename=abcdef'}, by changing your post command to:
http.post(url, body: data, headers:{'Cookie': cookie})
Incidentally, I think you have a mismatch of awaits and thens in your code above. Generally, you don't want statics in classes, if they should be top level functions instead. Instead you could create a cookie aware class like:
class Session {
Map<String, String> headers = {};
Future<Map> get(String url) async {
http.Response response = await http.get(url, headers: headers);
updateCookie(response);
return json.decode(response.body);
}
Future<Map> post(String url, dynamic data) async {
http.Response response = await http.post(url, body: data, headers: headers);
updateCookie(response);
return json.decode(response.body);
}
void updateCookie(http.Response response) {
String rawCookie = response.headers['set-cookie'];
if (rawCookie != null) {
int index = rawCookie.indexOf(';');
headers['cookie'] =
(index == -1) ? rawCookie : rawCookie.substring(0, index);
}
}
}