Handling non-Ok requests in dart - dart

I have this simple dart snippet:
import 'package:http/http.dart' as http;
Client _http = new BrowserClient();
final response = await _http
.post(url, headers: someHeader, body: someValue);
The server for the current request, returns Bad Request 400 response. I want to be able to get the status code for some reasons. But as soon as the _http.post get called, I get this error:
POST http://localhost/path 400 (Bad Request)
Putting the block in try/catch doesn't help, since the exception catched is ClientException which has no information about status-code and response-body (which is important here). How can I handle status-codes here, without throwing exceptions?
UPDATE:
I have this snippet after _http.post() call:
if (response.statusCode == 400) {
// manage bad request
}
But the response is null, so the statusCode is not accessible here.
UPDATE 2:
I get the request on server and can trace on server. As I mentioned, the server is sending a 400 Bad Request response, and works just fine. But getting the response in Dart causes the error.

The Response object has a field statusCode where you can get the status code of the response.
You can do something like that:
final response = await _http
.post(url, headers: someHeader, body: someValue);
if (response.statusCode == 400) {
// manage bad request
}

I suspect the url, a header or the body is invalid somehow. (e.g. invalid characters in a header). The request is not actually being sent to the server, and so ClientException is being thrown instead of giving you a response.

Related

How to send request to another server in shelf dart

I need to make a request to my firebase rtdb from my shelf server hosted on 127.0.0.1, I have the url and the db secrets. But whenever i try to make a get request to the db url using the http package, i get a 401 error.
My code:
import 'dart:io';
import 'package:http/http.dart';
import 'package:firebase/firebase_io.dart';
class FirebaseLocalClient {
void putSudokuBoard() async {
var a = await get(
Uri.parse(
"<db url>"),
headers: {
"Authorization": "Bearer <your database secret>",
'Content-Type': "application/js"
});
print(a.statusCode);
//print(a.runtimeType);
}
}
void main(List<String> args) {
FirebaseLocalClient().putSudokuBoard();
}
I call this code from a shelf server(similar to the code in main function), but running it here itself recieves a 401 error.
I am not able to understand why i am recieving a 401 error, i have the db secrets and yet i am unable to get the data at that location. I tried using the admin sdk json but recieved 401 on that too
The output when i use a.body:
The output when i use a.statuscode:
If you are using the db secrets, it looks like you need to append the auth param.
per https://firebase.google.com/docs/database/rest/retrieve-data#section-rest-uri-params
curl 'https://docs-examples.firebaseio.com/auth-example.json?auth=CREDENTIAL'
Remove the Authorization header and try it in curl

Dart http server freezes when content type is set to text/html

I have a very simple Dart HttpServer like this:
server.listen((request) async {
final html = await indexHtml; // Loaded from a file.
request.response.write(html);
await request.response.close();
});
That works perfectly (except it shows the HTML as text), but if I set the content-type correctly like this:
server.listen((request) async {
final html = await indexHtml;
request.headers.set("Content-type", "text/html");
request.response.write(html);
await request.response.close();
});
Then it freezes and never returns a response. I've tried telnetting to it and typing GET / HTTP/1.1 but it just never returns any data. Not even headers. Chrome just spins forever.
Am I doing something stupid or is this broken?
Ugh, I was being stupid, and it actually did give me an exception in the logs:
[ERROR:flutter/lib/ui/ui_dart_state.cc(177)] Unhandled Exception: HttpException: HTTP headers are not mutable
I was trying to modify the request headers, not the response headers. Instead of
request.headers.set("Content-type", "text/html");
it should be
request.response.headers.set("Content-type", "text/html");
or rather
request.response.headers.contentType = ContentType.html;
as julemand101 suggested.

Keep HttpRequest stream open while I issue a Client.post

My dart server has a function which receives a POST request from a client. I want to use information from that request to issue a POST to another server, then use the response from this other server to send a response back to the original client request. When I issue my POST to the other server, it closes the stream on the inbound client request and I can no longer respond. Is there a way to keep the request stream 'alive' while I do a POST? Or, is there another way to do this? I did try to issue the POST on a different Isolate, but that didn't help, the http request stream is still getting closed.
void postRequest(HttpRequest request) async {
final endPoint = 'https://www.anotherserver.com/information';
final client = Client();
final data = request.headers.value('data'); // Get data from client
final response = client.post(endPoint, body: data); // Send data to other server
// Do stuff with the response from endPoint server
// For simplicity of this example, just send back the response body back to the client
// This write call to the request causes an "Stream Sink Closed" exception
// It appears the POST call to the endPoint server, caused the client request stream
// to get closed.
request.response.write(response.body);
await request.response.flush();
await request.response.close();
}
I was not awaiting the client.post.... I need to do a better job of watching out for that.

How to get the HTTP response text from a HttpRequest.postFormData's catchError's _XMLHttpRequestProgressEvent?

Given the following pseudo code:
import "dart:html";
HttpRequest.postFormData(url, data).then((HttpRequest request) {
...
}).catchError((error) {
// How do I get the response text from here?
});
If the web server replies with a 400 BAD REQUEST then the catchError will be invoked. However, the error parameter is of the type _XMLHttpRequestProgressEvent which apparently doesn't exist in Dart's library.
So, how do I get the response text from the 400 BAD REQUEST response that was sent from the web server?
It seems like the target in your error object is actually your HttpRequest.
You may find this link helpful: https://www.dartlang.org/docs/tutorials/forms/#handling-post-requests
You could do something like:
import "dart:html";
HttpRequest.postFormData(url, data).then((HttpRequest request) {
request.onReadyStateChange.listen((response) => /* do sth with response */);
}).catchError((error) {
print(error.target.responseText); // Current target should be you HttpRequest
});

how to add content-type to Twilio response?

How to add content-type to Twilio Response? I am getting 502 bad gateway error and the error says that it could be because of missing Content-Type. But I do see that the response has the Content-type. So what could be going wrong? I am also seeing the twilio reason is connection-time out! What does that mean? This is related to my earlier post at: An attempt to retrieve content from returned the HTTP status code 502. Please check the URL and try again
Response - The HTTP headers and body of your server's response to Twilio
Headers
Content-Type text/html
Transfer-Encoding chunked
X-Twilio-Reason connection timed out
Body
1
<html><head><title>502 Bad Gateway</title></head><body><h1>Bad Gateway</h1>An upstream server returned an invalid response.</body></html>
Can somebody help me to find out why twilio is giving error while accessing my API?
This is what I have in my controller:
public class TestController : ApiController
{
[HttpPost]
public HttpResponseMessage Post([FromBody]SmsRequest smsReq)
{
string smsReqUpper = smsReq.Body.ToUpper();
string testString = "TEST";
var response = new Twilio.TwiML.TwilioResponse();
if (smsReqUpper == testString)
{
response.Sms("Test Successful");
return Request.CreateResponse(HttpStatusCode.OK, response.Element);
}
else
{
string strBody = "Invalid Text Command. Please text the word TEST " ;
response.Sms(strBody);
return Request.CreateResponse(HttpStatusCode.OK, response.Element);
//return new TwiMLResult(response);
}
}
The Content-Type text/html bit refers to the 502 bad gateway response, not the actual response coming from your server. Add the "text/xml" content type to your request (I don't recognize the framework you are using) and you should be good to go.
To debug your response you can use curl -vvv [URL] until the Content-Type: text/xml part is present.

Resources