summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2021-03-20 14:41:45 +0100
committerHauke Mehrtens <hauke@hauke-m.de>2021-03-21 22:22:12 +0100
commit15346de8d3ba422002496526ee24c62a3601ab8c (patch)
tree9f1f966a177c44b61c025b324da82ddb35653180
parentf53a63999784bcb7dc513e221f3f25dd3de2f35e (diff)
downloaduhttpd2-15346de8d3ba422002496526ee24c62a3601ab8c.tar.gz
client: Always close connection with request body in case of error
When we run into an error like a 404 Not Found the request body is not read and will be parsed as part of the next request. The next Request will then fail because there is unexpected data in it. When we run into such a problem with a request body close return an error and close the connection. This should be easier than trying to recover the state. We saw this problem when /ubus/ was not installed, but the browser tried to access it. Then uhttpd returned a 404, but the next request done in this connection also failed with a HTTP 400, bad request. Fixes: FS#3378 Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
-rw-r--r--client.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/client.c b/client.c
index 6233d01..2be8f22 100644
--- a/client.c
+++ b/client.c
@@ -138,6 +138,7 @@ void uh_request_done(struct client *cl)
void __printf(4, 5)
uh_client_error(struct client *cl, int code, const char *summary, const char *fmt, ...)
{
+ struct http_request *r = &cl->request;
va_list arg;
uh_http_header(cl, code, summary);
@@ -151,6 +152,17 @@ uh_client_error(struct client *cl, int code, const char *summary, const char *fm
va_end(arg);
}
+ /* Close the connection even when keep alive is set, when it
+ * contains a request body, as it was not read and we are
+ * currently out of sync. Without handling this the body will be
+ * interpreted as part of the next request. The alternative
+ * would be to read and discard the request body here.
+ */
+ if (r->transfer_chunked || r->content_length > 0) {
+ cl->state = CLIENT_STATE_CLOSE;
+ cl->request.connection_close = true;
+ }
+
uh_request_done(cl);
}