From: Willy Tarreau Date: Thu, 10 Apr 2014 09:59:33 +0000 (+0200) Subject: CLEANUP: http: prepare dedicated processing for chunked encoded message bodies X-Git-Tag: v1.5-dev23~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=890988f122eb8a5ecb05a914a781a3ac33abb904;p=thirdparty%2Fhaproxy.git CLEANUP: http: prepare dedicated processing for chunked encoded message bodies Content-length encoded message bodies are trivial to deal with, but chunked-encoded will require improvements, so let's separate the code flows between the two to ease next steps. The behaviour is not changed at all, the code is only rearranged. --- diff --git a/src/proto_http.c b/src/proto_http.c index 93cf033ebe..a1b064abdf 100644 --- a/src/proto_http.c +++ b/src/proto_http.c @@ -4298,26 +4298,27 @@ int http_wait_for_request_body(struct session *s, struct channel *req, int an_bi * related structures are ready. */ - if (unlikely(msg->msg_state < HTTP_MSG_BODY)) - goto missing_data; + if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) { + /* This is the first call */ + if (msg->msg_state < HTTP_MSG_BODY) + goto missing_data; - if (msg->msg_state < HTTP_MSG_100_SENT) { - /* If we have HTTP/1.1 and Expect: 100-continue, then we must - * send an HTTP/1.1 100 Continue intermediate response. - */ - if (msg->flags & HTTP_MSGF_VER_11) { - struct hdr_ctx ctx; - ctx.idx = 0; - /* Expect is allowed in 1.1, look for it */ - if (http_find_header2("Expect", 6, req->buf->p, &txn->hdr_idx, &ctx) && - unlikely(ctx.vlen == 12 && strncasecmp(ctx.line+ctx.val, "100-continue", 12) == 0)) { - bo_inject(s->rep, http_100_chunk.str, http_100_chunk.len); + if (msg->msg_state < HTTP_MSG_100_SENT) { + /* If we have HTTP/1.1 and Expect: 100-continue, then we must + * send an HTTP/1.1 100 Continue intermediate response. + */ + if (msg->flags & HTTP_MSGF_VER_11) { + struct hdr_ctx ctx; + ctx.idx = 0; + /* Expect is allowed in 1.1, look for it */ + if (http_find_header2("Expect", 6, req->buf->p, &txn->hdr_idx, &ctx) && + unlikely(ctx.vlen == 12 && strncasecmp(ctx.line+ctx.val, "100-continue", 12) == 0)) { + bo_inject(s->rep, http_100_chunk.str, http_100_chunk.len); + } } + msg->msg_state = HTTP_MSG_100_SENT; } - msg->msg_state = HTTP_MSG_100_SENT; - } - if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) { /* we have msg->sov which points to the first byte of message body. * req->buf->p still points to the beginning of the message and msg->sol * is still null. We must save the body in msg->next because it @@ -4331,6 +4332,17 @@ int http_wait_for_request_body(struct session *s, struct channel *req, int an_bi msg->msg_state = HTTP_MSG_DATA; } + if (!(msg->flags & HTTP_MSGF_TE_CHNK)) { + /* We're in content-length mode, we just have to wait for enough data. */ + if (req->buf->i - msg->sov < msg->body_len) + goto missing_data; + + /* OK we have everything we need now */ + goto http_end; + } + + /* OK here we're parsing a chunked-encoded message */ + if (msg->msg_state == HTTP_MSG_CHUNK_SIZE) { /* read the chunk size and assign it to ->chunk_len, then * set ->sov and ->next to point to the body and switch to DATA or @@ -4350,6 +4362,9 @@ int http_wait_for_request_body(struct session *s, struct channel *req, int an_bi * We have the first data byte is in msg->sov. We're waiting for at * least a whole chunk or the whole content length bytes after msg->sov. */ + if (msg->msg_state == HTTP_MSG_TRAILERS) + goto http_end; + if (req->buf->i - msg->sov >= msg->body_len) /* we have enough bytes now */ goto http_end;