MEDIUM: http: headers must be forwarded even if data was already inspected

Currently, we forward headers only if the incoming message is still before
HTTP_MSG_CHUNK_SIZE, otherwise they'll be considered as data. In practice
this is always true for the response since there's no data inspection, and
for the request there is no compression so there's no problem with forwarding
them as data.

But the principle is incorrect and will make it difficult to later add data
processing features. So better fix it now.

The new principle is simple :
  - if headers were not yet forwarded, forward them now.
  - while doing so, check if we need to update the state
This commit is contained in:
Willy Tarreau 2014-04-22 14:29:58 +02:00
parent 6fef8ae047
commit b59c7bfc95

View File

@ -5027,20 +5027,26 @@ int http_request_forward_body(struct session *s, struct channel *req, int an_bit
* an "Expect: 100-continue" header.
*/
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. We
* must save the body in msg->next because it survives buffer
* re-alignments.
if (msg->sov) {
/* we have msg->sov which points to the first byte of message
* body, and req->buf.p still points to the beginning of the
* message. We forward the headers now, as we don't need them
* anymore, and we want to flush them.
*/
channel_forward(req, msg->sov);
msg->next = 0;
msg->sov = 0;
b_adv(req->buf, msg->sov);
msg->next -= msg->sov;
msg->sov = 0;
if (msg->flags & HTTP_MSGF_TE_CHNK)
msg->msg_state = HTTP_MSG_CHUNK_SIZE;
else
msg->msg_state = HTTP_MSG_DATA;
/* The previous analysers guarantee that the state is somewhere
* between MSG_BODY and the first MSG_DATA. So msg->sol and
* msg->next are always correct.
*/
if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) {
if (msg->flags & HTTP_MSGF_TE_CHNK)
msg->msg_state = HTTP_MSG_CHUNK_SIZE;
else
msg->msg_state = HTTP_MSG_DATA;
}
}
/* Some post-connect processing might want us to refrain from starting to
@ -6184,19 +6190,26 @@ int http_response_forward_body(struct session *s, struct channel *res, int an_bi
goto aborted_xfer; /* no memory */
}
if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) {
/* we have msg->sov which points to the first byte of message body.
* res->buf.p still points to the beginning of the message. We
* forward the headers, we don't need them.
if (msg->sov) {
/* we have msg->sov which points to the first byte of message
* body, and res->buf.p still points to the beginning of the
* message. We forward the headers now, as we don't need them
* anymore, and we want to flush them.
*/
channel_forward(res, msg->sov);
msg->next = 0;
msg->sov = 0;
b_adv(res->buf, msg->sov);
msg->next -= msg->sov;
msg->sov = 0;
if (msg->flags & HTTP_MSGF_TE_CHNK)
msg->msg_state = HTTP_MSG_CHUNK_SIZE;
else
msg->msg_state = HTTP_MSG_DATA;
/* The previous analysers guarantee that the state is somewhere
* between MSG_BODY and the first MSG_DATA. So msg->sol and
* msg->next are always correct.
*/
if (msg->msg_state < HTTP_MSG_CHUNK_SIZE) {
if (msg->flags & HTTP_MSGF_TE_CHNK)
msg->msg_state = HTTP_MSG_CHUNK_SIZE;
else
msg->msg_state = HTTP_MSG_DATA;
}
}
if (s->comp_algo != NULL) {