SNode.C
Loading...
Searching...
No Matches
web::http::Parser Class Referenceabstract

#include <Parser.h>

Inheritance diagram for web::http::Parser:
Collaboration diagram for web::http::Parser:

Public Member Functions

 Parser (core::socket::stream::SocketContext *socketContext, const enum HTTPCompliance &compliance=HTTPCompliance::RFC2616|HTTPCompliance::RFC7230)
virtual ~Parser ()
std::size_t parse ()
void reset ()

Protected Types

enum struct  HTTPCompliance : unsigned short {
  RFC1945 = 0x01 << 0 , RFC2616 = 0x01 << 1 , RFC7230 = 0x01 << 2 , RFC7231 = 0x01 << 3 ,
  RFC7232 = 0x01 << 4 , RFC7233 = 0x01 << 5 , RFC7234 = 0x01 << 6 , RFC7235 = 0x01 << 7 ,
  RFC7540 = 0x01 << 8 , RFC7541 = 0x01 << 9
}
enum struct  ParserState {
  BEGIN , FIRSTLINE , HEADER , BODY ,
  TRAILER , ERROR
}

Protected Member Functions

virtual void analyzeHeader ()

Protected Attributes

enum web::http::Parser::HTTPCompliance hTTPCompliance
ParserState parserState = ParserState::BEGIN
TransferEncoding transferEncoding = TransferEncoding::HTTP10
CiStringMap< std::string > headers
std::vector< char > content
int httpMajor = 0
int httpMinor = 0
std::list< web::http::ContentDecoder * > decoderQueue
core::socket::stream::SocketContextsocketContext = nullptr
std::string line
std::size_t contentLength = 0
std::size_t contentLengthRead = 0

Static Protected Attributes

static const std::regex httpVersionRegex

Private Member Functions

virtual void begin ()=0
virtual void parseStartLine (const std::string &line)=0
virtual void parseError (int code, const std::string &reason)=0
virtual void parsingFinished ()=0
std::size_t readStartLine ()
std::size_t readHeader ()
std::size_t readContent ()
std::size_t readTrailer ()

Private Attributes

web::http::decoder::Fields headerDecoder
std::set< std::string > trailerFieldsExpected
web::http::decoder::Fields trailerDecoder

Friends

enum HTTPCompliance operator| (const enum HTTPCompliance &c1, const enum HTTPCompliance &c2)
enum HTTPCompliance operator& (const enum HTTPCompliance &c1, const enum HTTPCompliance &c2)

Detailed Description

Definition at line 71 of file Parser.h.

Member Enumeration Documentation

◆ HTTPCompliance

enum struct web::http::Parser::HTTPCompliance : unsigned short
strongprotected
Enumerator
RFC1945 
RFC2616 
RFC7230 
RFC7231 
RFC7232 
RFC7233 
RFC7234 
RFC7235 
RFC7540 
RFC7541 

Definition at line 73 of file Parser.h.

73 : unsigned short {
74 RFC1945 = 0x01 << 0, // HTTP 1.0
75 RFC2616 = 0x01 << 1, // HTTP 1.1
76 RFC7230 = 0x01 << 2, // Message Syntax and Routing
77 RFC7231 = 0x01 << 3, // Semantics and Content
78 RFC7232 = 0x01 << 4, // Conditional Requests
79 RFC7233 = 0x01 << 5, // Range Requests
80 RFC7234 = 0x01 << 6, // Caching
81 RFC7235 = 0x01 << 7, // Authentication
82 RFC7540 = 0x01 << 8, // HTTP 2.0
83 RFC7541 = 0x01 << 9 // Header Compression
84 } hTTPCompliance;

◆ ParserState

enum struct web::http::Parser::ParserState
strongprotected
Enumerator
BEGIN 
FIRSTLINE 
HEADER 
BODY 
TRAILER 
ERROR 

Definition at line 98 of file Parser.h.

