From 58f0d02445e2465e7b06c1d1b6262de3b86bd8b1 Mon Sep 17 00:00:00 2001
From: Mike Lundy <mike@fluffypenguin.org>
Date: Thu, 26 Apr 2012 16:10:20 -0700
Subject: [PATCH] Fix HTTP spec violation (chunked encoding vs.
 content-length)

The HTTP/1.1 spec (4.4.3) says: "If a message is received with both a
Transfer-Encoding header field and a Content-Length header field, the
latter MUST be ignored."

Instead of dropping the Content-Length field, pound drops whichever of
the two was sent last. This fixes that.
---
 http.c |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/http.c b/http.c
index bb2ce8b..80df52c 100644
--- a/http.c
+++ b/http.c
@@ -487,7 +487,7 @@ log_bytes(char *res, const LONG cnt)
 void
 do_http(thr_arg *arg)
 {
-    int                 cl_11, be_11, res, chunked, n, sock, no_cont, skip, conn_closed, force_10, sock_proto, is_rpc;
+    int                 cl_11, be_11, res, chunked, len_idx, n, sock, no_cont, skip, conn_closed, force_10, sock_proto, is_rpc;
     LISTENER            *lstn;
     SERVICE             *svc;
     BACKEND             *backend, *cur_backend, *old_backend;
@@ -651,7 +651,7 @@ do_http(thr_arg *arg)
         }
 
         /* check other headers */
-        for(chunked = 0, cont = L_1, n = 1; n < MAXHEADERS && headers[n]; n++) {
+        for(chunked = 0, len_idx = -1, cont = L_1, n = 1; n < MAXHEADERS && headers[n]; n++) {
             /* no overflow - see check_header for details */
             switch(check_header(headers[n], buf)) {
             case HEADER_HOST:
@@ -669,7 +669,7 @@ do_http(thr_arg *arg)
                 break;
             case HEADER_TRANSFER_ENCODING:
                 if(cont >= L0)
-                    headers_ok[n] = 0;
+                    headers_ok[len_idx] = 0;
                 else if(!strcasecmp("chunked", buf))
                     if(chunked)
                         headers_ok[n] = 0;
@@ -682,6 +682,8 @@ do_http(thr_arg *arg)
                 else
                     if((cont = ATOL(buf)) < 0L)
                         headers_ok[n] = 0;
+                    else
+                        len_idx = n;
                 break;
             case HEADER_ILLEGAL:
                 if(lstn->log_level > 0) {
-- 
1.7.8.5

