42      context_(request_.context()) {
 
 
   64                std::bind(&HttpRequestParser::receiveStartHandler, 
this));
 
   67                std::bind(&HttpRequestParser::httpMethodHandler, 
this));
 
   70                std::bind(&HttpRequestParser::uriHandler, 
this));
 
   73                std::bind(&HttpRequestParser::versionHTTPHandler, 
this, 
'H',
 
   77                std::bind(&HttpRequestParser::versionHTTPHandler, 
this, 
'T',
 
   81                std::bind(&HttpRequestParser::versionHTTPHandler, 
this, 
'T',
 
   85                std::bind(&HttpRequestParser::versionHTTPHandler, 
this, 
'P',
 
   89                std::bind(&HttpRequestParser::versionHTTPHandler, 
this, 
'/',
 
   93                std::bind(&HttpRequestParser::versionNumberStartHandler, 
this,
 
   95                          &context_->http_version_major_));
 
   98                std::bind(&HttpRequestParser::versionNumberHandler, 
this,
 
  100                          &context_->http_version_major_));
 
  103                std::bind(&HttpRequestParser::versionNumberStartHandler, 
this,
 
  105                          &context_->http_version_minor_));
 
  108                std::bind(&HttpRequestParser::versionNumberHandler, 
this,
 
  110                          &context_->http_version_minor_));
 
  113                std::bind(&HttpRequestParser::expectingNewLineHandler, 
this,
 
  117                std::bind(&HttpRequestParser::headerLineStartHandler, 
this));
 
  120                std::bind(&HttpRequestParser::headerLwsHandler, 
this));
 
  123                std::bind(&HttpRequestParser::headerNameHandler, 
this));
 
  126                std::bind(&HttpRequestParser::spaceBeforeHeaderValueHandler, 
this));
 
  129                std::bind(&HttpRequestParser::headerValueHandler, 
this));
 
  132                std::bind(&HttpRequestParser::expectingNewLineHandler, 
this,
 
  136                std::bind(&HttpRequestParser::expectingNewLineHandler, 
this,
 
  140                std::bind(&HttpRequestParser::bodyHandler, 
this));
 
  144HttpRequestParser::receiveStartHandler() {
 
  153                parseFailure(
"invalid first character " + std::string(1, bytes[0]) +
 
  154                             " in HTTP method name");
 
  157                context_->method_.push_back(bytes[0]);
 
  169HttpRequestParser::httpMethodHandler() {
 
  178                         " in HTTP method name");
 
  183            context_->method_.push_back(c);
 
  190HttpRequestParser::uriHandler() {
 
  196        } 
else if (
isCtl(c)) {
 
  202            context_->uri_.push_back(c);
 
  209HttpRequestParser::versionHTTPHandler(
const char expected_letter,
 
  210                                      const unsigned int next_state) {
 
  212                         [
this, expected_letter, next_state](
const char c) {
 
  214        if (c == expected_letter) {
 
  219                context_->http_version_major_ = 0;
 
  220                context_->http_version_minor_ = 0;
 
  227            parseFailure(
"unexpected character " + std::string(1, c) +
 
  228                         " in HTTP version string");
 
  234HttpRequestParser::versionNumberStartHandler(
const unsigned int next_state,
 
  235                                             unsigned int* storage) {
 
  237                         [
this, next_state, storage](
const char c) 
mutable {
 
  241            *storage = *storage * 10 + c - 
'0';
 
  252HttpRequestParser::versionNumberHandler(
const char following_character,
 
  253                                        const unsigned int next_state,
 
  254                                        unsigned int* 
const storage) {
 
  256                         [
this, following_character, next_state, storage](
const char c)
 
  260        if (c == following_character) {
 
  263        } 
else if (isdigit(c)) {
 
  265            *storage = *storage * 10 + c - 
'0';
 
  275HttpRequestParser::expectingNewLineHandler(
const unsigned int next_state) {
 
  291                    uint64_t content_length =
 
  292                        request_.getHeaderValueAsUint64(
"Content-Length");
 
  293                    if (content_length > 0) {
 
  299                } 
catch (
const std::exception& ex) {
 
  302                    if (request_.requiresBody()) {
 
  324HttpRequestParser::headerLineStartHandler() {
 
  331        } 
else if (!context_->headers_.empty() && ((c == 
' ') || (c == 
'\t'))) {
 
  342            context_->headers_.push_back(HttpHeaderContext());
 
  343            context_->headers_.back().name_.push_back(c);
 
  350HttpRequestParser::headerLwsHandler() {
 
  357        } 
else if ((c == 
' ') || (c == 
'\t')) {
 
  362        } 
else if (
isCtl(c)) {
 
  363            parseFailure(
"control character found in the HTTP header " +
 
  364                        context_->headers_.back().name_);
 
  368            context_->headers_.back().value_.push_back(c);
 
  375HttpRequestParser::headerNameHandler() {
 
  383                         " found in the HTTP header name");
 
  387            context_->headers_.back().name_.push_back(c);
 
  394HttpRequestParser::spaceBeforeHeaderValueHandler() {
 
  400        } 
else if (c == 
'\r') {
 
  405        } 
else if (
isCtl(c)) {
 
  406            parseFailure(
"control character found in the HTTP header " 
  407                         + context_->headers_.back().name_);
 
  411            context_->headers_.back().value_.push_back(c);
 
  418HttpRequestParser::headerValueHandler() {
 
  425        } 
else if (
isCtl(c)) {
 
  426            parseFailure(
"control character found in the HTTP header " 
  427                         + context_->headers_.back().name_);
 
  431            context_->headers_.back().value_.push_back(c);
 
  438HttpRequestParser::bodyHandler() {
 
  442        context_->body_ += body;
 
  443        size_t content_length = request_.getHeaderValueAsUint64(
"Content-Length");
 
  444        if (context_->body_.length() < content_length) {
 
  449            if (context_->body_.length() > content_length) {
 
  450                context_->body_.resize(content_length);
 
void getNextFromBuffer(std::string &bytes, const size_t limit=1)
Retrieves next bytes of data from the buffer.
static const int DATA_READ_OK_EVT
Chunk of data successfully read and parsed.
static const int NEED_MORE_DATA_EVT
Unable to proceed with parsing until new data is provided.
bool isSpecial(const signed char c) const
Checks if specified value is a special character.
void parseFailure(const std::string &error_msg)
Transition parser to failure state.
bool isChar(const signed char c) const
Checks if specified value is a character.
void stateWithReadHandler(const std::string &handler_name, std::function< void(const char c)> after_read_logic)
Generic parser handler which reads a single byte of data and parses it using specified callback funct...
void invalidEventError(const std::string &handler_name, const unsigned int event)
This method is called when invalid event occurred in a particular parser state.
static const int HTTP_PARSE_OK_ST
Parsing successfully completed.
HttpMessageParserBase(HttpMessage &message)
Constructor.
void stateWithMultiReadHandler(const std::string &handler_name, std::function< void(const std::string &)> after_read_logic)
Generic parser handler which reads multiple bytes of data and parses it using specified callback func...
bool isCtl(const signed char c) const
Checks if specified value is a control value.
static const int HTTP_PARSE_OK_EVT
Parsing HTTP request successful.
virtual void defineStates() override
Defines states of the parser.
static const int EXPECTING_NEW_LINE1_ST
Parsing first new line (after HTTP version number).
static const int HTTP_URI_ST
Parsing URI.
static const int HTTP_VERSION_MAJOR_ST
Parsing major HTTP version number.
static const int HTTP_VERSION_SLASH_ST
Parsing slash character in "HTTP/Y.X".
static const int SPACE_BEFORE_HEADER_VALUE_ST
Parsing space before header value.
static const int HTTP_BODY_ST
Parsing body of a HTTP message.
static const int HTTP_VERSION_MAJOR_START_ST
Starting to parse major HTTP version number.
static const int EXPECTING_NEW_LINE3_ST
Expecting second new line marking end of HTTP headers.
static const int HEADER_NAME_ST
Parsing header name.
static const int RECEIVE_START_ST
State indicating a beginning of parsing.
void initModel()
Initialize the state model for parsing.
static const int HEADER_LWS_ST
Parsing LWS (Linear White Space), i.e.
static const int HTTP_VERSION_MINOR_ST
Parsing minor HTTP version number.
static const int HEADER_LINE_START_ST
Starting to parse a header line.
static const int HTTP_VERSION_H_ST
Parsing letter "H" of "HTTP".
static const int HTTP_VERSION_MINOR_START_ST
Starting to parse minor HTTP version number.
static const int HTTP_METHOD_ST
Parsing HTTP method, e.g. GET, POST etc.
static const int HEADER_VALUE_ST
Parsing header value.
HttpRequestParser(HttpRequest &request)
Constructor.
static const int EXPECTING_NEW_LINE2_ST
Expecting new line after parsing header value.
static const int HTTP_VERSION_P_ST
Parsing letter "P" in "HTTP".
static const int HTTP_VERSION_T2_ST
Parsing second occurrence of "T" in "HTTP".
static const int HTTP_VERSION_T1_ST
Parsing first occurrence of "T" in "HTTP".
Represents HTTP request message.
void initDictionaries()
Initializes the event and state dictionaries.
void postNextEvent(unsigned int event)
Sets the next event to the given event value.
void defineState(unsigned int value, const std::string &label, StateHandler handler, const StatePausing &state_pausing=STATE_PAUSE_NEVER)
Adds an state value and associated label to the set of states.
unsigned int getNextEvent() const
Fetches the model's next event.
void transition(unsigned int state, unsigned int event)
Sets up the model to transition into given state with a given event.
static const int START_EVT
Event issued to start the model execution.
void setState(unsigned int state)
Sets the current state to the given state value.
unsigned int getCurrState() const
Fetches the model's current state.
Defines the logger used by the top-level component of kea-lfc.