From: Tom Peters Date: Fri, 13 Jun 2014 20:53:28 +0000 (-0400) Subject: URI parsing X-Git-Tag: 3.0.0-233~1480^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cd701ef7d705ad2fee80425590d11cc9f7cff5dd;p=thirdparty%2Fsnort3.git URI parsing --- diff --git a/src/service_inspectors/nhttp_inspect/nhttp_enum.h b/src/service_inspectors/nhttp_inspect/nhttp_enum.h index 7f571bb4c..d17225981 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_enum.h +++ b/src/service_inspectors/nhttp_inspect/nhttp_enum.h @@ -51,13 +51,19 @@ typedef enum { SEC__NOTCOMPUTE=-4, SEC__NOTPRESENT=-1, SEC_REQUEST = 2, SEC_STAT typedef enum { VERS__NOTCOMPUTE=-4, VERS__PROBLEMATIC=-2, VERS__NOTPRESENT=-1, VERS__OTHER=1, VERS_1_0, VERS_1_1, VERS_2_0 } VersionId; // Every request method we have ever heard of -typedef enum { METH__NOTCOMPUTE=-4, METH__INSUFMEMORY=-3, METH__PROBLEMATIC=-2, METH__NOTPRESENT=-1, METH__OTHER=1, METH_GET, METH_HEAD, METH_POST, METH_PUT, METH_DELETE, METH_TRACE, - METH_CONNECT, METH_PROPFIND, +typedef enum { METH__NOTCOMPUTE=-4, METH__INSUFMEMORY=-3, METH__PROBLEMATIC=-2, METH__NOTPRESENT=-1, METH__OTHER=1, METH_OPTIONS, METH_GET, METH_HEAD, METH_POST, METH_PUT, + METH_DELETE, METH_TRACE, METH_CONNECT, METH_PROPFIND, METH_PROPPATCH, METH_MKCOL, METH_COPY, METH_MOVE, METH_LOCK, METH_UNLOCK, METH_VERSION_CONTROL, METH_REPORT, METH_CHECKOUT, METH_CHECKIN, METH_UNCHECKOUT, METH_MKWORKSPACE, METH_UPDATE, METH_LABEL, METH_MERGE, METH_BASELINE_CONTROL, METH_MKACTIVITY, METH_ORDERPATCH, METH_ACL, METH_PATCH, METH_SEARCH, METH_BCOPY, METH_BDELETE, METH_BMOVE, METH_BPROPFIND, METH_BPROPPATCH, METH_NOTIFY, METH_POLL, METH_SUBSCRIBE, METH_UNSUBSCRIBE, METH_X_MS_ENUMATTS, METH_BIND, METH_LINK, METH_MKCALENDAR, METH_MKREDIRECTREF, METH_REBIND, METH_UNBIND, METH_UNLINK, METH_UPDATEREDIRECTREF } MethodId; +// URI formats +typedef enum { URI__NOTCOMPUTE=-4, URI__PROBLEMATIC=-2, URI__NOTPRESENT=-1, URI_ASTERISK = 2, URI_AUTHORITY, URI_ABSPATH, URI_ABSOLUTE } UriType; + +// URI schemes +typedef enum { SCH__NOTCOMPUTE=-4, SCH__INSUFMEMORY=-3, SCH__NOTPRESENT=-1, SCH_OTHER = 1, SCH_HTTP, SCH_HTTPS, SCH_FTP, SCH_GOPHER, SCH_FILE } SchemeId; + // Every header we have ever heard of typedef enum { HEAD__NOTCOMPUTE=-4, HEAD__INSUFMEMORY=-3, HEAD__PROBLEMATIC=-2, HEAD__NOTPRESENT=-1, HEAD__OTHER=1, HEAD_CACHE_CONTROL, HEAD_CONNECTION, HEAD_DATE, HEAD_PRAGMA, HEAD_TRAILER, HEAD_COOKIE, HEAD_SET_COOKIE, @@ -70,7 +76,7 @@ typedef enum { HEAD__NOTCOMPUTE=-4, HEAD__INSUFMEMORY=-3, HEAD__PROBLEMATIC=-2, // All the infractions we might find while parsing and analyzing a message typedef enum { INF_TRUNCATED=0x1, INF_HEADTOOLONG=0x2, /*INF_STARTTOOSHORT=0x4,*/ INF_BADREQLINE=0x8, INF_BADSTATLINE=0x10, INF_TOOMANYHEADERS=0x20, INF_BADHEADER=0x40, INF_BADSTATCODE=0x80, INF_UNKNOWNVERSION=0x100, INF_BADVERSION=0x200, INF_NOSCRATCH=0x400, INF_BADHEADERREPS=0x800, INF_BADHEADERDATA=0x1000, - INF_BROKENCHUNK=0x2000, INF_BADCHUNKSIZE=0x4000, INF_BADPHRASE= 0x8000 } Infraction; + INF_BROKENCHUNK=0x2000, INF_BADCHUNKSIZE=0x4000, INF_BADPHRASE=0x8000, INF_BADURI=0x10000, INF_BADPORT=0x20000 } Infraction; // Formats for output from a header normalization function typedef enum { NORM_NULL, NORM_FIELD, NORM_INT64, NORM_ENUM64, NORM_ENUM64LIST } NormFormat; @@ -81,11 +87,13 @@ typedef enum { TRANSCODE__OTHER=1, TRANSCODE_CHUNKED, TRANSCODE_IDENTITY, TRANSC } // end namespace NHttpEnums // Individual pieces of the message found during parsing -// Set length to -1 when field has no value -typedef struct { - const uint8_t *start = nullptr; - int32_t length = -1; -} field; +// Length values <= 0 are StatusCode values and imply that the start pointer is meaningless. +// Never use the start pointer without verifying that length > 0. +struct field { +public: + const uint8_t *start; + int32_t length; +}; typedef enum { diff --git a/src/service_inspectors/nhttp_inspect/nhttp_flow_data.cc b/src/service_inspectors/nhttp_inspect/nhttp_flow_data.cc index 162584bc4..01b0f5a0e 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_flow_data.cc +++ b/src/service_inspectors/nhttp_inspect/nhttp_flow_data.cc @@ -50,8 +50,9 @@ void NHttpFlowData::halfReset(SourceId sourceId) { chunkOctets[sourceId] = STAT_NOTPRESENT; versionId[sourceId] = VERS__NOTPRESENT; - if (sourceId == SRC_CLIENT) methodId = METH__NOTPRESENT; - else statusCodeNum = STAT_NOTPRESENT; + methodId[sourceId] = METH__NOTPRESENT; + schemeId[sourceId] = SCH__NOTPRESENT; + statusCodeNum[sourceId] = STAT_NOTPRESENT; } diff --git a/src/service_inspectors/nhttp_inspect/nhttp_flow_data.h b/src/service_inspectors/nhttp_inspect/nhttp_flow_data.h index 3c9b79acc..a11ad7713 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_flow_data.h +++ b/src/service_inspectors/nhttp_inspect/nhttp_flow_data.h @@ -75,16 +75,18 @@ private: int64_t octetsExpected[2] = { NHttpEnums::STAT_NOTPRESENT, NHttpEnums::STAT_NOTPRESENT }; // expected size of the upcoming body or chunk body section // Inspector's internal data about the current message + // Some items don't apply in both directions. Have two copies anyway just to simplify code and minimize hard-to-find bugs + NHttpEnums::VersionId versionId[2] = { NHttpEnums::VERS__NOTPRESENT, NHttpEnums::VERS__NOTPRESENT }; + NHttpEnums::MethodId methodId[2] = { NHttpEnums::METH__NOTPRESENT, NHttpEnums::METH__NOTPRESENT }; + NHttpEnums::SchemeId schemeId[2] = { NHttpEnums::SCH__NOTPRESENT, NHttpEnums::SCH__NOTPRESENT }; + int32_t statusCodeNum[2] = { NHttpEnums::STAT_NOTPRESENT, NHttpEnums::STAT_NOTPRESENT }; + int64_t dataLength[2] = { NHttpEnums::STAT_NOTPRESENT, NHttpEnums::STAT_NOTPRESENT }; // length of the data from Content-Length field or chunk header. int64_t bodySections[2] = { NHttpEnums::STAT_NOTPRESENT, NHttpEnums::STAT_NOTPRESENT }; // number of body sections seen so far including chunk headers int64_t bodyOctets[2] = { NHttpEnums::STAT_NOTPRESENT, NHttpEnums::STAT_NOTPRESENT }; // number of user data octets seen so far (either regular body or chunks) int64_t numChunks[2] = { NHttpEnums::STAT_NOTPRESENT, NHttpEnums::STAT_NOTPRESENT }; // number of chunks seen so far int64_t chunkSections[2] = { NHttpEnums::STAT_NOTPRESENT, NHttpEnums::STAT_NOTPRESENT }; // number of sections seen so far in the current chunk int64_t chunkOctets[2] = { NHttpEnums::STAT_NOTPRESENT, NHttpEnums::STAT_NOTPRESENT }; // number of user data octets seen so far in the current chunk including terminating CRLF - - NHttpEnums::VersionId versionId[2] = { NHttpEnums::VERS__NOTPRESENT, NHttpEnums::VERS__NOTPRESENT }; - NHttpEnums::MethodId methodId = NHttpEnums::METH__NOTPRESENT; - int32_t statusCodeNum = NHttpEnums::STAT_NOTPRESENT; }; #endif diff --git a/src/service_inspectors/nhttp_inspect/nhttp_msg_head_shared.cc b/src/service_inspectors/nhttp_inspect/nhttp_msg_head_shared.cc index 87bc568d9..77b846a6b 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_msg_head_shared.cc +++ b/src/service_inspectors/nhttp_inspect/nhttp_msg_head_shared.cc @@ -144,7 +144,7 @@ void NHttpMsgHeadShared::parseHeaderLines() { } void NHttpMsgHeadShared::deriveHeaderNameId(int index) { - if (headerName[index].length <= 0) return; + if (headerName[index].length <= 0) return; // Normalize header field name to lower case for matching purposes uint8_t *lowerName; if ((lowerName = scratchPad.request(headerName[index].length)) == nullptr) { @@ -152,8 +152,8 @@ void NHttpMsgHeadShared::deriveHeaderNameId(int index) { headerNameId[index] = HEAD__INSUFMEMORY; return; } - int32_t lowerLength = norm2Lower(headerName[index].start, headerName[index].length, lowerName, infractions, nullptr); - headerNameId[index] = (HeaderId) strToCode(lowerName, lowerLength, headerList); + norm2Lower(headerName[index].start, headerName[index].length, lowerName, infractions, nullptr); + headerNameId[index] = (HeaderId) strToCode(lowerName, headerName[index].length, headerList); } void NHttpMsgHeadShared::genEvents() { diff --git a/src/service_inspectors/nhttp_inspect/nhttp_msg_request.cc b/src/service_inspectors/nhttp_inspect/nhttp_msg_request.cc index 6527565c6..c55d3b040 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_msg_request.cc +++ b/src/service_inspectors/nhttp_inspect/nhttp_msg_request.cc @@ -34,6 +34,7 @@ #include "snort.h" #include "nhttp_enum.h" +#include "nhttp_head_norm.h" #include "nhttp_msg_request.h" using namespace NHttpEnums; @@ -43,12 +44,31 @@ void NHttpMsgRequest::initSection() { NHttpMsgStart::initSection(); method.length = STAT_NOTCOMPUTE; uri.length = STAT_NOTCOMPUTE; + uriLegacyNorm.length = STAT_NOTCOMPUTE; + uriType = URI__NOTCOMPUTE; + scheme.length = STAT_NOTCOMPUTE; + schemeId = SCH__NOTCOMPUTE; + host.length = STAT_NOTCOMPUTE; + hostNorm.length = STAT_NOTCOMPUTE; + port.length = STAT_NOTCOMPUTE; + portValue = STAT_NOTCOMPUTE; + path.length = STAT_NOTCOMPUTE; + pathNorm.length = STAT_NOTCOMPUTE; + query.length = STAT_NOTCOMPUTE; + queryNorm.length = STAT_NOTCOMPUTE; + fragment.length = STAT_NOTCOMPUTE; + fragmentNorm.length = STAT_NOTCOMPUTE; } // All the processing that is done for every message (i.e. not just-in-time) is done here. void NHttpMsgRequest::analyze() { NHttpMsgStart::analyze(); deriveMethodId(); + parseUri(); + deriveSchemeId(); + parseAuthority(); + derivePortValue(); + parseAbsPath(); } void NHttpMsgRequest::parseStartLine() { @@ -84,6 +104,128 @@ void NHttpMsgRequest::deriveMethodId() { methodId = (MethodId) strToCode(method.start, method.length, methodList); } +void NHttpMsgRequest::parseUri() { + if (uriType != URI__NOTCOMPUTE) return; + if (uri.length <= 0) { + uriType = URI__NOTPRESENT; + return; + } + + // Four basic types of HTTP URI + // "*" means request does not apply to any specific resource + if ((uri.length == 1) && (uri.start[0] == '*')) { + uriType = URI_ASTERISK; + scheme.length = STAT_NOTPRESENT; + authority.length = STAT_NOTPRESENT; + absPath.length = STAT_NOTPRESENT; + } + // CONNECT method uses an authority + else if (methodId == METH_CONNECT) { + uriType = URI_AUTHORITY; + scheme.length = STAT_NOTPRESENT; + authority.length = uri.length; + authority.start = uri.start; + absPath.length = STAT_NOTPRESENT; + } + // Absolute path is a path but no scheme or authority + else if (uri.start[0] == '/') { + uriType = URI_ABSPATH; + scheme.length = STAT_NOTPRESENT; + authority.length = STAT_NOTPRESENT; + absPath.length = uri.length; + absPath.start = uri.start; + } + // Absolute URI includes scheme, authority, and path + else { + // Find the "://" and then the "/" + int j; + int k; + for (j = 0; (uri.start[j] != ':') && (j < uri.length); j++); + for (k = j+3; (uri.start[k] != '/') && (k < uri.length); k++); + if ((k < uri.length) && (uri.start[j+1] == '/') && (uri.start[j+2] == '/')) { + uriType = URI_ABSOLUTE; + scheme.length = j; + scheme.start = uri.start; + authority.length = k - j - 3; + authority.start = uri.start + j + 3; + absPath.length = uri.length - k; + absPath.start = uri.start + k; + } + else { + infractions |= INF_BADURI; + uriType = URI__PROBLEMATIC; + scheme.length = STAT_PROBLEMATIC; + authority.length = STAT_PROBLEMATIC; + absPath.length = STAT_PROBLEMATIC; + } + } +} + +void NHttpMsgRequest::deriveSchemeId() { + if (schemeId != SCH__NOTCOMPUTE) return; + if (scheme.length <= 0) return; + + // Normalize scheme name to lower case for matching purposes + uint8_t *lowerScheme; + if ((lowerScheme = scratchPad.request(scheme.length)) == nullptr) { + infractions |= INF_NOSCRATCH; + schemeId = SCH__INSUFMEMORY; + return; + } + norm2Lower(scheme.start, scheme.length, lowerScheme, infractions, nullptr); + schemeId = (SchemeId) strToCode(lowerScheme, scheme.length, schemeList); +} + +void NHttpMsgRequest::parseAuthority() { + if (host.length != STAT_NOTCOMPUTE) return; + if (authority.length <= 0) return; + host.start = authority.start; + for (host.length = 0; (authority.start[host.length] != ':') && (host.length < authority.length); host.length++); + if (host.length < authority.length) { + port.length = authority.length - host.length - 1; + port.start = authority.start + host.length + 1; + } + else port.length = STAT_NOTPRESENT; +} + +void NHttpMsgRequest::derivePortValue() { + if (portValue != SCH__NOTCOMPUTE) return; + if (port.length <= 0) return; + portValue = 0; + for (int k = 0; k < port.length; k++) { + portValue = portValue * 10 + (port.start[k] - '0'); + if ((port.start[k] < '0') || (port.start[k] > '9') || (portValue > 65535)) + { + infractions |= INF_BADURI; + portValue = STAT_PROBLEMATIC; + break; + } + } +} + +void NHttpMsgRequest::parseAbsPath() { + if (path.length != STAT_NOTCOMPUTE) return; + if (absPath.length <= 0) return; + path.start = absPath.start; + for (path.length = 0; (absPath.start[path.length] != '?') && (absPath.start[path.length] != '#') && (path.length < absPath.length); path.length++); + if (path.length == absPath.length) { + query.length = STAT_NOTPRESENT; + fragment.length = STAT_NOTPRESENT; + return; + } + if (absPath.start[path.length] == '?') { + query.start = absPath.start + path.length + 1; + for (query.length = 0; (query.start[query.length] != '#') && (query.length < absPath.length - path.length - 1); query.length++); + fragment.start = query.start + query.length + 1; + fragment.length = absPath.length - path.length - 1 - query.length - 1; + } + else { + query.length = STAT_NOTPRESENT; + fragment.start = absPath.start + path.length + 1; + fragment.length = absPath.length - path.length - 1; + } +} + void NHttpMsgRequest::genEvents() { if (infractions != 0) SnortEventqAdd(NHTTP_GID, EVENT_ASCII); // I'm just an example event } @@ -93,6 +235,21 @@ void NHttpMsgRequest::printSection(FILE *output) const { if (versionId != VERS__NOTCOMPUTE) fprintf(output, "Version Id: %d\n", versionId); if (methodId != METH__NOTCOMPUTE) fprintf(output, "Method Id: %d\n", methodId); printInterval(output, "URI", uri.start, uri.length); + if (uriType != URI__NOTCOMPUTE) fprintf(output, "URI Type: %d\n", uriType); + printInterval(output, "Scheme", scheme.start, scheme.length); + if (schemeId != SCH__NOTCOMPUTE) fprintf(output, "Scheme Id: %d\n", schemeId); + printInterval(output, "Authority", authority.start, authority.length); + printInterval(output, "Host Name", host.start, host.length); + printInterval(output, "Normalized Host Name", hostNorm.start, hostNorm.length); + printInterval(output, "Port", port.start, port.length); + if (portValue != STAT_NOTCOMPUTE) fprintf(output, "Port Value: %d\n", portValue); + printInterval(output, "Absolute Path", absPath.start, absPath.length); + printInterval(output, "Path", path.start, path.length); + printInterval(output, "Normalized Path", pathNorm.start, pathNorm.length); + printInterval(output, "Query", query.start, query.length); + printInterval(output, "Normalized Query", queryNorm.start, queryNorm.length); + printInterval(output, "Fragment", fragment.start, fragment.length); + printInterval(output, "Normalized Fragment", fragmentNorm.start, fragmentNorm.length); NHttpMsgSection::printMessageWrapup(output); } @@ -111,7 +268,8 @@ void NHttpMsgRequest::updateFlow() const { else { sessionData->typeExpected[sourceId] = SEC_HEADER; sessionData->versionId[sourceId] = versionId; - sessionData->methodId = methodId; + sessionData->methodId[sourceId] = methodId; + sessionData->schemeId[sourceId] = schemeId; } } @@ -119,7 +277,7 @@ void NHttpMsgRequest::updateFlow() const { void NHttpMsgRequest::legacyClients() const { if (method.length > 0) SetHttpBuffer(HTTP_BUFFER_METHOD, method.start, (unsigned)method.length); if (uri.length > 0) SetHttpBuffer(HTTP_BUFFER_RAW_URI, uri.start, (unsigned)uri.length); - if (uri.length > 0) SetHttpBuffer(HTTP_BUFFER_URI, uri.start, (unsigned)uri.length); + if (uriLegacyNorm.length > 0) SetHttpBuffer(HTTP_BUFFER_URI, uriLegacyNorm.start, (unsigned)uriLegacyNorm.length); } diff --git a/src/service_inspectors/nhttp_inspect/nhttp_msg_request.h b/src/service_inspectors/nhttp_inspect/nhttp_msg_request.h index 1e416ccca..063764998 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_msg_request.h +++ b/src/service_inspectors/nhttp_inspect/nhttp_msg_request.h @@ -49,17 +49,40 @@ public: private: // Code conversion tables are for turning token strings into enums. static const StrCode methodList[]; + static const StrCode schemeList[]; // "Parse" methods cut things into pieces. "Derive" methods convert things into a new format such as an integer or enum token. "Normalize" methods convert // things into a standard form without changing the underlying format. void parseStartLine(); void deriveMethodId(); + void parseUri(); + void deriveSchemeId(); + void parseAuthority(); + void derivePortValue(); + void parseAbsPath(); // This is where all the derived values, extracted message parts, and normalized values are. - // Note that this is all scalars, buffer pointers, and buffer sizes. The actual buffers are in the message buffer (raw pieces) or the + // Note that these are all scalars, buffer pointers, and buffer sizes. The actual buffers are in the message buffer (raw pieces) or the // scratchPad (normalized pieces). field method; + + // URI stuff field uri; + field uriLegacyNorm; + NHttpEnums::UriType uriType; + field scheme; + field authority; + field host; + field hostNorm; + field port; + int32_t portValue; + field absPath; + field path; + field pathNorm; + field query; + field queryNorm; + field fragment; + field fragmentNorm; }; #endif diff --git a/src/service_inspectors/nhttp_inspect/nhttp_msg_section.cc b/src/service_inspectors/nhttp_inspect/nhttp_msg_section.cc index 2b2f0b56d..6945c0df6 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_msg_section.cc +++ b/src/service_inspectors/nhttp_inspect/nhttp_msg_section.cc @@ -59,8 +59,9 @@ void NHttpMsgSection::loadSection(const uint8_t *buffer, const uint16_t bufsize, sourceId = sessionData->sourceId; tcpClose = sessionData->tcpClose; versionId = sessionData->versionId[sourceId]; - methodId = sessionData->methodId; - statusCodeNum = sessionData->statusCodeNum; + methodId = sessionData->methodId[sourceId]; + schemeId = sessionData->schemeId[sourceId]; + statusCodeNum = sessionData->statusCodeNum[sourceId]; scratchPad.reinit(); } diff --git a/src/service_inspectors/nhttp_inspect/nhttp_msg_section.h b/src/service_inspectors/nhttp_inspect/nhttp_msg_section.h index d487e6c6d..2e44e2f6f 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_msg_section.h +++ b/src/service_inspectors/nhttp_inspect/nhttp_msg_section.h @@ -77,6 +77,7 @@ protected: NHttpEnums::SourceId sourceId; NHttpEnums::VersionId versionId; NHttpEnums::MethodId methodId; + NHttpEnums::SchemeId schemeId; int32_t statusCodeNum; }; diff --git a/src/service_inspectors/nhttp_inspect/nhttp_msg_status.cc b/src/service_inspectors/nhttp_inspect/nhttp_msg_status.cc index f4b0ac4ee..4e4ff9582 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_msg_status.cc +++ b/src/service_inspectors/nhttp_inspect/nhttp_msg_status.cc @@ -118,7 +118,7 @@ void NHttpMsgStatus::updateFlow() const { else { sessionData->typeExpected[sourceId] = SEC_HEADER; sessionData->versionId[sourceId] = versionId; - sessionData->statusCodeNum = statusCodeNum; + sessionData->statusCodeNum[sourceId] = statusCodeNum; } } diff --git a/src/service_inspectors/nhttp_inspect/nhttp_tables.cc b/src/service_inspectors/nhttp_inspect/nhttp_tables.cc index 8607c98fa..84014c259 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_tables.cc +++ b/src/service_inspectors/nhttp_inspect/nhttp_tables.cc @@ -45,7 +45,8 @@ using namespace NHttpEnums; const StrCode NHttpMsgRequest::methodList[] = - {{ METH_GET, "GET"}, + {{ METH_OPTIONS, "OPTIONS"}, + { METH_GET, "GET"}, { METH_HEAD, "HEAD"}, { METH_POST, "POST"}, { METH_PUT, "PUT"}, @@ -94,6 +95,14 @@ const StrCode NHttpMsgRequest::methodList[] = { METH_UPDATEREDIRECTREF, "UPDATEREDIRECTREF"}, { 0, nullptr} }; +const StrCode NHttpMsgRequest::schemeList[] = + {{ SCH_HTTP, "http"}, + { SCH_HTTPS, "https"}, + { SCH_FTP, "ftp"}, + { SCH_GOPHER, "gopher"}, + { SCH_FILE, "file"}, + { 0, nullptr} }; + const StrCode NHttpMsgHeadShared::headerList[] = {{ HEAD_CACHE_CONTROL, "cache-control"}, { HEAD_CONNECTION, "connection"}, diff --git a/src/service_inspectors/nhttp_inspect/nhttp_test_msgs.txt b/src/service_inspectors/nhttp_inspect/nhttp_test_msgs.txt index cbf066a35..df1e9da3f 100644 --- a/src/service_inspectors/nhttp_inspect/nhttp_test_msgs.txt +++ b/src/service_inspectors/nhttp_inspect/nhttp_test_msgs.txt @@ -251,14 +251,97 @@ MKREDIRECTREF / HTTP/2.0\r\n\r\n @3002 @break @request -BIND 1234567890?abcdef HTTP/1.1\r\n\r\n +BIND /1234567890?abcdef HTTP/1.1\r\n\r\n @3003 @break @request GET /test/hi-there.txt HTTP/1.0\r\n\r\n +@3004 +@break +@request +GET /URI/Absolute/Path/Example HTTP/1.1\r\n\r\n +@3005 +@break +@request +GET /uri/aBSOLUTE/pATH/eXAMPLE?with-query HTTP/1.1\r\n\r\n + +@3006 +@break +@request +MKWORKSPACE /URI/Absolute/Path/Example#with-fragment HTTP/1.1\r\n\r\n + +@3007 +@break +@request +BPROPFIND /URI/Absolute/Path/Example?with_QUERY#AndAFragmentToo HTTP/1.1\r\n\r\n + +@3008 +@break +@request +GET /?with-query HTTP/1.1\r\n\r\n + +@3009 +@break +@request +ORDERPATCH /#with-fragment HTTP/1.1\r\n\r\n + +@3010 +@break +@request +UPDATEREDIRECTREF /?with_QUERY#AndAFragmentToo HTTP/1.1\r\n\r\n + +@3011 +@break +@request +VERYLONGUNKNOWNMETHODTEST /?# HTTP/1.1\r\n\r\n + +@3012 +@break +@request +LABEL /stuff?# HTTP/1.1\r\n\r\n + +@3013 +@break +@request +MKCALENDAR /*stufflotsandlotslotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsofstuff?1# HTTP/1.1\r\n\r\n + +@3014 +@break +@request +VERSION-CONTROL /*stufflotsandlotslotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsandlotsofstuff?#A HTTP/1.1\r\n\r\n + +@3015 +@break +@request +OPTIONS * HTTP/1.1\r\n\r\n + +@3016 +@break +@request +OPTIONS /*options/may/have?a*resource HTTP/1.1\r\n\r\n + +@3017 +@break +@request +CONNECT this.is.an.authority.com HTTP/1.1\r\n\r\n + +@3018 +@break +@request +CONNECT this.is.an.authority.with.a.port.com:8739 HTTP/1.1\r\n\r\n + +@3019 +@break +@request +GET http://iamahost.com/simple/example/of/a/path/ HTTP/1.1\r\n\r\n + +@3020 +@break +@request +GET HtTpS://1.2.3.4.5.a:6/abcdef/ghijklmnop/qrstuvwxyz/?thequery?fieldcontinues?until#afragme#arrives#1234 HTTP/1.1\r\n\r\n # *********************************************************************************************** # Invalid request start lines