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

Reply via email to