@@ -6,8 +6,10 @@ using namespace std;
66HTTPParser::HTTPParser (ClientFD_t ClientFD) :
77 Client(ClientFD),
88 _RequestCount(0 ),
9- _HTTPRequest(" " ),
10- _RegexContentLength(regex(" .*Content-Length: ([0-9]+).*" , regex::extended))
9+ _RequestCountGet(0 ),
10+ _RequestCountPost(0 ),
11+ _RequestCountPostAS(0 ),
12+ _HTTPRequest(" " )
1113{
1214 DBG (120 , " Constructor" );
1315}
@@ -19,127 +21,100 @@ HTTPParser::~HTTPParser()
1921
2022void HTTPParser::appendBuffer (const char * BufferRef, const uint16_t BufferSize)
2123{
22- _HTTPRequest = _HTTPRequest + std:: string (&BufferRef[0 ], BufferSize);
24+ _HTTPRequest = _HTTPRequest + string (&BufferRef[0 ], BufferSize);
2325 DBG (250 , " Buffer:'" << _HTTPRequest << " '" );
2426 _splitRequests ();
2527}
2628
2729void HTTPParser::_splitRequests ()
2830{
29- DBG (200 , " splitRequests Buffer:'" << _HTTPRequest << " '" );
31+ DBG (180 , " splitRequests Buffer:'" << _HTTPRequest << " '" );
3032
31- _SplittedRequests.clear ();
32-
33- size_t ContentLengthFoundPos = _HTTPRequest.find (" Content-Length" );
34- size_t EndMarkerFoundPos = _HTTPRequest.find (" \n\r " );
35-
36- cmatch RegexMatch;
37-
38- uint SplitPosition = 0 ;
33+ // -> reset incomplete request string
34+ string incompleteRequest (" " );
3935
40- while (
41- (ContentLengthFoundPos < EndMarkerFoundPos) ||
42- (ContentLengthFoundPos == string::npos && EndMarkerFoundPos != string::npos)
43- )
44- {
45- if (ContentLengthFoundPos < EndMarkerFoundPos) {
46- if (regex_match (_HTTPRequest.c_str (), RegexMatch, _RegexContentLength)) {
47- DBG (140 , " Content-Length header found." );
48- int ContentLength = stoi (RegexMatch[1 ]);
49- SplitPosition = EndMarkerFoundPos+ContentLength+3 ;
50- }
51- }
52- else if (ContentLengthFoundPos == string::npos && EndMarkerFoundPos != string::npos)
53- {
54- SplitPosition = EndMarkerFoundPos+3 ;
55- }
36+ // -> cut from last found \n\r (last valid request end marker) until string end
37+ size_t LastDelimiterPos = _HTTPRequest.rfind (" \n\r " );
5638
57- _SplittedRequests.push_back (
58- _HTTPRequest.substr (0 , SplitPosition)
59- );
39+ // -> if min 1 full valid request && rest without end marker
40+ if (LastDelimiterPos != string::npos && LastDelimiterPos != _HTTPRequest.length ()) {
6041
61- _HTTPRequest.erase (0 , SplitPosition);
42+ // -> put incomplete last request into tmp string
43+ incompleteRequest = _HTTPRequest.substr (LastDelimiterPos);
6244
63- ContentLengthFoundPos = _HTTPRequest. find ( " Content-Length " );
64- EndMarkerFoundPos = _HTTPRequest. find ( " \n\r " );
45+ // -> remove "\n\r"
46+ incompleteRequest. replace ( 0 , 2 , " " );
6547 }
6648
49+ // -> split requests into _SplittedRequests vector
50+ _SplittedRequests.clear ();
51+ String::split (_HTTPRequest, " \n\r " , _SplittedRequests);
6752 _RequestCount = _SplittedRequests.size ();
68- DBG (120 , " splitRequests after split Vector Element count:" << _RequestCount);
69- }
53+ DBG (120 , " splitRequests count after splitted into Vector:" << _RequestCount);
7054
71- void HTTPParser::parseRequestsComplete ()
72- {
73- for (auto &Request:_SplittedRequests) {
74- vector<std::string> RequestLines;
75- String::split (Request, " \n " , RequestLines);
76- }
55+ // -> "restore" incomplete last request buffer
56+ _HTTPRequest = incompleteRequest;
7757}
7858
79- uint HTTPParser::parseRequestsBasic (SharedMemAddress_t SHMGetRequests, const ASRequestHandlerRef_t ASRequestHandlerRef)
59+ uint HTTPParser::processRequests (SharedMemAddress_t SHMGetRequests, const ASRequestHandlerRef_t ASRequestHandlerRef)
8060{
8161 setBaseAddress (SHMGetRequests);
8262
83- uint16_t PythonRequestCount = 0 ;
84-
8563 for (auto &Request:_SplittedRequests) {
86- PythonRequestCount += _parseBaseProps (Request, ASRequestHandlerRef);
64+ _processRequestProperties (Request, ASRequestHandlerRef);
8765 }
8866
89- return _SplittedRequests. size () - PythonRequestCount ;
67+ return _RequestCountGet ;
9068}
9169
92- uint16_t HTTPParser::_parseBaseProps (string& Request, const ASRequestHandlerRef_t ASRequestHandlerRef)
70+ void HTTPParser::_processRequestProperties (string& Request, const ASRequestHandlerRef_t ASRequestHandlerRef)
9371{
9472 DBG (180 , " HTTP Request:'" << Request << " '" );
9573
96- // - find first line endline
97- size_t StartPos = Request.find (" \n " );
98-
99- // - set result vector
100- vector<std::string> BasePropsFound;
101-
102- // - reverse split
103- String::rsplit (Request, StartPos, " " , BasePropsFound);
74+ BasePropsResult_t BasePropsFound;
75+ this ->_parseRequestProperties (Request, BasePropsFound);
10476
10577 DBG (140 , " HTTP Version:" << BasePropsFound.at (0 ) << " File:" << BasePropsFound.at (1 ) << " Method:" << BasePropsFound.at (2 ));
10678 DBG (140 , " HTTP Payload (c_str):" << Request.c_str ());
10779
108- uint16_t HTTPMethod = (BasePropsFound.at (2 ).find (" POST" ) != string::npos) ? 2 : 1 ;
109- uint16_t HTTPVersion = (BasePropsFound.at (0 ).find (" HTTP/1.1" ) != string::npos) ? 1 : 2 ;
80+ // - check HTTP/1.2 (currently unimplemented)
81+ const size_t HTTPVersion1_2Found = BasePropsFound.at (0 ).find (" HTTP/1.2" );
82+
83+ // - if not HTTP/1.1, do not process further
84+ const size_t HTTPVersion1_1Found = BasePropsFound.at (0 ).find (" HTTP/1.1" );
85+
86+ const uint16_t HTTPMethod = (BasePropsFound.at (2 ).find (" POST" ) != string::npos) ? 2 : 1 ;
87+ const uint16_t HTTPVersion = (BasePropsFound.at (0 ).find (" HTTP/1.1" ) != string::npos) ? 1 : 2 ;
11088
111- size_t PythonReqFound = BasePropsFound.at (1 ).find (" /python/" );
89+ // - check if POST request is an AS request
90+ const size_t PythonReqFound = BasePropsFound.at (1 ).find (" /python/" );
11291
92+ // - get unique request nr
11393 uint16_t RequestNr = getNextReqNr ();
11494
115- DBG (140 , " HTTP RequestNr:" << RequestNr << " HTTPVersion:" << HTTPVersion);
95+ DBG (140 , " HTTP RequestNr:" << RequestNr << " HTTPVersion:" << HTTPVersion << " HTTPMethod: " << HTTPMethod );
11696
117- cmatch RegexMatch;
97+ if (HTTPMethod == 2 ) {
98+ ++this ->_RequestCountPost ;
99+ }
118100
119- if (PythonReqFound != BasePropsFound.at (1 ).npos ) {
101+ if (HTTPMethod == 2 && PythonReqFound != BasePropsFound.at (1 ).npos ) {
120102
121103 DBG (140 , " Python Request:" << Request);
122104
123- string Payload = " " ;
124-
125- size_t ContentLengthFoundPos = Request.find (" Content-Length" );
126- size_t EndMarkerFoundPos = Request.find (" \n\r " );
105+ ++this ->_RequestCountPostAS ;
127106
128- if (ContentLengthFoundPos != string::npos && EndMarkerFoundPos != string::npos) {
129- if (regex_match (Request.c_str (), RegexMatch, _RegexContentLength)) {
130- DBG (140 , " Content-Length header found." );
131- int ContentLength = stoi (RegexMatch[1 ]);
132- uint SubStrStart = EndMarkerFoundPos+3 ;
133- uint SubStrEnd = EndMarkerFoundPos+ContentLength+3 ;
134- Payload = Request.substr (SubStrStart, SubStrEnd);
135- }
136- }
107+ // -> cut first properties line from request
108+ size_t FirstLineEndMarker = Request.find (" \n " );
109+ Request.replace (0 , FirstLineEndMarker+1 , " " );
137110
138- // - get Host header
139- BasePropsResult_t BaseProps;
140111 RequestHeaderResult_t Headers;
141- this ->_parseBasePropsRV (Request, BaseProps);
142- this ->_parseHeadersRV (Request, Headers);
112+ this ->_parseRequestHeaders (Request, Headers);
113+
114+ auto ContentBytes = stoi (Headers.at (" Content-Length" ));
115+ string Payload = Request.substr (Request.length ()-ContentBytes, ContentBytes);
116+
117+ DBG (140 , " HTTP POST-AS payload:" << Payload);
143118
144119 // - add ASRequestHandler request
145120 ASRequestHandlerRef->addRequest ({
@@ -150,9 +125,12 @@ uint16_t HTTPParser::_parseBaseProps(string& Request, const ASRequestHandlerRef_
150125 RequestNr,
151126 Payload
152127 });
153- return 1 ;
154128 }
155- else {
129+
130+ if (HTTPMethod == 1 ) {
131+
132+ ++this ->_RequestCountGet ;
133+
156134 // - set values in get requests shared memory
157135 const char * MsgCString = Request.c_str ();
158136
@@ -173,32 +151,33 @@ uint16_t HTTPParser::_parseBaseProps(string& Request, const ASRequestHandlerRef_
173151
174152 void * NextSegmentAddr = getNextAddress (MsgLength);
175153 DBG (120 , " Set SharedMem ClientFD:" << ClientFDAddr << " PayloadLength:" << MsgLengthAddr << " Payload:" << MsgAddress << " NextSegment:" << NextSegmentAddr);
176- return 0 ;
177154 }
178155}
179156
180- void HTTPParser::_parseBasePropsRV (string& Request, BasePropsResultRef_t ResultRef)
157+ void HTTPParser::_parseRequestProperties (string& Request, BasePropsResultRef_t ResultRef)
181158{
182159 DBG (120 , " HTTP Request:'" << Request << " '" );
183160
184161 // - find first line endline
185162 size_t StartPos = Request.find (" \n " );
186163
164+ // -> if no headers (no \n), set start pos to end of string
165+ if (StartPos == string::npos) {
166+ StartPos = Request.length ();
167+ }
168+
187169 // - reverse split
188170 String::rsplit (Request, StartPos, " " , ResultRef);
189171
190- // - remove first line from Request
191- Request = Request.substr (StartPos+1 , Request.length ());
192-
193172 DBG (120 , " HTTP Version:" << ResultRef.at (0 ) << " File:" << ResultRef.at (1 ) << " Method:" << ResultRef.at (2 ) << " Request:" << Request);
194173}
195174
196- void HTTPParser::_parseHeadersRV (string& Request, RequestHeaderResultRef_t ResultRef)
175+ void HTTPParser::_parseRequestHeaders (string& Request, RequestHeaderResultRef_t ResultRef)
197176{
198177 DBG (120 , " HTTP Request:'" << Request << " '" );
199178
200179 // - reverse split header lines
201- vector<std:: string> Lines;
180+ vector<string> Lines;
202181 String::split (Request, " \n " , Lines);
203182
204183 // - loop over lines, split, put into result map
@@ -208,12 +187,12 @@ void HTTPParser::_parseHeadersRV(string& Request, RequestHeaderResultRef_t Resul
208187
209188 DBG (120 , " Line:'" << Line << " '" );
210189
211- vector<std:: string> HeaderPair;
190+ vector<string> HeaderPair;
212191 if (Line.find (' :' ) != string::npos) {
213192 String::rsplit (Line, Line.length (), " : " , HeaderPair);
214193
215- std:: string HeaderID = HeaderPair.at (1 );
216- std:: string HeaderValue = HeaderPair.at (0 ).substr (0 , HeaderPair.at (0 ).length ()- 1 );
194+ string HeaderID = HeaderPair.at (1 );
195+ string HeaderValue = HeaderPair.at (0 ).substr (0 , HeaderPair.at (0 ).length ());
217196
218197 DBG (120 , " HeaderID:'" << HeaderID << " '" );
219198 DBG (120 , " HeaderValue:'" << HeaderValue << " '" );
0 commit comments