98{ BEGIN, FIRSTLINE, HEADER, BODY, TRAILER, ERROR };

Constructor & Destructor Documentation

◆ Parser()

web::http::Parser::Parser ( core::socket::stream::SocketContext * socketContext,
const enum HTTPCompliance & compliance = HTTPCompliance::RFC2616 | HTTPCompliance::RFC7230 )
explicit

Definition at line 97 of file Parser.cpp.

98 : hTTPCompliance(compliance)
102 }
enum web::http::Parser::HTTPCompliance hTTPCompliance
web::http::decoder::Fields headerDecoder
Definition Parser.h:130
core::socket::stream::SocketContext * socketContext
Definition Parser.h:127
web::http::decoder::Fields trailerDecoder
Definition Parser.h:133

References web::http::decoder::Fields::Fields(), headerDecoder, socketContext, and trailerDecoder.

Referenced by web::http::server::RequestParser::RequestParser(), and web::http::client::ResponseParser::ResponseParser().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ~Parser()

web::http::Parser::~Parser ( )
virtual

Definition at line 104 of file Parser.cpp.

104 {
105 reset();
106 }

References reset().

Here is the call graph for this function:

Member Function Documentation

◆ analyzeHeader()

void web::http::Parser::analyzeHeader ( )
protectedvirtual

Reimplemented in web::http::client::ResponseParser, and web::http::server::RequestParser.

Definition at line 194 of file Parser.cpp.

194 {
195 bool success = true;
196
197 // Determine message framing.
198 // RFC 9112 ยง6.3: Transfer-Encoding (chunked) overrides Content-Length.
199 const bool hasChunked = transferEncodingHasChunked(headers);
200
201 if (hasChunked) {
203 decoderQueue.emplace_back(new web::http::decoder::Chunked(socketContext));
204
205 if (headers.contains("Trailer")) {
206 std::string trailers = headers["Trailer"];
207
208 while (!trailers.empty()) {
209 std::string trailerField;
210 std::tie(trailerField, trailers) = httputils::str_split(trailers, ',');
211 httputils::str_trimm(trailerField);
212 trailerFieldsExpected.insert(trailerField);
213 trailerField.clear();
214 }
215 trailerDecoder.setFieldsExpected(trailerFieldsExpected);
216 }
217 } else if (headers.contains("Content-Length")) {
218 std::size_t length = 0;
219
220 if (!parseContentLengthStrict(headers["Content-Length"], length)) {
221 parseError(400, "Invalid Content-Length");
222 success = false;
223 } else {
224 contentLength = length;
225 decoderQueue.emplace_back(new web::http::decoder::Identity(socketContext, contentLength));
226 }
227 }
228
229 if (success) {
230 // Transfer-Encoding (other than chunked) is currently not implemented, but we keep the
231 // existing behavior of not altering the decoder queue here.
232 if (headers.contains("Transfer-Encoding")) {
233 const std::string& encoding = headers["Transfer-Encoding"];
234 if (web::http::ciContains(encoding, "compressed")) {
235 // decoderQueue.emplace_back(new web::http::decoder::Compress(socketContext));
236 }
237 if (web::http::ciContains(encoding, "deflate")) {
238 // decoderQueue.emplace_back(new web::http::decoder::Deflate(socketContext));
239 }
240 if (web::http::ciContains(encoding, "gzip")) {
241 // decoderQueue.emplace_back(new web::http::decoder::GZip(socketContext));
242 }
243 }
244
245 if (decoderQueue.empty()) {
246 decoderQueue.emplace_back(new web::http::decoder::HTTP10Response(socketContext));
247 }
248
249 if (headers.contains("Content-Encoding")) {
250 const std::string& encoding = headers["Content-Encoding"];
251
252 if (web::http::ciContains(encoding, "compressed")) {
253 // decoderQueue.emplace_back(new web::http::decoder::Compress(socketContext));
254 }
255 if (web::http::ciContains(encoding, "deflate")) {
256 // decoderQueue.emplace_back(new web::http::decoder::Deflate(socketContext));
257 }
258 if (web::http::ciContains(encoding, "gzip")) {
259 // decoderQueue.emplace_back(new web::http::decoder::GZip(socketContext));
260 }
261 if (web::http::ciContains(encoding, "br")) {
262 // decoderQueue.emplace_back(new web::http::decoder::Br(socketContext));
263 }
264 }
265 }
266 }
virtual void parseError(int code, const std::string &reason)=0
std::size_t contentLength
Definition Parser.h:143
CiStringMap< std::string > headers
Definition Parser.h:119
std::list< web::http::ContentDecoder * > decoderQueue
Definition Parser.h:125
TransferEncoding transferEncoding
Definition Parser.h:102
std::set< std::string > trailerFieldsExpected
Definition Parser.h:132
std::pair< std::string, std::string > str_split(const std::string &base, char c_middle)
std::string & str_trimm(std::string &text)
bool ciContains(const std::string &str1, const std::string &str2)
static bool transferEncodingHasChunked(CiStringMap< std::string > &headers)
Definition Parser.cpp:83
static bool parseContentLengthStrict(const std::string &s, std::size_t &out)
Definition Parser.cpp:63

