Skip to content

Commit bc96775

Browse files
committed
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.
1 parent 41f28b3 commit bc96775

File tree

3 files changed

+14
-2
lines changed

3 files changed

+14
-2
lines changed

include/haproxy/h1.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ struct h1m {
131131
uint64_t curr_len; // content-length or last chunk length
132132
uint64_t body_len; // total known size of the body length
133133
uint32_t next; // next byte to parse, relative to buffer's head
134+
unsigned int err_code; // the HTTP status code corresponding to the error, if it can be specified (0: unset)
134135
int err_pos; // position in the byte stream of the first error (H1 or H2)
135136
int err_state; // state where the first error was met (H1 or H2)
136137
};
@@ -358,6 +359,7 @@ static inline struct h1m *h1m_init_req(struct h1m *h1m)
358359
h1m->flags = H1_MF_NONE;
359360
h1m->curr_len = 0;
360361
h1m->body_len = 0;
362+
h1m->err_code = 0;
361363
h1m->err_pos = -2;
362364
h1m->err_state = 0;
363365
return h1m;
@@ -371,6 +373,7 @@ static inline struct h1m *h1m_init_res(struct h1m *h1m)
371373
h1m->flags = H1_MF_RESP;
372374
h1m->curr_len = 0;
373375
h1m->body_len = 0;
376+
h1m->err_code = 0;
374377
h1m->err_pos = -2;
375378
h1m->err_state = 0;
376379
return h1m;

src/h1_htx.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,10 @@ static int h1_postparse_req_hdrs(struct h1m *h1m, union h1_sl *h1sl, struct htx
163163
* size allowed.
164164
*/
165165
if (h1_eval_htx_size(meth, uri, vsn, hdrs) > max) {
166-
if (htx_is_empty(htx))
166+
if (htx_is_empty(htx)) {
167+
h1m->err_code = 431;
167168
goto error;
169+
}
168170
goto output_full;
169171
}
170172

@@ -364,8 +366,13 @@ int h1_parse_msg_hdrs(struct h1m *h1m, union h1_sl *h1sl, struct htx *dsthtx,
364366
* contains headers and is full, which is detected by it being
365367
* full and the offset to be zero, it's an error because
366368
* headers are too large to be handled by the parser. */
367-
if (ret < 0 || (!ret && !ofs && !buf_room_for_htx_data(srcbuf)))
369+
if (ret < 0)
370+
goto error;
371+
if (!ret && !ofs && !buf_room_for_htx_data(srcbuf)) {
372+
if (!(h1m->flags & H1_MF_RESP))
373+
h1m->err_code = (h1m->err_state < H1_MSG_HDR_FIRST) ? 414: 431;
368374
goto error;
375+
}
369376
goto end;
370377
}
371378
total = ret;

src/mux_h1.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,6 +1926,8 @@ static size_t h1_handle_headers(struct h1s *h1s, struct h1m *h1m, struct htx *ht
19261926
TRACE_DEVEL("leaving on missing data or error", H1_EV_RX_DATA|H1_EV_RX_HDRS, h1s->h1c->conn, h1s);
19271927
if (ret == -1) {
19281928
h1s->flags |= H1S_F_PARSING_ERROR;
1929+
if (h1m->err_code)
1930+
h1s->h1c->errcode = h1m->err_code;
19291931
TRACE_ERROR("parsing error, reject H1 message", H1_EV_RX_DATA|H1_EV_RX_HDRS|H1_EV_H1S_ERR, h1s->h1c->conn, h1s);
19301932
h1_capture_bad_message(h1s->h1c, h1s, h1m, buf);
19311933
}

0 commit comments

Comments
 (0)