From 669e6da163954718e7a8fcb5256b9910e89487b0 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sat, 2 Dec 2006 20:12:09 +0100 Subject: [PATCH] [BUG] implemented support for multi-line headers as required by RFC2616. This patch was added in 1.2.9 but was then incidentely reverted by manipulation error when merging next patch (enforce max number of conns). It's now merged again. --- src/proto_http.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/proto_http.c b/src/proto_http.c index f6a3ccd363..c4afe9c1e7 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -469,8 +469,10 @@ int process_cli(struct session *t) goto process_data; } - /* to get a complete header line, we need the ending \r\n, \n\r, \r or \n too */ - if (ptr > req->r - 2) { + /* To get a complete header line, we need the ending \r\n, \n\r, + * \r or \n, possibly followed by a white space or tab indicating + * that the header goes on next line. */ + if (ptr > req->r - 3) { /* this is a partial header, let's wait for more to come */ req->lr = ptr; break; @@ -484,6 +486,29 @@ int process_cli(struct session *t) else req->lr = ptr + 2; /* \r\n or \n\r */ + /* Now, try to detect multi-line headers. From RFC 2616 : + * HTTP/1.1 header field values can be folded onto multiple lines if the + * continuation line begins with a space or horizontal tab. All linear + * white space, including folding, has the same semantics as SP. A + * recipient MAY replace any linear white space with a single SP before + * interpreting the field value or forwarding the message downstream. + * + * LWS = [CRLF] 1*( SP | HT ) + */ + if (req->lr < req->r && + (*req->lr == ' ' || *req->lr == '\t')) { + /* we are allowed to replace the \r\n with spaces */ + while (ptr < req->lr) + *ptr++ = ' '; + /* now look for end of LWS */ + do { + req->lr++; + } while (req->lr < req->r && (*req->lr == ' ' || *req->lr == '\t')); + + /* continue processing on the same header */ + continue; + } + /* * now we know that we have a full header ; we can do whatever * we want with these pointers :