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