I am using route to handle http requests to my server. This is my current route code:
HttpServer.bind("127.0.0.1", 8080).then((server) {
new Router(server)
..filter(new RegExp(r'/.*'), addCorsHeaders)
..filter(new RegExp(r'/admin/.*'), authenticate)
..serve(userGetURL, method: 'GET').listen(userGetHandler)
..serve(userPostURL, method: 'POST').listen(userPostHandler);
});
I am trying to get JSON data that I am POSTing to a URL. The data will be used to get an entity from the database and return it as JSON to the caller. I am basically trying to create a server application that will handle all the data and a client application that will display it.
I cannot figure out how to get the data from a POST. Everything I have tried requires that I listen to the stream, but it is already being listened to. This is how I have been trying to get the POST data:
userPostHandler(HttpRequest req) {
req.listen((List<int> buffer) {
// Return the data back to the client.
res.write(new String.fromCharCodes(buffer));
res.close();
}
}
The problem is I get a Bad state: Stream has already been listened to.
error.
EDIT: The filters
Future<bool> authenticate(HttpRequest req) {
if (req.method == 'POST') {
// Post data is not null
// Authenticate user
String userName = '';
String password = '';
User user = new User();
user.DBConnect().then((User user) {
return new Future.value(user.ValidateUser(userName, password));
});
}
}
Future<bool> addCorsHeaders(HttpRequest req) {
print('${req.method}: ${req.uri.path}');
req.response.headers.add('Access-Control-Allow-Origin', '*, ');
req.response.headers.add('Access-Control-Allow-Methods', 'POST, OPTIONS, GET');
req.response.headers.add('Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept');
return new Future.value(true);
}
Using the following code I was able to get a POST working:
Here is what I figured out. Any write to the response automatically drains the body and thus destroy the POST data. As mentioned here. Also, listening to the response is done asynchronously and thus must be completed before close() is called.