]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: http: make msg->eol carry the last CRLF length
authorWilly Tarreau <w@1wt.eu>
Thu, 13 Mar 2014 14:48:45 +0000 (15:48 +0100)
committerWilly Tarreau <w@1wt.eu>
Tue, 22 Apr 2014 21:15:28 +0000 (23:15 +0200)
One of the issues we face when we need to either forward headers only
before compressing, or rewind the stream during a redispatch is to know
the proper length of the request headers. msg->eoh always has the total
length up to the last CRLF, and we never know whether the request ended
with a single LF or a standard CRLF. This makes it hard to rewind the
headers without explicitly checking the bytes in the buffer.

Instead of doing so, we now use msg->eol to carry the length of the last
CRLF (either 1 or 2). Since it is not modified at all after HTTP_MSG_BODY,
and was only left in an undefined state, it is safe to use at any moment.

Thus, the complete header length to forward or to rewind now is always
msg->eoh + msg->eol.

include/types/proto_http.h
src/proto_http.c

index 53e9fb4e830725e556b78cc23e8b6da37efadcf3..95860c05e5ab7d7148f567e1499eae34b546a301 100644 (file)
@@ -320,11 +320,22 @@ enum {
  *                             for states after START. When in HTTP_MSG_BODY,
  *                             eoh points to the first byte of the last CRLF
  *                             preceeding data. Relative to buffer's origin.
+ *                             This value then remains unchanged till the end
+ *                             so that we can rewind the buffer to change some
+ *                             headers if needed (eg: http-send-name-header).
+ *
  *  - sov                    : When in HTTP_MSG_BODY, will point to the first
  *                             byte of data (relative to buffer's origin).
  *  - sol (start of line)    : start of current line during parsing, or zero.
- *  - eol (End of Line)      : relative offset in the buffer of the first byte
- *                             which marks the end of the line (LF or CRLF).
+ *
+ *  - eol (End of Line)      : Before HTTP_MSG_BODY, relative offset in the
+ *                             buffer of the first byte which marks the end of
+ *                             the line current (LF or CRLF).
+ *                             From HTTP_MSG_BODY to the end, contains the
+ *                             length of the last CRLF (1 for a plain LF, or 2
+ *                             for a true CRLF). So eoh+eol always contain the
+ *                             exact size of the header size.
+ *
  * Note that all offsets are relative to the origin of the buffer (buf->p)
  * which always points to the beginning of the message (request or response).
  * Since a message may not wrap, pointer computations may be one without any
index a1b064abdfcd33f263a01161665ee6ba27d7e829..7c0b7fe735974062d621c4bba780a9b8a57ef938 100644 (file)
@@ -1731,12 +1731,16 @@ void http_msg_analyzer(struct http_msg *msg, struct hdr_idx *idx)
 
        case HTTP_MSG_LAST_LF:
        http_msg_last_lf:
-               /* Assumes msg->sol points to the first of either CR or LF */
+               /* Assumes msg->sol points to the first of either CR or LF.
+                * Sets ->sov and ->next to the total header length, ->eoh to
+                * the last CRLF, and ->eol to the last CRLF length (1 or 2).
+                */
                EXPECT_LF_HERE(ptr, http_msg_invalid);
                ptr++;
                msg->sov = msg->next = ptr - buf->p;
                msg->eoh = msg->sol;
                msg->sol = 0;
+               msg->eol = msg->sov - msg->eoh;
                msg->msg_state = HTTP_MSG_BODY;
                return;