Florian Obser([email protected]) on 2021.05.15 17:14:38 +0200:
> Turns out it's not that difficult to do this correctly since we already
> wait until we read all http headers from the fcgi upstream. We just need
> to delay writing of the http header until we know if the body is empty
> or not.
> 
> OK?

seems to work, ok benno@

The comments in server_fcgi_header seem to suggest more dragons lurk in this
area.

> 
> 
> diff --git httpd.h httpd.h
> index b3a40b3af68..c4adfba232d 100644
> --- httpd.h
> +++ httpd.h
> @@ -300,6 +300,7 @@ struct fcgi_data {
>       int                      end;
>       int                      status;
>       int                      headersdone;
> +     int                      headerssent;
>  };
>  
>  struct range {
> diff --git server_fcgi.c server_fcgi.c
> index 64a0e9d2abb..e1e9704c920 100644
> --- server_fcgi.c
> +++ server_fcgi.c
> @@ -114,6 +114,7 @@ server_fcgi(struct httpd *env, struct client *clt)
>       clt->clt_fcgi.toread = sizeof(struct fcgi_record_header);
>       clt->clt_fcgi.status = 200;
>       clt->clt_fcgi.headersdone = 0;
> +     clt->clt_fcgi.headerssent = 0;
>  
>       if (clt->clt_srvevb != NULL)
>               evbuffer_free(clt->clt_srvevb);
> @@ -544,22 +545,20 @@ server_fcgi_read(struct bufferevent *bev, void *arg)
>                               if (!clt->clt_fcgi.headersdone) {
>                                       clt->clt_fcgi.headersdone =
>                                           server_fcgi_getheaders(clt);
> -                                     if (clt->clt_fcgi.headersdone) {
> -                                             if (server_fcgi_header(clt,
> -                                                 clt->clt_fcgi.status)
> -                                                 == -1) {
> -                                                     server_abort_http(clt,
> -                                                         500,
> -                                                         "malformed fcgi "
> -                                                         "headers");
> -                                                     return;
> -                                             }
> -                                     }
>                                       if (!EVBUFFER_LENGTH(clt->clt_srvevb))
>                                               break;
>                               }
>                               /* FALLTHROUGH */
>                       case FCGI_END_REQUEST:
> +                             if (clt->clt_fcgi.headersdone &&
> +                                 !clt->clt_fcgi.headerssent) {
> +                                     if (server_fcgi_header(clt,
> +                                         clt->clt_fcgi.status) == -1) {
> +                                             server_abort_http(clt, 500,
> +                                                 "malformed fcgi headers");
> +                                             return;
> +                                     }
> +                             }
>                               if (server_fcgi_writechunk(clt) == -1) {
>                                       server_abort_http(clt, 500,
>                                           "encoding error");
> @@ -600,6 +599,8 @@ server_fcgi_header(struct client *clt, unsigned int code)
>       char                     tmbuf[32];
>       struct kv               *kv, *cl, key;
>  
> +     clt->clt_fcgi.headerssent = 1;
> +
>       if (desc == NULL || (error = server_httperror_byid(code)) == NULL)
>               return (-1);
>  
> @@ -615,6 +616,12 @@ server_fcgi_header(struct client *clt, unsigned int code)
>       if (kv_add(&resp->http_headers, "Server", HTTPD_SERVERNAME) == NULL)
>               return (-1);
>  
> +     if (clt->clt_fcgi.type == FCGI_END_REQUEST ||
> +         EVBUFFER_LENGTH(clt->clt_srvevb) == 0) {
> +             /* Can't chunk encode an empty body. */
> +             clt->clt_fcgi.chunked = 0;
> +     }
> +
>       /* Set chunked encoding */
>       if (clt->clt_fcgi.chunked) {
>               /* XXX Should we keep and handle Content-Length instead? */
> 
> 
> -- 
> I'm not entirely sure you are real.
> 

Reply via email to