/** * Processes identity request body. * * @param[in] connp * @returns HTP_OK on state change, HTP_ERROR on error, or HTP_DATA when more data is needed. */ htp_status_t htp_connp_REQ_BODY_IDENTITY(htp_connp_t *connp) { // Determine how many bytes we can consume. size_t bytes_to_consume; if (connp->in_current_len - connp->in_current_read_offset >= connp->in_body_data_left) { bytes_to_consume = connp->in_body_data_left; } else { bytes_to_consume = connp->in_current_len - connp->in_current_read_offset; } // If the input buffer is empty, ask for more data. if (bytes_to_consume == 0) return HTP_DATA; // Consume data. int rc = htp_tx_req_process_body_data_ex(connp->in_tx, connp->in_current_data + connp->in_current_read_offset, bytes_to_consume); if (rc != HTP_OK) return rc; // Adjust counters. connp->in_current_read_offset += bytes_to_consume; connp->in_current_consume_offset += bytes_to_consume; connp->in_stream_offset += bytes_to_consume; connp->in_tx->request_message_len += bytes_to_consume; connp->in_body_data_left -= bytes_to_consume; if (connp->in_body_data_left == 0) { // End of request body. connp->in_state = htp_connp_REQ_FINALIZE; return HTP_OK; } // Ask for more data. return HTP_DATA; }
/** * Processes a chunk of data. * * @param[in] connp * @returns HTP_OK on state change, HTP_ERROR on error, or HTP_DATA when more data is needed. */ htp_status_t htp_connp_REQ_BODY_CHUNKED_DATA(htp_connp_t *connp) { // Determine how many bytes we can consume. size_t bytes_to_consume; if (connp->in_current_len - connp->in_current_read_offset >= connp->in_chunked_length) { // Entire chunk available in the buffer; read all of it. bytes_to_consume = connp->in_chunked_length; } else { // Partial chunk available in the buffer; read as much as we can. bytes_to_consume = connp->in_current_len - connp->in_current_read_offset; } #ifdef HTP_DEBUG fprintf(stderr, "htp_connp_REQ_BODY_CHUNKED_DATA Consuming %zd bytes\n", bytes_to_consume); #endif // If the input buffer is empty, ask for more data. if (bytes_to_consume == 0) return HTP_DATA; // Consume the data. htp_status_t rc = htp_tx_req_process_body_data_ex(connp->in_tx, connp->in_current_data + connp->in_current_read_offset, bytes_to_consume); if (rc != HTP_OK) return rc; // Adjust counters. connp->in_current_read_offset += bytes_to_consume; connp->in_current_consume_offset += bytes_to_consume; connp->in_stream_offset += bytes_to_consume; connp->in_tx->request_message_len += bytes_to_consume; connp->in_chunked_length -= bytes_to_consume; if (connp->in_chunked_length == 0) { // End of the chunk. connp->in_state = htp_connp_REQ_BODY_CHUNKED_DATA_END; return HTP_OK; } // Ask for more data. return HTP_DATA; }
htp_status_t htp_tx_state_request_complete_partial(htp_tx_t *tx) { if (tx == NULL) return HTP_ERROR; // Finalize request body. if (htp_tx_req_has_body(tx)) { htp_status_t rc = htp_tx_req_process_body_data_ex(tx, NULL, 0); if (rc != HTP_OK) return rc; } tx->request_progress = HTP_REQUEST_COMPLETE; // Run hook REQUEST_COMPLETE. htp_status_t rc = htp_hook_run_all(tx->connp->cfg->hook_request_complete, tx); if (rc != HTP_OK) return rc; // Clean-up. if (tx->connp->put_file != NULL) { bstr_free(tx->connp->put_file->filename); free(tx->connp->put_file); tx->connp->put_file = NULL; } return HTP_OK; }
htp_status_t htp_tx_req_process_body_data(htp_tx_t *tx, const void *data, size_t len) { if ((tx == NULL) || (data == NULL)) return HTP_ERROR; if (len == 0) return HTP_OK; return htp_tx_req_process_body_data_ex(tx, data, len); }