References web::http::decoder::Chunked::Chunked(), web::http::Chunked, web::http::ciContains(), contentLength, decoderQueue, headers, web::http::decoder::HTTP10Response::HTTP10Response(), web::http::decoder::Identity::Identity(), web::http::parseContentLengthStrict(), parseError(), web::http::decoder::Fields::setFieldsExpected(), socketContext, httputils::str_split(), httputils::str_trimm(), trailerDecoder, trailerFieldsExpected, transferEncoding, and web::http::transferEncodingHasChunked().

Referenced by web::http::client::ResponseParser::analyzeHeader(), web::http::server::RequestParser::analyzeHeader(), and readHeader().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ begin()

virtual void web::http::Parser::begin ( )
privatepure virtual

Implemented in web::http::client::ResponseParser, and web::http::server::RequestParser.

Referenced by parse().

Here is the caller graph for this function:

◆ parse()

std::size_t web::http::Parser::parse ( )

Definition at line 126 of file Parser.cpp.

126 {
127 std::size_t ret = 0;
128 std::size_t consumed = 0;
129
130 do {
131 switch (parserState) {
133 begin();
135 [[fallthrough]];
137 ret = readStartLine();
138 break;
140 ret = readHeader();
141 break;
143 ret = readContent();
144 break;
146 ret = readTrailer();
147 break;
149 break;
150 }
151 consumed += ret;
152 } while (ret > 0 && parserState != ParserState::BEGIN && parserState != ParserState::ERROR);
153
154 return consumed;
155 }
ParserState parserState
Definition Parser.h:100
std::size_t readContent()
Definition Parser.cpp:268
virtual void begin()=0
std::size_t readTrailer()
Definition Parser.cpp:291
std::size_t readStartLine()
Definition Parser.cpp:157
std::size_t readHeader()
Definition Parser.cpp:181

References BEGIN, begin(), BODY, ERROR, FIRSTLINE, HEADER, parserState, readContent(), readHeader(), readStartLine(), readTrailer(), and TRAILER.

Referenced by apps::http::SimpleSocketProtocol::onReceivedFromPeer(), web::http::client::SocketContext::onReceivedFromPeer(), and web::http::server::SocketContext::onReceivedFromPeer().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parseError()

virtual void web::http::Parser::parseError ( int code,
const std::string & reason )
privatepure virtual

Implemented in web::http::client::ResponseParser, and web::http::server::RequestParser.

Referenced by analyzeHeader(), readContent(), readHeader(), and readTrailer().

Here is the caller graph for this function:

◆ parseStartLine()

virtual void web::http::Parser::parseStartLine ( const std::string & line)
privatepure virtual

