147
147
* @return Method number of M_UNKNOWN
149
149
int htp_convert_method_to_number(bstr *method) {
150
if (method == NULL) return M_UNKNOWN;
150
151
// TODO Optimize using parallel matching, or something
151
152
if (bstr_cmpc(method, "GET") == 0) return M_GET;
152
153
if (bstr_cmpc(method, "PUT") == 0) return M_PUT;
1228
1234
if (incomplete->path != NULL) {
1229
1235
// Make a copy of the path, on which we can work on
1230
1236
normalized->path = bstr_strdup(incomplete->path);
1232
// Decode URL-encoded (and %u-encoded) characters, as well as lowercase,
1233
// compress separators and convert backslashes.
1234
htp_decode_path_inplace(connp->cfg, connp->in_tx, normalized->path);
1236
// Handle UTF-8 in path
1237
if (connp->cfg->path_convert_utf8) {
1238
// Decode Unicode characters into a single-byte stream, using best-fit mapping
1239
htp_utf8_decode_path_inplace(connp->cfg, connp->in_tx, normalized->path);
1241
// Only validate path as a UTF-8 stream
1242
htp_utf8_validate_path(connp->in_tx, normalized->path);
1237
if (normalized->path != NULL) {
1238
// Decode URL-encoded (and %u-encoded) characters, as well as lowercase,
1239
// compress separators and convert backslashes.
1240
htp_decode_path_inplace(connp->cfg, connp->in_tx, normalized->path);
1242
// Handle UTF-8 in path
1243
if (connp->cfg->path_convert_utf8) {
1244
// Decode Unicode characters into a single-byte stream, using best-fit mapping
1245
htp_utf8_decode_path_inplace(connp->cfg, connp->in_tx, normalized->path);
1247
// Only validate path as a UTF-8 stream
1248
htp_utf8_validate_path(connp->in_tx, normalized->path);
1251
// RFC normalization
1252
htp_normalize_uri_path_inplace(normalized->path);
1245
// RFC normalization
1246
htp_normalize_uri_path_inplace(normalized->path);
1841
1852
for (i = 0; i < list_size(tx->request_header_lines); i++) {
1842
1853
htp_header_line_t *hl = list_get(tx->request_header_lines, i);
1843
1854
bstr_add_str_noex(request_headers_raw, hl->line);
1855
if (hl->terminators)
1856
bstr_add_str_noex(request_headers_raw, hl->terminators);
1858
bstr_add_cstr_noex(request_headers_raw, "\r\n");
1846
1861
return request_headers_raw;
1879
1894
return tx->request_headers_raw;
1898
* Construct a bstr that contains the raw response headers.
1903
bstr *htp_tx_generate_response_headers_raw(htp_tx_t *tx) {
1904
bstr *response_headers_raw = NULL;
1907
for (i = 0; i < list_size(tx->response_header_lines); i++) {
1908
htp_header_line_t *hl = list_get(tx->response_header_lines, i);
1909
len += bstr_len(hl->line);
1910
if (hl->terminators)
1911
len += bstr_len(hl->terminators);
1916
response_headers_raw = bstr_alloc(len);
1917
if (response_headers_raw == NULL) {
1918
htp_log(tx->connp, HTP_LOG_MARK, HTP_LOG_ERROR, 0, "Failed to allocate bstring of %d bytes", len);
1922
for (i = 0; i < list_size(tx->response_header_lines); i++) {
1923
htp_header_line_t *hl = list_get(tx->response_header_lines, i);
1924
bstr_add_str_noex(response_headers_raw, hl->line);
1925
if (hl->terminators)
1926
bstr_add_str_noex(response_headers_raw, hl->terminators);
1928
bstr_add_cstr_noex(response_headers_raw, "\r\n");
1931
return response_headers_raw;
1935
* Get a bstr that contains the raw response headers. This method will always
1936
* return an up-to-date buffer, containing the last known headers. Thus, if
1937
* it is called once after RESPONSE_HEADERS phase it will return one buffer, but
1938
* it may return a different buffer if called after RESPONSE_TRAILERS phase (but
1939
* only if the response actually contains trailer headers). Do not retain the
1940
* bstr pointer, as the buffer may change. If there are no changes to the
1941
* response header structure, only one buffer will be contstructed and used. (Multiple
1942
* invocations of this method will not cause multiple buffers to be created.)
1947
bstr *htp_tx_get_response_headers_raw(htp_tx_t *tx) {
1948
// Check that we are not called too early
1949
if (tx->progress < TX_PROGRESS_RES_HEADERS) return NULL;
1951
if (tx->response_headers_raw == NULL) {
1952
tx->response_headers_raw = htp_tx_generate_response_headers_raw(tx);
1953
tx->response_headers_raw_lines = list_size(tx->response_header_lines);
1955
// Check that the buffer we have is not obsolete
1956
if (tx->response_headers_raw_lines < list_size(tx->response_header_lines)) {
1957
// Rebuild raw buffer
1958
bstr_free(tx->response_headers_raw);
1959
tx->response_headers_raw = htp_tx_generate_response_headers_raw(tx);
1960
tx->response_headers_raw_lines = list_size(tx->response_header_lines);
1964
return tx->response_headers_raw;