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.
This commit is contained in:
Willy Tarreau 2014-04-10 11:59:33 +02:00
parent 5a8f947f4f
commit 890988f122

View File

@ -4298,26 +4298,27 @@ int http_wait_for_request_body(struct session *s, struct channel *req, int an_bi
* related structures are ready. * related structures are ready.
*/ */
if (unlikely(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);
}
}
msg->msg_state = HTTP_MSG_100_SENT;
}
if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) { 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);
}
}
msg->msg_state = HTTP_MSG_100_SENT;
}
/* we have msg->sov which points to the first byte of message body. /* 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 * 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 * 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; 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) { if (msg->msg_state == HTTP_MSG_CHUNK_SIZE) {
/* read the chunk size and assign it to ->chunk_len, then /* 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 * 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 * 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. * 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 */ if (req->buf->i - msg->sov >= msg->body_len) /* we have enough bytes now */
goto http_end; goto http_end;