http
http copied to clipboard
HTTP request results in exception when body is not read by the server.
version: 0.12.1 If I sent a post/put requests with a jsonBody and the server responds without reading the body, then it throws an unhandled exception
E/flutter ( 3983): [ERROR:flutter/lib/ui/ui_dart_state.cc(157)] Unhandled Exception:
E/flutter ( 3983): #0 IOClient.send (package:http/src/io_client.dart:62:7)
E/flutter ( 3983): <asynchronous suspension>
E/flutter ( 3983): #1 BaseClient._sendUnstreamed (package:http/src/base_client.dart:176:38)
E/flutter ( 3983): #2 BaseClient.put (package:http/src/base_client.dart:81:7)
E/flutter ( 3983): #3 put.<anonymous closure> (package:http/http.dart:94:16)
E/flutter ( 3983): #4 _withClient (package:http/http.dart:166:20)
E/flutter ( 3983): #5 put (package:http/http.dart:93:5)
Here is how I reproduced the problem. In my flutter app, I have 2 buttons that will send requests to the servers.

In my flask servers,
@app.route('/test-post', methods=['POST'])
def test_post():
# print(request.get_json())
return make_response('tested', 200)
@app.route('/test-put', methods=['PUT'])
def test_put():
# print(request.get_json())
return make_response('tested', 200)
When the request is sent, it will result in the above exception. But if the "request.get_json()" or "request.get_data()" is called in flask, it will work just fine. I am guessing the server terminated the input stream when it sends back the response, which caused the error.
I was experiencing this issue and I was lost. This workaround saved my day. I'm using the same technologies as you, Flutter + Flask.
@koyadovic You can try using dio package instead, I haven't use it but it is recommended by a lot of people. https://pub.dev/packages/dio
I had this request today. The most frustrated part of this error is that there is no expection message. Flask would return a 200 despite the exception, which makes identifying the issue more difficult.
I can't reproduce this. Version 0.12.1 seems incompatible with recent Dart SDKs due to a minor breaking change in the SDK, however when I fix that or use an older Dart SDK and try making a post request to a (Dart) server which response with OK but does not read the body I get no exception.
Can somebody post a complete reproduction?
I tried with
//server.dart
import 'dart:io';
void main() async {
var server = await HttpServer.bind('localhost', 8080);
await for (var request in server) {
await (request.response..statusCode = HttpStatus.ok).close();
}
}
// client.dart
import 'package:http/http.dart' as http;
void main() async {
var client = http.Client();
await client.post(Uri.http('localhost:8080', ''), body: 'something');
print('Done');
client.close();
}
@natebosch I tried to reproduce the issue with minimal code with Dart frontend and Python backend, see if it is useful.
// client.dart
import 'package:http/http.dart' as http;
void main() async {
var client = http.Client();
await client.post(Uri.http('192.168.1.245:8080', 'test'), body: 'something');
print('first request done');
await client.post(Uri.http('192.168.1.245:8080', 'test'), body: 'something');
print('second request done');
client.close();
}
from flask import Flask, request
app = Flask(__name__)
@app.route("/test", methods=["POST"])
def test():
return "this is a return", 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8080,debug=True)
The first request is fine, but adding second request gives an exception. If I run the Dart code directly, I get the exception Connection closed before full header was received.
first request done
Unhandled exception:
Connection closed before full header was received
#0 IOClient.send (package:http/src/io_client.dart:61:7)
<asynchronous suspension>
#1 BaseClient._sendUnstreamed (package:http/src/base_client.dart:93:32)
<asynchronous suspension>
#2 main (file:///C:/Users/User/AndroidStudioProjects/homie/test/client.dart:7:3)
<asynchronous suspension>
But if I run the client side code on a Flutter environment, the exception reason somehow get compressed and not shown in the debugger.
I/flutter (20429): first request done
E/flutter (20429): [ERROR:flutter/lib/ui/ui_dart_state.cc(199)] Unhandled Exception:
E/flutter (20429): #0 IOClient.send (package:http/src/io_client.dart:61:7)
E/flutter (20429): <asynchronous suspension>
E/flutter (20429): #1 BaseClient._sendUnstreamed (package:http/src/base_client.dart:93:32)
E/flutter (20429): <asynchronous suspension>
E/flutter (20429): #2 main (package:homie/main.dart:7:3)
E/flutter (20429): <asynchronous suspension>
E/flutter (20429):
Back to the exception itself. If I add request.body in Flask like the following:
@app.route("/test", methods=["POST"])
def test():
request.data
return "this is a return", 200
Then on the client side everything works fine. Not sure how to reproduce the error using a Dart server.
Thanks for the workaround joey! You saved me from a lot of trouble.
I'm not able to reproduce this with multiple unread POST bodies to either a Dart or Python+Flask server.
If this is still a problem for someone, please add a comment with the Dart SDK version and the code you are using.