if (++ptr >= end)
ptr = buf->data;
if (chunk & 0xF000000) /* overflow will occur */
- return -1;
+ goto error;
chunk = (chunk << 4) + c;
}
/* empty size not allowed */
if (ptr == buf->lr)
- return -1;
+ goto error;
while (http_is_spht[(unsigned char)*ptr]) {
if (++ptr >= end)
}
if (*ptr != '\n')
- return -1;
+ goto error;
if (++ptr >= end)
ptr = buf->data;
/* done */
continue;
}
else
- return -1;
+ goto error;
}
/* OK we found our CRLF and now <ptr> points to the next byte,
msg->hdr_content_len = chunk;
msg->msg_state = chunk ? HTTP_MSG_DATA : HTTP_MSG_TRAILERS;
return 1;
+ error:
+ msg->err_pos = ptr - buf->data;
+ return -1;
}
/* This function skips trailers in the buffer <buf> associated with HTTP
}
if (*ptr == '\r') {
- if (p1)
+ if (p1) {
+ msg->err_pos = ptr - buf->data;
return -1;
+ }
p1 = ptr;
}
if (bytes > buf->l - buf->send_max)
return 0;
- if (*ptr != '\n')
+ if (*ptr != '\n') {
+ msg->err_pos = ptr - buf->data;
return -1;
+ }
ptr++;
if (ptr >= buf->data + buf->size)
goto missing_data;
else if (ret < 0) {
session_inc_http_err_ctr(s);
+ if (msg->err_pos >= 0)
+ http_capture_bad_message(&s->fe->invalid_req, s, req, msg, HTTP_MSG_CHUNK_SIZE, s->be);
goto return_bad_req;
}
/* otherwise we're in HTTP_MSG_DATA or HTTP_MSG_TRAILERS state */
goto missing_data;
else if (ret < 0) {
session_inc_http_err_ctr(s);
+ if (msg->err_pos >= 0)
+ http_capture_bad_message(&s->fe->invalid_req, s, req, msg, HTTP_MSG_DATA_CRLF, s->be);
goto return_bad_req;
}
/* we're in MSG_CHUNK_SIZE now */
goto missing_data;
else if (ret < 0) {
session_inc_http_err_ctr(s);
+ if (msg->err_pos >= 0)
+ http_capture_bad_message(&s->fe->invalid_req, s, req, msg, HTTP_MSG_TRAILERS, s->be);
goto return_bad_req;
}
/* we're in HTTP_MSG_DONE now */
}
else {
+ int old_state = msg->msg_state;
+
/* other states, DONE...TUNNEL */
/* for keep-alive we don't want to forward closes on DONE */
if ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL ||
if (!(s->flags & SN_FINST_MASK))
s->flags |= SN_FINST_D;
}
+ if (msg->err_pos >= 0)
+ http_capture_bad_message(&s->fe->invalid_req, s, req, msg, old_state, s->be);
goto return_bad_req;
}
return 1;
if (!ret)
goto missing_data;
- else if (ret < 0)
+ else if (ret < 0) {
+ if (msg->err_pos >= 0)
+ http_capture_bad_message(&s->be->invalid_rep, s, res, msg, HTTP_MSG_CHUNK_SIZE, s->fe);
goto return_bad_res;
+ }
/* otherwise we're in HTTP_MSG_DATA or HTTP_MSG_TRAILERS state */
/* Don't set a PUSH at the end of that chunk if it's not the last one */
if (msg->msg_state == HTTP_MSG_DATA)
if (!ret)
goto missing_data;
- else if (ret < 0)
+ else if (ret < 0) {
+ if (msg->err_pos >= 0)
+ http_capture_bad_message(&s->be->invalid_rep, s, res, msg, HTTP_MSG_DATA_CRLF, s->fe);
goto return_bad_res;
+ }
/* we're in MSG_CHUNK_SIZE now */
}
else if (msg->msg_state == HTTP_MSG_TRAILERS) {
if (ret == 0)
goto missing_data;
- else if (ret < 0)
+ else if (ret < 0) {
+ if (msg->err_pos >= 0)
+ http_capture_bad_message(&s->be->invalid_rep, s, res, msg, HTTP_MSG_TRAILERS, s->fe);
goto return_bad_res;
+ }
/* we're in HTTP_MSG_DONE now */
}
else {
+ int old_state = msg->msg_state;
+
/* other states, DONE...TUNNEL */
/* for keep-alive we don't want to forward closes on DONE */
if ((txn->flags & TX_CON_WANT_MSK) == TX_CON_WANT_KAL ||
if (!(s->flags & SN_FINST_MASK))
s->flags |= SN_FINST_D;
}
+ if (msg->err_pos >= 0)
+ http_capture_bad_message(&s->be->invalid_rep, s, res, msg, old_state, s->fe);
goto return_bad_res;
}
return 1;