Hi,

When httpd received the following request,

  POST /cgi-bin/test.cgi HTTP/1.0
  Host: 127.0.0.1
  Content-Type: application/json
  Content-Length: 0

if the request is handled by fastcgi, STDIN is closed immediately.

But the problem is that STDIN is never closed if the request doesn't
have "Content-Length" header like the following.  read(STDIN) doesn't
return forever.

  POST /cgi-bin/test.cgi HTTP/1.0
  Host: 127.0.0.1
  Content-Type: application/json

In RFC7230 Section 3.3.3

|   6.  If this is a request message and none of the above are true, then
|       the message body length is zero (no message body is present).

it mentions the body length is zero if both Content-Length and
Content-Transfer-Encoding is not specified.

The diff is to fix the problm.

ok?

Treat the message body length as 0 byte if Content-Length is not
specified and chunked transfer is not used.

Index: usr.sbin/httpd/server_http.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_http.c,v
retrieving revision 1.136
diff -u -p -r1.136 server_http.c
--- usr.sbin/httpd/server_http.c        14 Jan 2020 20:48:57 -0000      1.136
+++ usr.sbin/httpd/server_http.c        4 Feb 2020 06:30:14 -0000
@@ -421,12 +421,12 @@ server_read_http(struct bufferevent *bev
                        /* HTTP request payload */
                        if (clt->clt_toread > 0)
                                bev->readcb = server_read_httpcontent;
-
-                       /* Single-pass HTTP body */
-                       if (clt->clt_toread < 0) {
-                               clt->clt_toread = TOREAD_UNLIMITED;
-                               bev->readcb = server_read;
-                       }
+                       else if (!desc->http_chunked)
+                               /*
+                                * When no content-length and no chunked
+                                * transfer, it means body length is zero.
+                                */
+                               clt->clt_toread = 0;
                        break;
                default:
                        server_abort_http(clt, 405, "method not allowed");

Reply via email to