MEDIUM: http: make the chunk crlf parser only depend on the buffer

The chunk crlf parser used to depend on the channel and on the HTTP
message, eventhough it's not really needed. Let's remove this dependency
so that it can be used within the H2 to H1 gateway.

As part of this small API change, it was renamed to h1_skip_chunk_crlf()
to mention that it doesn't depend on http_msg anymore.
This commit is contained in:
Willy Tarreau 2017-09-21 11:33:54 +02:00
parent e56cdd3629
commit b28925675d
2 changed files with 16 additions and 16 deletions

View File

@ -139,22 +139,19 @@ static inline const char *h1_msg_state_str(enum h1_state msg_state)
* caller must ensure that ->p points to the first byte to parse. It returns * caller must ensure that ->p points to the first byte to parse. It returns
* the number of bytes parsed on success, so the caller can set msg_state to * the number of bytes parsed on success, so the caller can set msg_state to
* HTTP_MSG_CHUNK_SIZE. If not enough data are available, the function does not * HTTP_MSG_CHUNK_SIZE. If not enough data are available, the function does not
* change anything and returns zero. If a parse error is encountered, the * change anything and returns zero. Otherwise it returns a negative value
* function returns < 0. Note: this function is designed to parse wrapped CRLF * indicating the error positionn relative to <stop>. Note: this function is
* at the end of the buffer. * designed to parse wrapped CRLF at the end of the buffer.
*/ */
static inline int http_skip_chunk_crlf(struct http_msg *msg) static inline int h1_skip_chunk_crlf(const struct buffer *buf, int start, int stop)
{ {
const struct buffer *buf = msg->chn->buf; const char *ptr = b_ptr(buf, start);
const char *ptr; int bytes = 1;
int bytes;
/* NB: we'll check data availabilty at the end. It's not a /* NB: we'll check data availabilty at the end. It's not a
* problem because whatever we match first will be checked * problem because whatever we match first will be checked
* against the correct length. * against the correct length.
*/ */
bytes = 1;
ptr = b_ptr(buf, msg->next);
if (*ptr == '\r') { if (*ptr == '\r') {
bytes++; bytes++;
ptr++; ptr++;
@ -162,13 +159,12 @@ static inline int http_skip_chunk_crlf(struct http_msg *msg)
ptr = buf->data; ptr = buf->data;
} }
if (msg->next + bytes > buf->i) if (bytes > stop - start)
return 0; return 0;
if (*ptr != '\n') { if (*ptr != '\n')
msg->err_pos = buffer_count(buf, buf->p, ptr); return -buffer_count(buf, ptr, b_ptr(buf, stop));
return -1;
}
return bytes; return bytes;
} }

View File

@ -6156,11 +6156,15 @@ http_msg_forward_chunked_body(struct stream *s, struct http_msg *msg)
case HTTP_MSG_CHUNK_CRLF: case HTTP_MSG_CHUNK_CRLF:
/* we want the CRLF after the data */ /* we want the CRLF after the data */
ret = http_skip_chunk_crlf(msg); ret = h1_skip_chunk_crlf(chn->buf, msg->next, chn->buf->i);
if (ret == 0) if (ret == 0)
goto missing_data_or_waiting; goto missing_data_or_waiting;
if (ret < 0) if (ret < 0) {
msg->err_pos = chn->buf->i + ret;
if (msg->err_pos < 0)
msg->err_pos += chn->buf->size;
goto chunk_parsing_error; goto chunk_parsing_error;
}
msg->next += ret; msg->next += ret;
msg->msg_state = HTTP_MSG_CHUNK_SIZE; msg->msg_state = HTTP_MSG_CHUNK_SIZE;
/* fall through for HTTP_MSG_CHUNK_SIZE */ /* fall through for HTTP_MSG_CHUNK_SIZE */