Implemented in web::http::client::ResponseParser, and web::http::server::RequestParser.

Referenced by readStartLine().

Here is the caller graph for this function:

◆ parsingFinished()

virtual void web::http::Parser::parsingFinished ( )
privatepure virtual

Implemented in web::http::client::ResponseParser, and web::http::server::RequestParser.

Referenced by readContent(), and readTrailer().

Here is the caller graph for this function:

◆ readContent()

std::size_t web::http::Parser::readContent ( )
private

Definition at line 268 of file Parser.cpp.

268 {
269 ContentDecoder* contentDecoder = decoderQueue.front();
270
271 const std::size_t consumed = contentDecoder->read();
272
273 if (contentDecoder->isComplete()) {
274 contentDecoder = decoderQueue.back();
275
276 std::vector<char> chunk = contentDecoder->getContent();
277 content.insert(content.end(), chunk.begin(), chunk.end());
278
279 if (transferEncoding == TransferEncoding::Chunked && headers.contains("Trailer")) {
281 } else {
283 }
284 } else if (contentDecoder->isError()) {
285 parseError(501, "Wrong content encoding");
286 }
287
288 return consumed;
289 }
virtual void parsingFinished()=0
std::vector< char > content
Definition Parser.h:120

References web::http::Chunked, content, decoderQueue, web::http::ContentDecoder::getContent(), headers, web::http::ContentDecoder::isComplete(), web::http::ContentDecoder::isError(), parseError(), parserState, parsingFinished(), web::http::ContentDecoder::read(), TRAILER, and transferEncoding.

Referenced by parse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readHeader()

std::size_t web::http::Parser::readHeader ( )
private

Definition at line 181 of file Parser.cpp.

181 {
182 const std::size_t consumed = headerDecoder.read();
183
184 if (headerDecoder.isError()) {
185 parseError(headerDecoder.getErrorCode(), headerDecoder.getErrorReason());
186 } else if (headerDecoder.isComplete()) {
187 headers = std::move(headerDecoder.getHeader());
189 }
190
191 return consumed;
192 }
virtual void analyzeHeader()
Definition Parser.cpp:194

References analyzeHeader(), web::http::decoder::Fields::getErrorCode(), web::http::decoder::Fields::getErrorReason(), web::http::decoder::Fields::getHeader(), headerDecoder, headers, web::http::decoder::Fields::isComplete(), web::http::decoder::Fields::isError(), parseError(), and web::http::decoder::Fields::read().

Referenced by parse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readStartLine()

std::size_t web::http::Parser::readStartLine ( )
private

Definition at line 157 of file Parser.cpp.

157 {
158 std::size_t consumed = 0;
159 std::size_t ret = 0;
160
161 do {
162 char ch = 0;
163 ret = socketContext->readFromPeer(&ch, 1);
164
165 if (ret > 0) {
166 consumed += ret;
167 if (ch == '\r' || ch == '\n') {
168 if (ch == '\n') {
170 line.clear();
171 }
172 } else {
173 line += ch;
174 }
175 }
176 } while (ret > 0 && parserState == ParserState::FIRSTLINE);
177
178 return consumed;
179 }
virtual void parseStartLine(const std::string &line)=0
std::string line
Definition Parser.h:142

References FIRSTLINE, line, parserState, parseStartLine(), core::socket::stream::SocketContext::readFromPeer(), and socketContext.

Referenced by parse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ readTrailer()

std::size_t web::http::Parser::readTrailer ( )
private

Definition at line 291 of file Parser.cpp.

291 {
292 const std::size_t consumed = trailerDecoder.read();
293
294 if (trailerDecoder.isError()) {
295 parseError(trailerDecoder.getErrorCode(), trailerDecoder.getErrorReason());
296 } else if (trailerDecoder.isComplete()) {
297 web::http::CiStringMap<std::string>&& trailer = trailerDecoder.getHeader();
298 headers.insert(trailer.begin(), trailer.end());
300 }
301
302 return consumed;
303 }

