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)
};
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;
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;
* 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;
}
* 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;
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);
}