From: Willy Tarreau Date: Thu, 13 Mar 2014 14:48:45 +0000 (+0100) Subject: MINOR: http: make msg->eol carry the last CRLF length X-Git-Tag: v1.5-dev23~31 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0558a02eb141a8f6d9e894834547cb64213e4ed4;p=thirdparty%2Fhaproxy.git MINOR: http: make msg->eol carry the last CRLF length 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. --- diff --git a/include/types/proto_http.h b/include/types/proto_http.h index 53e9fb4e83..95860c05e5 100644 --- a/include/types/proto_http.h +++ b/include/types/proto_http.h @@ -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 diff --git a/src/proto_http.c b/src/proto_http.c index a1b064abdf..7c0b7fe735 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -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;