The current code hides gross errors in the Status header generated by
fastcgi applications:
- Bogus codes are converted to 200.
- The presence of multple Status headers is not reported as an error.

IMHO, this doesn't really help anyone.

The patch below attempts to address both these concerns.

Ross


Index: server_fcgi.c
===================================================================
RCS file: /cvs/src/usr.sbin/httpd/server_fcgi.c,v
retrieving revision 1.81
diff -u -p -r1.81 server_fcgi.c
--- server_fcgi.c       9 Feb 2020 09:44:04 -0000       1.81
+++ server_fcgi.c       11 Jul 2020 11:08:53 -0000
@@ -141,7 +141,7 @@ server_fcgi(struct httpd *env, struct cl
        memset(hbuf, 0, sizeof(hbuf));
        clt->clt_fcgi.state = FCGI_READ_HEADER;
        clt->clt_fcgi.toread = sizeof(struct fcgi_record_header);
-       clt->clt_fcgi.status = 200;
+       clt->clt_fcgi.status = 0; /* -1 = err; 0 = not set; ... */
        clt->clt_fcgi.headersdone = 0;
 
        if (clt->clt_srvevb != NULL)
@@ -574,7 +574,11 @@ server_fcgi_read(struct bufferevent *bev
                                        clt->clt_fcgi.headersdone =
                                            server_fcgi_getheaders(clt);
                                        if (clt->clt_fcgi.headersdone) {
-                                               if (server_fcgi_header(clt,
+                                               if (clt->clt_fcgi.status == 0)
+                                                       clt->clt_fcgi.status
+                                                           = 200;
+                                               if (clt->clt_fcgi.status == -1
+                                                   || server_fcgi_header(clt,
                                                    clt->clt_fcgi.status)
                                                    == -1) {
                                                        server_abort_http(clt,
@@ -797,12 +801,17 @@ server_fcgi_getheaders(struct client *cl
                DPRINTF("%s: %s: %s", __func__, key, value);
 
                if (strcasecmp("Status", key) == 0) {
-                       value[strcspn(value, " \t")] = '\0';
-                       code = (int)strtonum(value, 100, 600, &errstr);
-                       if (errstr != NULL || server_httperror_byid(
-                           code) == NULL)
-                               code = 200;
-                       clt->clt_fcgi.status = code;
+                       if (clt->clt_fcgi.status != 0)
+                               /* This is not the first status header. */
+                               clt->clt_fcgi.status = -1;
+                       else {
+                               value[strcspn(value, " \t")] = '\0';
+                               code = (int)strtonum(value, 100, 600, &errstr);
+                               if (errstr != NULL || server_httperror_byid(
+                                   code) == NULL)
+                                       code = -1;
+                               clt->clt_fcgi.status = code;
+                       }
                } else {
                        (void)kv_add(&resp->http_headers, key, value);
                }

Reply via email to