On Wed, Aug 10, 2022 at 09:06:03AM +0200, Omar Polo wrote: > Claudio Jeker <[email protected]> wrote: > > On Tue, Jul 05, 2022 at 10:08:53AM +0000, [email protected] 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 > > > > > > [email protected]:/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]; >
Looks good to me. OK claudio@ -- :wq Claudio
