diff options
| author | Lu <[email protected]> | 2018-07-13 19:58:21 +0800 |
|---|---|---|
| committer | Lu <[email protected]> | 2018-07-13 19:58:21 +0800 |
| commit | 029c1140317f76229690b8aa89e10b78f9d6a19d (patch) | |
| tree | 38222f2a33d81a640db94b20cfb9ce1e5b628078 | |
| parent | 660e3fbe82371b090a57f6ae1b30ebd5fb98947e (diff) | |
实现对Chunk类型的应答内容的解析 #2
| -rw-r--r-- | src/http1.cc | 29 | ||||
| -rw-r--r-- | src/httpscan.cc | 97 | ||||
| -rw-r--r-- | src/httpscan.h | 10 |
3 files changed, 127 insertions, 9 deletions
diff --git a/src/http1.cc b/src/http1.cc index ac02b58..2011bd6 100644 --- a/src/http1.cc +++ b/src/http1.cc @@ -670,17 +670,22 @@ int Http1ResponseParserCallbacks::CallbackOnMessageComplete(http_parser * parser int Http1ResponseParserCallbacks::CallbackOnChunkHeader(http_parser * parser) { + auto * resp_ptr = __response_this_ptr(parser); + resp_ptr->__set_section_state(resp_ptr->kSectionBody, resp_ptr->kStateReading); + /* On chunk begin, setup chunk tag */ - __response_this_ptr(parser)->body_is_chunk = true; - __response_this_ptr(parser)->body_chunk_id++; + resp_ptr->body_is_chunk = true; + resp_ptr->body_chunk_id++; /* Drop old body content */ - __response_this_ptr(parser)->body_content_ = nullptr; + resp_ptr->body_content_ = nullptr; return 0; } int Http1ResponseParserCallbacks::CallbackOnChunkComplete(http_parser * parser) { + auto * resp_ptr = __response_this_ptr(parser); + resp_ptr->__set_section_state(resp_ptr->kSectionBody, resp_ptr->kStateComplete); return 0; } @@ -848,28 +853,36 @@ int Http1Connection::on_connection_read_response(pxy_conn_ctx_t * conn_ctx, pxy_ conn_ctx->passthrough = 1; return 0; } + else if (forward_len == 0) + { + return 0; + } if (response.SectionState(response.kSectionHeader) == response.kStateComplete) { http_session.CallRequestHeaderCallback(); - goto __forward; } if (response.SectionState(response.kSectionBody) == response.kStateComplete) { http_session.CallResponseBodyCallback(); - goto __forward; } + /* 如果有任何一部分为Reading,说明该部分数据还为到来,暂时不转发 */ + if (response.SectionState(response.kSectionHeader) == response.kStateReading || + response.SectionState(response.kSectionBody) == response.kStateReading) + { + return 0; + } + + /* 转发缓存中的数据,如果该Response处理结束,本Session处理完毕,销毁Session */ + evbuffer_add_buffer(upstream_evbuf, response.StolenEvBuf().release()); if (response.SectionState(response.kSectionMessage) == response.kStateComplete) { drop_last_session(); } return 0; - -__forward: - evbuffer_add_buffer(upstream_evbuf, response.StolenEvBuf().release()); } HttpSession & Http1Connection::create_new_session() diff --git a/src/httpscan.cc b/src/httpscan.cc index 6366f85..29ee773 100644 --- a/src/httpscan.cc +++ b/src/httpscan.cc @@ -232,14 +232,109 @@ void HttpScanSession::ScanRequestBody(HttpSession * http_session_ctx) void HttpScanSession::ScanResponseHeader(HttpSession * http_session_ctx) { + auto & response = http_session_ctx->response(); + + /* 扫描应答头部 */ + auto scan_result = scan_headers(response.cHeaders(), httpscan_module_ref_.table_id_ctrl_http_res_hdr); + + /* Hit */ + if (scan_result == scan_result_t::kScanResultHit) + { + http_session_ctx->SetResponseHeaderTag(http_session_ctx->kCallbackTagRepeat); + return hit_config_and_do_action(http_session_ctx); + } + /* Error */ + else if (scan_result == scan_result_t::kScanResultError) + { + return hit_scan_error(); + } + + /* Not Hit */ return; } void HttpScanSession::ScanResponseBody(HttpSession * http_session_ctx) { + auto & response = http_session_ctx->response(); + + /* Body Content and length, prepare for maat */ + const char * body_content_raw = response.Body()->data(); + size_t body_content_length = response.Body()->size(); + + auto scan_result = scan_body(body_content_raw, body_content_length, + httpscan_module_ref_.table_id_ctrl_http_res_body); + + /* Hit */ + if (scan_result == scan_result_t::kScanResultHit) + { + http_session_ctx->SetResponseBodyTag(http_session_ctx->kCallbackTagRepeat); + return hit_config_and_do_action(http_session_ctx); + } + /* Error */ + else if (scan_result == scan_result_t::kScanResultError) + { + return hit_scan_error(); + } + return; } +HttpScanSession::scan_result_t HttpScanSession::scan_headers(const HttpHeaders & c_headers, int table_id) +{ + scan_result_t scan_result = scan_result_t::kScanResultNotHit; + + c_headers.ForEachHeader([this, &scan_result, table_id] + (const std::string & field, const std::string & value) -> bool + { + int ret = Maat_set_scan_status(httpscan_module_ref_.maat_feather_ref, &maat_scan_mid_, + MAAT_SET_SCAN_DISTRICT, field.c_str(), (int) field.length()); + + if (ret < 0) + { + scan_result = scan_result_t::kScanResultError; + return false; + } + + int __dummy[MAAT_SCAN_RESULT_]; + + nr_maat_scan_result_ = Maat_full_scan_string(httpscan_module_ref_.maat_feather_ref, + table_id, MAAT_DEFAULT_CHARSET_, value.c_str(), (int) value.length(), maat_scan_result_, __dummy, + MAAT_SCAN_RESULT_, &maat_scan_mid_, 0); + + if (nr_maat_scan_result_ > 0) + { + scan_result = scan_result_t::kScanResultHit; + return false; + } + else if (nr_maat_scan_result_ == -1) + { + scan_result = scan_result_t::kScanResultError; + return false; + } + + return true; + }); + + return scan_result; +} + +HttpScanSession::scan_result_t HttpScanSession::scan_body(const char * data, size_t len, int table_id) +{ + /* Dummy For maat */ + int __dummy[MAAT_SCAN_RESULT_]; + + nr_maat_scan_result_ = Maat_full_scan_string(httpscan_module_ref_.maat_feather_ref, + table_id, CHARSET_UTF8, data, (int) len, maat_scan_result_, __dummy, MAAT_SCAN_RESULT_, &maat_scan_mid_, 0); + + if (nr_maat_scan_result_ > 0) + return scan_result_t::kScanResultHit; + + else if (nr_maat_scan_result_ == -1) + return scan_result_t::kScanResultError; + + return scan_result_t::kScanResultNotHit; +} + void HttpScanSession::hit_config_and_do_action(HttpSession * session) { /* 判断命中数量,若为多命中,选择优先级最高的动作执行 */ @@ -300,4 +395,4 @@ void HttpScanSession::hit_config_and_do_action(HttpSession * session) void HttpScanSession::hit_scan_error() { return; -}
\ No newline at end of file +} diff --git a/src/httpscan.h b/src/httpscan.h index 6b3fd1f..e3891ce 100644 --- a/src/httpscan.h +++ b/src/httpscan.h @@ -68,6 +68,16 @@ public: void ScanResponseBody(HttpSession *http_session_ctx); private: + enum class scan_result_t + { + kScanResultNotHit = 0, + kScanResultHit = 1, + kScanResultError = -1 + }; + + scan_result_t scan_headers(const HttpHeaders & c_headers, int table_id); + scan_result_t scan_body(const char * data, size_t len, int table_id); + void hit_config_and_do_action(HttpSession *session); void hit_scan_error(); |
