diff mbox series

[uhttpd,v2] client: Always close connection with request body in case of error

Message ID 20210321125510.4126686-1-hauke@hauke-m.de
State Accepted
Delegated to: Hauke Mehrtens
Headers show
Series [uhttpd,v2] client: Always close connection with request body in case of error | expand

Commit Message

Hauke Mehrtens March 21, 2021, 12:55 p.m. UTC
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>
---
 client.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
diff mbox series

Patch

diff --git a/client.c b/client.c
index 6233d01..451f90d 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,16 @@  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. 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);
 }