MINIR: mux-h1: Return 414 or 431 when appropriate

When the request is too large to fit in a buffer a 414 or a 431 error
message is returned depending on the error state of the request parser. A
414 is returned if the URI is too long, otherwise a 431 is returned.

This patch should fix the issue #1309.
This commit is contained in:
Christopher Faulet 2024-11-18 22:19:00 +01:00
parent 41f28b3c53
commit bc967758a2
3 changed files with 14 additions and 2 deletions

View File

@ -131,6 +131,7 @@ struct h1m {
uint64_t curr_len; // content-length or last chunk length
uint64_t body_len; // total known size of the body length
uint32_t next; // next byte to parse, relative to buffer's head
unsigned int err_code; // the HTTP status code corresponding to the error, if it can be specified (0: unset)
int err_pos; // position in the byte stream of the first error (H1 or H2)
int err_state; // state where the first error was met (H1 or H2)
};
@ -358,6 +359,7 @@ static inline struct h1m *h1m_init_req(struct h1m *h1m)
h1m->flags = H1_MF_NONE;
h1m->curr_len = 0;
h1m->body_len = 0;
h1m->err_code = 0;
h1m->err_pos = -2;
h1m->err_state = 0;
return h1m;
@ -371,6 +373,7 @@ static inline struct h1m *h1m_init_res(struct h1m *h1m)
h1m->flags = H1_MF_RESP;
h1m->curr_len = 0;
h1m->body_len = 0;
h1m->err_code = 0;
h1m->err_pos = -2;
h1m->err_state = 0;
return h1m;

View File

@ -163,8 +163,10 @@ static int h1_postparse_req_hdrs(struct h1m *h1m, union h1_sl *h1sl, struct htx
* size allowed.
*/
if (h1_eval_htx_size(meth, uri, vsn, hdrs) > max) {
if (htx_is_empty(htx))
if (htx_is_empty(htx)) {
h1m->err_code = 431;
goto error;
}
goto output_full;
}
@ -364,8 +366,13 @@ int h1_parse_msg_hdrs(struct h1m *h1m, union h1_sl *h1sl, struct htx *dsthtx,
* contains headers and is full, which is detected by it being
* full and the offset to be zero, it's an error because
* headers are too large to be handled by the parser. */
if (ret < 0 || (!ret && !ofs && !buf_room_for_htx_data(srcbuf)))
if (ret < 0)
goto error;
if (!ret && !ofs && !buf_room_for_htx_data(srcbuf)) {
if (!(h1m->flags & H1_MF_RESP))
h1m->err_code = (h1m->err_state < H1_MSG_HDR_FIRST) ? 414: 431;
goto error;
}
goto end;
}
total = ret;

View File

@ -1926,6 +1926,8 @@ static size_t h1_handle_headers(struct h1s *h1s, struct h1m *h1m, struct htx *ht
TRACE_DEVEL("leaving on missing data or error", H1_EV_RX_DATA|H1_EV_RX_HDRS, h1s->h1c->conn, h1s);
if (ret == -1) {
h1s->flags |= H1S_F_PARSING_ERROR;
if (h1m->err_code)
h1s->h1c->errcode = h1m->err_code;
TRACE_ERROR("parsing error, reject H1 message", H1_EV_RX_DATA|H1_EV_RX_HDRS|H1_EV_H1S_ERR, h1s->h1c->conn, h1s);
h1_capture_bad_message(h1s->h1c, h1s, h1m, buf);
}