htp_status_t htp_tx_state_request_line(htp_tx_t *tx) { if (tx == NULL) return HTP_ERROR; // Determine how to process the request URI. if (tx->request_method_number == HTP_M_CONNECT) { // When CONNECT is used, the request URI contains an authority string. if (htp_parse_uri_hostport(tx->connp, tx->request_uri, tx->parsed_uri_raw) != HTP_OK) { return HTP_ERROR; } } else { // Parse the request URI into htp_tx_t::parsed_uri_raw. if (htp_parse_uri(tx->request_uri, &(tx->parsed_uri_raw)) != HTP_OK) { return HTP_ERROR; } } // Build htp_tx_t::parsed_uri, but only if it was not explicitly set already. if (tx->parsed_uri == NULL) { tx->parsed_uri = htp_uri_alloc(); if (tx->parsed_uri == NULL) return HTP_ERROR; // Keep the original URI components, but create a copy which we can normalize and use internally. if (htp_normalize_parsed_uri(tx->connp, tx->parsed_uri_raw, tx->parsed_uri) != HTP_OK) { return HTP_ERROR; } } // Check parsed_uri hostname. if (tx->parsed_uri->hostname != NULL) { if (htp_validate_hostname(tx->parsed_uri->hostname) == 0) { tx->flags |= HTP_HOSTU_INVALID; } } // Run hook REQUEST_URI_NORMALIZE. htp_status_t rc = htp_hook_run_all(tx->connp->cfg->hook_request_uri_normalize, tx); if (rc != HTP_OK) return rc; // Run hook REQUEST_LINE. rc = htp_hook_run_all(tx->connp->cfg->hook_request_line, tx); if (rc != HTP_OK) return rc; // Move on to the next phase. tx->connp->in_state = htp_connp_REQ_PROTOCOL; return HTP_OK; }
htp_status_t htp_tx_state_request_line(htp_tx_t *tx) { htp_connp_t *connp = tx->connp; if (connp->in_tx->request_method_number == HTP_M_CONNECT) { // Parse authority if (htp_parse_uri_hostport(connp, connp->in_tx->request_uri, &(connp->in_tx->parsed_uri_incomplete)) != HTP_OK) { // Note: downstream responsible for error logging. return HTP_ERROR; } } else { // Parse the request URI if (htp_parse_uri(connp->in_tx->request_uri, &(connp->in_tx->parsed_uri_incomplete)) != HTP_OK) { // Note: downstream responsible for error logging. return HTP_ERROR; } // Keep the original URI components, but // create a copy which we can normalize and use internally. if (htp_normalize_parsed_uri(connp, connp->in_tx->parsed_uri_incomplete, connp->in_tx->parsed_uri) != HTP_OK) { // Note: downstream responsible for error logging. return HTP_ERROR; } // Run hook REQUEST_URI_NORMALIZE. int rc = htp_hook_run_all(connp->cfg->hook_request_uri_normalize, connp); if (rc != HTP_OK) return rc; // Now is a good time to generate request_uri_normalized, before we finalize // parsed_uri (and lose the information which parts were provided in the request and // which parts we added). if (connp->cfg->generate_request_uri_normalized) { connp->in_tx->request_uri_normalized = htp_unparse_uri_noencode(connp->in_tx->parsed_uri); if (connp->in_tx->request_uri_normalized == NULL) return HTP_ERROR; #ifdef HTP_DEBUG fprint_raw_data(stderr, "request_uri_normalized", (unsigned char *) bstr_ptr(connp->in_tx->request_uri_normalized), bstr_len(connp->in_tx->request_uri_normalized)); #endif } // Finalize parsed_uri. // Scheme. if (connp->in_tx->parsed_uri->scheme != NULL) { if (bstr_cmp_c(connp->in_tx->parsed_uri->scheme, "http") != 0) { // TODO Invalid scheme. } } else { connp->in_tx->parsed_uri->scheme = bstr_dup_c("http"); if (connp->in_tx->parsed_uri->scheme == NULL) { return HTP_ERROR; } } // Path. if (connp->in_tx->parsed_uri->path == NULL) { connp->in_tx->parsed_uri->path = bstr_dup_c("/"); if (connp->in_tx->parsed_uri->path == NULL) { return HTP_ERROR; } } } // Run hook REQUEST_LINE. int rc = htp_hook_run_all(connp->cfg->hook_request_line, connp); if (rc != HTP_OK) return rc; // Move on to the next phase. connp->in_state = htp_connp_REQ_PROTOCOL; return HTP_OK; }