References web::http::decoder::Fields::getErrorCode(), web::http::decoder::Fields::getErrorReason(), web::http::decoder::Fields::getHeader(), headers, web::http::decoder::Fields::isComplete(), web::http::decoder::Fields::isError(), parseError(), parsingFinished(), web::http::decoder::Fields::read(), and trailerDecoder.

Referenced by parse().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ reset()

void web::http::Parser::reset ( )

Definition at line 108 of file Parser.cpp.

108 {
110 headers.clear();
111 content.clear();
112 httpMinor = 0;
113 httpMajor = 0;
114 line.clear();
115 contentLength = 0;
117
118 for (const ContentDecoder* contentDecoder : decoderQueue) {
119 delete contentDecoder;
120 }
121 decoderQueue.clear();
122
123 trailerFieldsExpected.clear();
124 }
std::size_t contentLengthRead
Definition Parser.h:144

References BEGIN, content, contentLength, contentLengthRead, decoderQueue, headers, httpMajor, httpMinor, line, parserState, and trailerFieldsExpected.

Referenced by web::http::client::ResponseParser::parseError(), web::http::server::RequestParser::parseError(), web::http::client::ResponseParser::parsingFinished(), web::http::server::RequestParser::parsingFinished(), and ~Parser().

Here is the caller graph for this function:

◆ operator&

enum HTTPCompliance operator& ( const enum HTTPCompliance & c1,
const enum HTTPCompliance & c2 )
friend

Definition at line 309 of file Parser.cpp.

309 {
310 return static_cast<enum Parser::HTTPCompliance>(static_cast<unsigned short>(c1) & static_cast<unsigned short>(c2));
311 }

◆ operator|

enum HTTPCompliance operator| ( const enum HTTPCompliance & c1,
const enum HTTPCompliance & c2 )
friend

Definition at line 305 of file Parser.cpp.

305 {
306 return static_cast<enum Parser::HTTPCompliance>(static_cast<unsigned short>(c1) | static_cast<unsigned short>(c2));
307 }

Member Data Documentation

◆ content

std::vector<char> web::http::Parser::content
protected

◆ contentLength

std::size_t web::http::Parser::contentLength = 0
protected

◆ contentLengthRead

std::size_t web::http::Parser::contentLengthRead = 0
protected

Definition at line 144 of file Parser.h.

Referenced by reset().

◆ decoderQueue

std::list<web::http::ContentDecoder*> web::http::Parser::decoderQueue
protected

Definition at line 125 of file Parser.h.

Referenced by analyzeHeader(), readContent(), and reset().

◆ headerDecoder

web::http::decoder::Fields web::http::Parser::headerDecoder
private

Definition at line 130 of file Parser.h.

Referenced by Parser(), and readHeader().

◆ headers

◆ hTTPCompliance

enum web::http::Parser::HTTPCompliance web::http::Parser::hTTPCompliance
protected

◆ httpMajor

◆ httpMinor

◆ httpVersionRegex

const std::regex web::http::Parser::httpVersionRegex
staticprotected

◆ line

std::string web::http::Parser::line
protected

Definition at line 142 of file Parser.h.

Referenced by readStartLine(), and reset().

◆ parserState

◆ socketContext

core::socket::stream::SocketContext* web::http::Parser::socketContext = nullptr
protected

Definition at line 127 of file Parser.h.

Referenced by analyzeHeader(), Parser(), and readStartLine().

◆ trailerDecoder

web::http::decoder::Fields web::http::Parser::trailerDecoder
private

Definition at line 133 of file Parser.h.

Referenced by analyzeHeader(), Parser(), and readTrailer().

◆ trailerFieldsExpected

std::set<std::string> web::http::Parser::trailerFieldsExpected
private

Definition at line 132 of file Parser.h.

Referenced by analyzeHeader(), and reset().

◆ transferEncoding


The documentation for this class was generated from the following files: