Padding of fcgi records is optional, but if we receive padding data we
authorflorian <florian@openbsd.org>
Sat, 2 Aug 2014 17:05:18 +0000 (17:05 +0000)
committerflorian <florian@openbsd.org>
Sat, 2 Aug 2014 17:05:18 +0000 (17:05 +0000)
should read it.

usr.sbin/httpd/httpd.h
usr.sbin/httpd/server_fcgi.c

index 10a7d54..3a387ed 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: httpd.h,v 1.31 2014/08/02 11:52:00 reyk Exp $ */
+/*     $OpenBSD: httpd.h,v 1.32 2014/08/02 17:05:18 florian Exp $      */
 
 /*
  * Copyright (c) 2006 - 2014 Reyk Floeter <reyk@openbsd.org>
@@ -239,7 +239,8 @@ struct privsep_proc {
 
 enum fcgistate {
        FCGI_READ_HEADER,
-       FCGI_READ_CONTENT
+       FCGI_READ_CONTENT,
+       FCGI_READ_PADDING
 };
 
 struct client {
@@ -270,6 +271,7 @@ struct client {
        int                      clt_inflight;
        enum fcgistate           clt_fcgi_state;
        int                      clt_fcgi_toread;
+       int                      clt_fcgi_padding_len;
        int                      clt_fcgi_type;
        struct evbuffer         *clt_srvevb;
 
index 7f19016..f375d8a 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: server_fcgi.c,v 1.10 2014/08/02 11:59:04 florian Exp $        */
+/*     $OpenBSD: server_fcgi.c,v 1.11 2014/08/02 17:05:18 florian Exp $        */
 
 /*
  * Copyright (c) 2014 Florian Obser <florian@openbsd.org>
@@ -451,10 +451,12 @@ server_fcgi_read(struct bufferevent *bev, void *arg)
                        h = (struct fcgi_record_header *)
                            EVBUFFER_DATA(clt->clt_srvevb);
                        DPRINTF("%s: record header: version %d type %d id %d "
-                           "content len %d", __func__, h->version, h->type,
-                           ntohs(h->id), ntohs(h->content_len));
+                           "content len %d padding %d", __func__,
+                            h->version, h->type, ntohs(h->id),
+                            ntohs(h->content_len), h->padding_len);
                        clt->clt_fcgi_type = h->type;
                        clt->clt_fcgi_toread = ntohs(h->content_len);
+                       clt->clt_fcgi_padding_len = h->padding_len;
                        evbuffer_drain(clt->clt_srvevb,
                            EVBUFFER_LENGTH(clt->clt_srvevb));
                        if (clt->clt_fcgi_toread != 0)
@@ -469,11 +471,25 @@ server_fcgi_read(struct bufferevent *bev, void *arg)
                                server_bufferevent_write_buffer(clt,
                                    clt->clt_srvevb);
                        }
+                       evbuffer_drain(clt->clt_srvevb,
+                           EVBUFFER_LENGTH(clt->clt_srvevb));
+                       if (!clt->clt_fcgi_padding_len) {
+                               clt->clt_fcgi_state = FCGI_READ_HEADER;
+                               clt->clt_fcgi_toread =
+                                   sizeof(struct fcgi_record_header);
+                       } else {
+                               clt->clt_fcgi_state = FCGI_READ_PADDING;
+                               clt->clt_fcgi_toread =
+                                   clt->clt_fcgi_padding_len;
+                       }
+                       break;
+               case FCGI_READ_PADDING:
                        evbuffer_drain(clt->clt_srvevb,
                            EVBUFFER_LENGTH(clt->clt_srvevb));
                        clt->clt_fcgi_state = FCGI_READ_HEADER;
                        clt->clt_fcgi_toread =
                            sizeof(struct fcgi_record_header);
+                       break;
                }
        } while (len > 0);
 }