htp: keep track of header line terminators so http_raw_header can reconstruct exact headers.

remotes/origin/HEAD
Victor Julien 13 years ago
parent 3d12b74012
commit d236e68b62

@ -704,7 +704,10 @@ struct htp_header_line_t {
/** Parsing flags: HTP_FIELD_INVALID_NOT_FATAL, HTP_FIELD_INVALID_FATAL, HTP_FIELD_LONG */
unsigned int flags;
/** terminator characters, if NULL assume RFC compliant 0d 0a */
bstr *terminators;
/** Header that uses this line. */
htp_header_t *header;
};

@ -460,7 +460,8 @@ int htp_connp_REQ_HEADERS(htp_connp_t *connp) {
}
// Prepare line for consumption
int chomp_result = htp_chomp(connp->in_line, &connp->in_line_len);
size_t raw_in_line_len = connp->in_line_len;
htp_chomp(connp->in_line, &connp->in_line_len);
// Check for header folding
if (htp_connp_is_line_folded(connp->in_line, connp->in_line_len) == 0) {
@ -491,11 +492,27 @@ int htp_connp_REQ_HEADERS(htp_connp_t *connp) {
}
// Add the raw header line to the list
connp->in_header_line->line = bstr_memdup((char *) connp->in_line, connp->in_line_len + chomp_result);
if (raw_in_line_len > connp->in_line_len) {
if (raw_in_line_len - connp->in_line_len == 2 &&
connp->in_line[connp->in_line_len] == 0x0d &&
connp->in_line[connp->in_line_len + 1] == 0x0a) {
connp->in_header_line->terminators = NULL;
} else {
connp->in_header_line->terminators =
bstr_memdup((char *) connp->in_line + connp->in_line_len,
raw_in_line_len - connp->in_line_len);
if (connp->in_header_line->terminators == NULL) {
return HTP_ERROR;
}
}
} else {
connp->in_header_line->terminators = NULL;
}
connp->in_header_line->line = bstr_memdup((char *) connp->in_line, connp->in_line_len);
if (connp->in_header_line->line == NULL) {
return HTP_ERROR;
}
list_add(connp->in_tx->request_header_lines, connp->in_header_line);
connp->in_header_line = NULL;

@ -487,6 +487,7 @@ int htp_connp_RES_HEADERS(htp_connp_t *connp) {
}
// Prepare line for consumption
size_t raw_out_line_len = connp->out_line_len;
htp_chomp(connp->out_line, &connp->out_line_len);
// Check for header folding
@ -517,6 +518,24 @@ int htp_connp_RES_HEADERS(htp_connp_t *connp) {
}
// Add the raw header line to the list
if (raw_out_line_len > connp->out_line_len) {
if (raw_out_line_len - connp->out_line_len == 2 &&
connp->out_line[connp->out_line_len] == 0x0d &&
connp->out_line[connp->out_line_len + 1] == 0x0a) {
connp->out_header_line->terminators = NULL;
} else {
connp->out_header_line->terminators =
bstr_memdup((char *) connp->out_line + connp->out_line_len,
raw_out_line_len - connp->out_line_len);
if (connp->out_header_line->terminators == NULL) {
return HTP_ERROR;
}
}
} else {
connp->out_header_line->terminators = NULL;
}
connp->out_header_line->line = bstr_memdup((char *) connp->out_line, connp->out_line_len);
if (connp->out_header_line->line == NULL) {
return HTP_ERROR;

@ -1830,6 +1830,10 @@ bstr *htp_tx_generate_request_headers_raw(htp_tx_t *tx) {
for (i = 0; i < list_size(tx->request_header_lines); i++) {
htp_header_line_t *hl = list_get(tx->request_header_lines, i);
len += bstr_len(hl->line);
if (hl->terminators)
len += bstr_len(hl->terminators);
else
len += 2; // 0d 0a
}
request_headers_raw = bstr_alloc(len);
@ -1841,6 +1845,10 @@ bstr *htp_tx_generate_request_headers_raw(htp_tx_t *tx) {
for (i = 0; i < list_size(tx->request_header_lines); i++) {
htp_header_line_t *hl = list_get(tx->request_header_lines, i);
bstr_add_str_noex(request_headers_raw, hl->line);
if (hl->terminators)
bstr_add_str_noex(request_headers_raw, hl->terminators);
else
bstr_add_cstr_noex(request_headers_raw, "\r\n");
}
return request_headers_raw;
@ -1892,6 +1900,10 @@ bstr *htp_tx_generate_response_headers_raw(htp_tx_t *tx) {
for (i = 0; i < list_size(tx->response_header_lines); i++) {
htp_header_line_t *hl = list_get(tx->response_header_lines, i);
len += bstr_len(hl->line);
if (hl->terminators)
len += bstr_len(hl->terminators);
else
len += 2; // 0d 0a
}
response_headers_raw = bstr_alloc(len);
@ -1903,6 +1915,10 @@ bstr *htp_tx_generate_response_headers_raw(htp_tx_t *tx) {
for (i = 0; i < list_size(tx->response_header_lines); i++) {
htp_header_line_t *hl = list_get(tx->response_header_lines, i);
bstr_add_str_noex(response_headers_raw, hl->line);
if (hl->terminators)
bstr_add_str_noex(response_headers_raw, hl->terminators);
else
bstr_add_cstr_noex(response_headers_raw, "\r\n");
}
return response_headers_raw;

Loading…
Cancel
Save