[BUG] http: offsets are relative to the buffer, not to ->som

Some wrong operations were performed on buffers, assuming the
offsets were relative to the beginning of the request while they
are relative to the beginning of the buffer. In practice this is
not yet an issue since both are the same... until we add support
for keep-alive.
This commit is contained in:
Willy Tarreau 2009-12-27 15:50:06 +01:00
parent d21e01c63f
commit 1d3bcce4dd
2 changed files with 17 additions and 41 deletions

View File

@ -259,9 +259,12 @@ typedef enum {
* eoh points to the first byte of the last CRLF
* preceeding data.
* - col and sov : When in HTTP_MSG_BODY, will point to the first
* byte of data.
* byte of data (relative to buffer).
* - sol (start of line) : start of line, also start of message when fully parsed.
* - eol (End of Line) : relative offset in the buffer of the first byte
* which marks the end of the line (LF or CRLF).
* Note that all offsets are relative to the beginning of the buffer. To get
* them relative to the current request, subtract ->som.
*/
struct http_msg {
unsigned int msg_state; /* where we are in the current message parsing */

View File

@ -1404,21 +1404,12 @@ void http_msg_analyzer(struct buffer *buf, struct http_msg *msg, struct hdr_idx
http_msg_rpbefore:
case HTTP_MSG_RPBEFORE:
if (likely(HTTP_IS_TOKEN(*ptr))) {
#if !defined(PARSE_PRESERVE_EMPTY_LINES)
if (likely(ptr != buf->data)) {
/* Remove empty leading lines, as recommended by
* RFC2616. This takes a lot of time because we
* must move all the buffer backwards, but this
* is rarely needed. The method above will be
* cleaner when we'll be able to start sending
* the request from any place in the buffer.
*/
ptr += buffer_replace2(buf, buf->lr, ptr, NULL, 0);
end = buf->r;
}
#endif
msg->sol = ptr;
if (likely(ptr != buf->data + msg->som)) {
/* Remove empty leading lines, as recommended by RFC2616. */
buffer_ignore(buf, ptr - buf->data - msg->som);
msg->som = ptr - buf->data;
}
msg->sol = ptr;
hdr_idx_init(idx);
state = HTTP_MSG_RPVER;
goto http_msg_rpver;
@ -1473,30 +1464,12 @@ void http_msg_analyzer(struct buffer *buf, struct http_msg *msg, struct hdr_idx
http_msg_rqbefore:
case HTTP_MSG_RQBEFORE:
if (likely(HTTP_IS_TOKEN(*ptr))) {
if (likely(ptr == buf->data)) {
msg->sol = ptr;
msg->som = 0;
} else {
#if PARSE_PRESERVE_EMPTY_LINES
/* only skip empty leading lines, don't remove them */
msg->sol = ptr;
if (likely(ptr != buf->data + msg->som)) {
/* Remove empty leading lines, as recommended by RFC2616. */
buffer_ignore(buf, ptr - buf->data - msg->som);
msg->som = ptr - buf->data;
#else
/* Remove empty leading lines, as recommended by
* RFC2616. This takes a lot of time because we
* must move all the buffer backwards, but this
* is rarely needed. The method above will be
* cleaner when we'll be able to start sending
* the request from any place in the buffer.
*/
buf->lr = ptr;
buffer_replace2(buf, buf->data, buf->lr, NULL, 0);
msg->som = 0;
msg->sol = buf->data;
ptr = buf->data;
end = buf->r;
#endif
}
msg->sol = ptr;
/* we will need this when keep-alive will be supported
hdr_idx_init(idx);
*/
@ -2136,9 +2109,9 @@ int http_wait_for_request(struct session *s, struct buffer *req, int an_bit)
/* ... and check if the request is HTTP/1.1 or above */
if ((msg->sl.rq.v_l == 8) &&
((req->data[msg->som + msg->sl.rq.v + 5] > '1') ||
((req->data[msg->som + msg->sl.rq.v + 5] == '1') &&
(req->data[msg->som + msg->sl.rq.v + 7] >= '1'))))
((req->data[msg->sl.rq.v + 5] > '1') ||
((req->data[msg->sl.rq.v + 5] == '1') &&
(req->data[msg->sl.rq.v + 7] >= '1'))))
txn->flags |= TX_REQ_VER_11;
/* "connection" has not been parsed yet */
@ -2657,7 +2630,7 @@ int http_process_request(struct session *s, struct buffer *req, int an_bit)
/* It needs to look into the URI */
if ((s->sessid == NULL) && s->be->appsession_name) {
get_srv_from_appsession(s, &req->data[msg->som + msg->sl.rq.u], msg->sl.rq.u_l);
get_srv_from_appsession(s, &req->data[msg->sl.rq.u], msg->sl.rq.u_l);
}
/*
@ -2789,7 +2762,7 @@ int http_process_request(struct session *s, struct buffer *req, int an_bit)
s->txn.meth == HTTP_METH_POST && s->be->url_param_name != NULL &&
s->be->url_param_post_limit != 0 &&
(txn->flags & (TX_REQ_CNT_LEN|TX_REQ_TE_CHNK)) &&
memchr(msg->sol + msg->sl.rq.u, '?', msg->sl.rq.u_l) == NULL) {
memchr(req->data + msg->sl.rq.u, '?', msg->sl.rq.u_l) == NULL) {
buffer_dont_connect(req);
req->analysers |= AN_REQ_HTTP_BODY;
}