]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4738: pub_sub: Can now get all headers, response str and method from...
authorSteve Chew (stechew) <stechew@cisco.com>
Mon, 12 May 2025 20:37:27 +0000 (20:37 +0000)
committerSteve Chew (stechew) <stechew@cisco.com>
Mon, 12 May 2025 20:37:27 +0000 (20:37 +0000)
Merge in SNORT/snort3 from ~STECHEW/snort3:update_http_event to master

Squashed commit of the following:

commit 0e25d6025597408baa71bb7b0396c2affc7f746b
Author: Steve Chew <stechew@cisco.com>
Date:   Sat May 10 15:58:00 2025 -0400

    pub_sub: Can now get all headers, response str and method from HttpEvent.

src/pub_sub/http_events.cc
src/pub_sub/http_events.h
src/pub_sub/test/pub_sub_http_event_test.cc

index 9805e3b230bb30aa9906a5a522fa60c97963ca9f..75676adde29f370ec116e761724fb071c2d8a505 100644 (file)
@@ -47,6 +47,12 @@ const uint8_t* HttpEvent::get_header(unsigned id, uint64_t sub_id, int32_t& leng
     }
 }
 
+// Returns all HTTP headers plus cookies.
+const uint8_t* HttpEvent::get_all_raw_headers(int32_t& length)
+{
+    return get_header(HttpEnums::HTTP_BUFFER_RAW_HEADER, 0, length);
+}
+
 const uint8_t* HttpEvent::get_content_type(int32_t& length)
 {
     return get_header(HttpEnums::HTTP_BUFFER_HEADER,
@@ -115,6 +121,11 @@ const uint8_t* HttpEvent::get_referer(int32_t& length)
         length);
 }
 
+const uint8_t*  HttpEvent::get_response_phrase(int32_t &length)
+{
+    return get_header(HttpEnums::HTTP_BUFFER_STAT_MSG, 0, length);
+}
+
 int32_t HttpEvent::get_response_code()
 {
     return http_msg_header->get_status_code_num();
@@ -164,6 +175,11 @@ const uint8_t* HttpEvent::get_x_working_with(int32_t& length)
         HttpEnums::HEAD_X_WORKING_WITH, length);
 }
 
+const uint8_t* HttpEvent::get_method(int32_t& length)
+{
+    return get_header(HttpEnums::HTTP_BUFFER_METHOD, 0, length);
+}
+
 bool HttpEvent::contains_webdav_method()
 {
     HttpEnums::MethodId method = http_msg_header->get_method_id();
index 1d8a9b1bb6846b0abba7b45eeedf921792a0ff58..debe7f87a33958e8c4da3a3ab65fb17e2cda059b 100644 (file)
@@ -37,12 +37,14 @@ public:
     HttpEvent(HttpMsgHeader* http_msg_header_, bool httpx, int64_t stream_id) :
         http_msg_header(http_msg_header_), is_httpx(httpx), httpx_stream_id(stream_id) { }
 
+    const uint8_t* get_all_raw_headers(int32_t &length); // Returns all HTTP headers plus cookies.
     const uint8_t* get_content_type(int32_t &length);
     const uint8_t* get_cookie(int32_t &length);
     const uint8_t* get_authority(int32_t &length);
     const uint8_t* get_uri_host(int32_t &length);
     const uint8_t* get_uri_query(int32_t &length);
     const uint8_t* get_location(int32_t &length);
+    const uint8_t* get_method(int32_t &length);
     const uint8_t* get_referer(int32_t &length);
     const uint8_t* get_server(int32_t &length);
     const uint8_t* get_trueip_addr(int32_t& length);
@@ -50,6 +52,7 @@ public:
     const uint8_t* get_user_agent(int32_t &length);
     const uint8_t* get_via(int32_t &length);
     const uint8_t* get_x_working_with(int32_t &length);
+    const uint8_t* get_response_phrase(int32_t &length);
     int32_t get_response_code();
     bool contains_webdav_method();
     bool get_is_httpx() const;
index a963e8476bc49c1479fdb65a36413203b3c23d34..0851de65f04cc3a1f2bfc48a54f55a36b8658a4b 100644 (file)
@@ -49,8 +49,13 @@ void Field::set(const Field& input)
 }
 
 const Field Field::FIELD_NULL { STAT_NO_SOURCE };
-const Field& HttpMsgSection::get_classic_buffer(unsigned, uint64_t, uint64_t)
-{ return Field::FIELD_NULL; }
+const Field& HttpMsgSection::get_classic_buffer(unsigned buffer_type, uint64_t, uint64_t)
+{
+    mock().actualCall("get_classic_buffer").withParameter("buffer_type", buffer_type);
+    Field *out = (Field*)mock().getData("output").getObjectPointer();
+    return (*out);
+}
+
 const Field& HttpMsgHeader::get_true_ip_addr()
 {
     Field *out = (Field*)mock().getData("output").getObjectPointer();
@@ -113,6 +118,55 @@ TEST(pub_sub_http_event_test, true_ip_addr)
     mock().checkExpectations();
 }
 
+TEST(pub_sub_http_event_test, get_method)
+{
+    const uint8_t* header_start;
+    int32_t header_length;
+
+    mock().expectOneCall("get_classic_buffer").withParameter("buffer_type", HttpEnums::HTTP_BUFFER_METHOD);
+    Field input(7, (const uint8_t*) "CONNECT");
+    mock().setDataObject("output", "Field", &input);
+    HttpEvent event(nullptr, false, 0);
+    header_start = event.get_method(header_length);
+    CHECK(7 == header_length);
+    CHECK(memcmp(header_start, "CONNECT", 7) == 0);
+    mock().checkExpectations();
+}
+
+TEST(pub_sub_http_event_test, get_response_phrase)
+{
+    const uint8_t* header_start;
+    int32_t header_length;
+
+    mock().expectOneCall("get_classic_buffer").withParameter("buffer_type", HttpEnums::HTTP_BUFFER_STAT_MSG);
+
+    Field input(7, (const uint8_t*) "CONNECT");
+    mock().setDataObject("output", "Field", &input);
+    HttpEvent event(nullptr, false, 0);
+    header_start = event.get_response_phrase(header_length);
+    CHECK(7 == header_length);
+    CHECK(memcmp(header_start, "CONNECT", 7) == 0);
+    mock().checkExpectations();
+}
+
+TEST(pub_sub_http_event_test, get_all_raw_headers)
+{
+    const char* headers = "Content-Type: application/pdf\n"
+        "Content-Length: 20000\n";
+    int32_t header_length = strlen(headers);
+    const uint8_t* header_start;
+    int32_t discovered_length;
+
+    mock().expectOneCall("get_classic_buffer").withParameter("buffer_type", HttpEnums::HTTP_BUFFER_RAW_HEADER);
+    Field input(header_length, (const uint8_t*) headers);
+    mock().setDataObject("output", "Field", &input);
+    HttpEvent event(nullptr, false, 0);
+    header_start = event.get_all_raw_headers(discovered_length);
+    CHECK(discovered_length == header_length);
+    CHECK(memcmp(header_start, headers, header_length) == 0);
+    mock().checkExpectations();
+}
+
 int main(int argc, char** argv)
 {
     return CommandLineTestRunner::RunAllTests(argc, argv);