Claudio Jeker <clau...@openbsd.org> wrote: > On Tue, Jul 05, 2022 at 10:08:53AM +0000, alex.vatche...@gmail.com wrote: > > >Synopsis: httpd+slowcgi sometimes wrongly interpret next request > > >Category: daemon > > >Environment: > > System : OpenBSD 7.1 > > Details : OpenBSD 7.1 (GENERIC.MP) #3: Sun May 15 10:27:01 MDT 2022 > > > > r...@syspatch-71-amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP > > > > Architecture: OpenBSD.amd64 > > Machine : amd64 > > >Description: > > I've got web application OTOBO which is running on OpenBSD > > httpd/slowcgi. > > This application heavily uses AJAX. > > Sometimes I'm able to reproduce the situation when httpd daemon passes > > POST request to OTOBO script (via slowcgi) without POST data. > > And the application stops in waiting to it and then times out. > > After inspecting source code of httpd I've found the reason: > > the http client context is reset after slowcgi closes the connection. > > If the connection is not closed (httpd->slowcgi) and the client makes > > new request using the same TCP connection (www client -> www server) > > it httpd thinks that it already has got the request and headers.
I experienced a similar issue with both slowcgi and gotwebd (a fastcgi application.) Can you please try the diff I posted a couple of days ago on tech@? Thanks! https://marc.info/?l=openbsd-tech&m=165986324502568&w=2 diff c183a4a9bb1884f4cdfd8d6387478615af6f7a38 e159f975f5eeebad1ec6598ba5c76ab7c2eb45bd commit - c183a4a9bb1884f4cdfd8d6387478615af6f7a38 commit + e159f975f5eeebad1ec6598ba5c76ab7c2eb45bd blob - 381fade2924c4b5cea77cd9cd6500e75d4d59257 blob + b6541b7c68235ac1dfc5a9d0243db988e5932a7f --- usr.sbin/httpd/server_fcgi.c +++ usr.sbin/httpd/server_fcgi.c @@ -77,6 +77,7 @@ struct server_fcgi_param { }; int server_fcgi_header(struct client *, unsigned int); +void server_fcgi_error(struct bufferevent *, short, void *); void server_fcgi_read(struct bufferevent *, void *); int server_fcgi_writeheader(struct client *, struct kv *, void *); int server_fcgi_writechunk(struct client *); @@ -133,7 +134,7 @@ server_fcgi(struct httpd *env, struct client *clt) clt->clt_srvbev_throttled = 0; clt->clt_srvbev = bufferevent_new(fd, server_fcgi_read, - NULL, server_file_error, clt); + NULL, server_fcgi_error, clt); if (clt->clt_srvbev == NULL) { errstr = "failed to allocate fcgi buffer event"; goto fail; @@ -482,6 +483,23 @@ fcgi_add_param(struct server_fcgi_param *p, const char } void +server_fcgi_error(struct bufferevent *bev, short error, void *arg) +{ + struct client *clt = arg; + + if ((error & EVBUFFER_EOF) && !clt->clt_fcgi.headersdone) { + server_abort_http(clt, 500, "malformed or no headers"); + return; + } + + /* send the end marker if not already */ + if (clt->clt_fcgi.chunked && !clt->clt_fcgi.end++) + server_bufferevent_print(clt, "0\r\n\r\n"); + + server_file_error(bev, error, arg); +} + +void server_fcgi_read(struct bufferevent *bev, void *arg) { uint8_t buf[FCGI_RECORD_SIZE];