I don't think that's true.
The HTTP specs seem clear -- the server is allowed to reply early and close the upload stream while the client is doing a large upload, and the client should listen for such a close:
"An HTTP/1.1 (or later) client sending a message-body SHOULD monitor the network connection for an error status while it is transmitting the request."
In the case of a large upload where the server finds out half-way-through that the upload is invalid, the correct behaviour for the server is to:
1. Respond on the "down" stream with the error details (HTTP 400 bad request, etc. etc.)
2. Close the "up" stream (i.e. half-close the connection) so that the client stops sending the second half of the large request.
(3. Don't close the "down" stream, as we want the client to read our error message.)
As well as the specs, we can look to pre-existing servers. The Apache AXIS SOAP server (Tomcat based) does this, for example if you have a very large XML upload with a syntax error half-way through it, Apache AXIS will follow steps 1-3 above when it reaches that point in the stream.
I think that a well-behaved server needs to always either read in the full request and/or half-close the TCP upload stream.
My questions from before still stand:
1) how do I know, in the akka.http.server.ExceptionHandler interface (or nearby), whether I need to half-close a part-read request body stream, or if the request body has been read?
2) in the akka.http.server.ExceptionHandler interface (or nearby) how do I half-close a part-read materialized request body stream, when I don't have a reference to it? I only have a reference to the unmaterialized Source.
As I feared, this doesn't work.
I have written an isolated test case which does the following:
1. The client makes a large upload
2. The routing code in the Akka server dispatches the request to a worker layer
3. The worker layer reads half of the upload body, then returns an exception to the router
4. The routing layer runs "request.entity.dataBytes.runWith(Sink.cancelled)"
5. The server responds with an error code
6. Now the TCP upload stream is still neither fully read nor closed. The client is blocked trying to upload the second half of the request. The Akka server code thinks the stream is still in use somewhere, as it doesn't know that the worker code has stopped reading the request.
7. That TCP connection is stalled, but the client doesn't know it. The next client request on that connection fails with a client timeout.
This test-case is tied to some of my app framework code. I'll try to minimise it into a test case and post it here or raise an issue.
Do you see what I mean?
I think we need some support for this case from the Akka framework -- it seems very difficult to deal with in userland code only.
Thanks very much,
Rich