Kea 2.7.6
|
Base class for the HTTP message parsers. More...
#include <http_message_parser_base.h>
Static Public Attributes | |
States supported by the HttpMessageParserBase. | |
static const int | HTTP_PARSE_OK_ST = SM_DERIVED_STATE_MIN + 1000 |
Parsing successfully completed. | |
static const int | HTTP_PARSE_FAILED_ST = SM_DERIVED_STATE_MIN + 1001 |
Parsing failed. | |
Static Public Attributes inherited from isc::util::StateModel | |
static const int | END_EVT = 2 |
Event issued to end the model execution. | |
static const int | END_ST = 1 |
Final state, all the state model has reached its conclusion. | |
static const int | FAIL_EVT = 3 |
Event issued to abort the model execution. | |
static const int | NEW_ST = 0 |
State that a state model is in immediately after construction. | |
static const int | NOP_EVT = 0 |
Signifies that no event has occurred. | |
static const int | SM_DERIVED_EVENT_MIN = 11 |
Value at which custom events in a derived class should begin. | |
static const int | SM_DERIVED_STATE_MIN = 11 |
Value at which custom states in a derived class should begin. | |
static const int | START_EVT = 1 |
Event issued to start the model execution. | |
Events used during HTTP message parsing. | |
static const int | DATA_READ_OK_EVT = SM_DERIVED_EVENT_MIN + 1 |
Chunk of data successfully read and parsed. | |
static const int | NEED_MORE_DATA_EVT = SM_DERIVED_EVENT_MIN + 2 |
Unable to proceed with parsing until new data is provided. | |
static const int | MORE_DATA_PROVIDED_EVT = SM_DERIVED_EVENT_MIN + 3 |
New data provided and parsing should continue. | |
static const int | HTTP_PARSE_OK_EVT = SM_DERIVED_EVENT_MIN + 1000 |
Parsing HTTP request successful. | |
static const int | HTTP_PARSE_FAILED_EVT = SM_DERIVED_EVENT_MIN + 1001 |
Parsing HTTP request failed. | |
HttpMessage & | message_ |
Reference to the parsed HTTP message. | |
std::string | buffer_ |
Internal buffer from which parser reads data. | |
size_t | buffer_pos_ |
Position of the next character to read from the buffer. | |
std::string | error_message_ |
Error message set by onModelFailure. | |
HttpMessageParserBase (HttpMessage &message) | |
Constructor. | |
void | poll () |
Run the parser as long as the amount of data is sufficient. | |
bool | needData () const |
Returns true if the parser needs more data to continue. | |
bool | httpParseOk () const |
Returns true if the message has been parsed successfully. | |
std::string | getErrorMessage () const |
Returns error message. | |
void | postBuffer (const void *buf, const size_t buf_size) |
Provides more input data to the parser. | |
std::string | getBufferAsString (const size_t limit=0) const |
Returns parser's input buffer as string. | |
static std::string | logFormatHttpMessage (const std::string &message, const size_t limit=0) |
Formats provided HTTP message for logging. | |
virtual void | defineEvents () override |
Define events used by the parser. | |
virtual void | verifyEvents () override |
Verifies events used by the parser. | |
virtual void | defineStates () override |
Defines states of the parser. | |
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 function. | |
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 function. | |
void | parseFailure (const std::string &error_msg) |
Transition parser to failure state. | |
virtual void | onModelFailure (const std::string &explanation) override |
A method called when parsing fails. | |
void | getNextFromBuffer (std::string &bytes, const size_t limit=1) |
Retrieves next bytes of data from the buffer. | |
void | invalidEventError (const std::string &handler_name, const unsigned int event) |
This method is called when invalid event occurred in a particular parser state. | |
void | parseEndedHandler () |
Handler for HTTP_PARSE_OK_ST and HTTP_PARSE_FAILED_ST. | |
bool | popNextFromBuffer (std::string &next, const size_t limit=1) |
Tries to read next byte from buffer. | |
bool | isChar (const signed char c) const |
Checks if specified value is a character. | |
bool | isCtl (const signed char c) const |
Checks if specified value is a control value. | |
bool | isSpecial (const signed char c) const |
Checks if specified value is a special character. | |
Additional Inherited Members | |
Public Member Functions inherited from isc::util::StateModel | |
StateModel () | |
Constructor. | |
virtual | ~StateModel () |
Destructor. | |
bool | didModelFail () const |
Returns whether or not the model failed. | |
void | endModel () |
Conducts a normal transition to the end of the model. | |
std::string | getContextStr () const |
Convenience method which returns a string rendition of the current state and next event. | |
unsigned int | getCurrState () const |
Fetches the model's current state. | |
std::string | getEventLabel (const int event) const |
Fetches the label associated with an event value. | |
unsigned int | getLastEvent () const |
Fetches the model's last event. | |
unsigned int | getNextEvent () const |
Fetches the model's next event. | |
std::string | getPrevContextStr () const |
Convenience method which returns a string rendition of the previous state and last event. | |
unsigned int | getPrevState () const |
Fetches the model's previous state. | |
std::string | getStateLabel (const int state) const |
Fetches the label associated with an state value. | |
bool | isModelDone () const |
Returns whether or not the model has finished execution. | |
bool | isModelNew () const |
Returns whether or not the model is new. | |
bool | isModelPaused () const |
Returns whether or not the model is paused. | |
bool | isModelRunning () const |
Returns whether or not the model is running. | |
bool | isModelWaiting () const |
Returns whether or not the model is waiting. | |
void | nopStateHandler () |
An empty state handler. | |
virtual void | runModel (unsigned int event) |
Processes events through the state model. | |
void | startModel (const int start_state) |
Begins execution of the model. | |
void | unpauseModel () |
Unpauses state model. | |
Protected Member Functions inherited from isc::util::StateModel | |
void | abortModel (const std::string &explanation) |
Aborts model execution. | |
void | defineEvent (unsigned int value, const std::string &label) |
Adds an event value and associated label to the set of events. | |
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. | |
bool | doOnEntry () |
Checks if on entry flag is true. | |
bool | doOnExit () |
Checks if on exit flag is true. | |
const EventPtr & | getEvent (unsigned int value) |
Fetches the event referred to by value. | |
const StatePtr | getState (unsigned int value) |
Fetches the state referred to by value. | |
const StatePtr | getStateInternal (unsigned int value) |
Fetches the state referred to by value. | |
void | initDictionaries () |
Initializes the event and state dictionaries. | |
void | postNextEvent (unsigned int event) |
Sets the next event to the given event value. | |
void | setState (unsigned int state) |
Sets the current state to the given state value. | |
void | transition (unsigned int state, unsigned int event) |
Sets up the model to transition into given state with a given event. | |
virtual void | verifyStates () |
Validates the contents of the set of states. | |
Base class for the HTTP message parsers.
This is a base class for HttpRequestParser
and HttpResponseParser
classes. It provides common states, events and functionality for processing the received HTTP messages.
This class must not be used directly. Instead, an instance of the derived class should be used.
HTTP uses TCP as a transport which is asynchronous in nature, i.e. the HTTP message is received in chunks and multiple TCP connections can be established at the same time. Multiplexing between these connections requires providing a separate state machine per connection to "remember" the state of each transaction when the parser is waiting for asynchronous data to be delivered. While the parser is waiting for the data, it can parse requests received over other connections. This class provides means for parsing partial data received over the specific connection and interrupting data parsing to switch to a different context.
A new method HttpMessageParserBase::poll has been created to run the parser's state machine as long as there are unparsed data in the parser's internal buffer. This method returns control to the caller when the parser runs out of data in this buffer. The caller must feed the buffer by calling HttpMessageParserBase::postBuffer and then run HttpMessageParserBase::poll again.
In case, the caller provides more data than indicated by the "Content-Length" header the parser will return from poll()
after parsing the data which constitute the HTTP request and not parse the extraneous data. The caller should test the HttpMessageParserBase::needData and HttpMessageParserBase::httpParseOk to determine whether parsing has completed.
The util::StateModel::runModel must not be used to run the parser state machine, thus it is made private method.
Definition at line 65 of file http_message_parser_base.h.
isc::http::HttpMessageParserBase::HttpMessageParserBase | ( | HttpMessage & | message | ) |
Constructor.
message | Reference to the HTTP request or response message. |
Definition at line 28 of file http_message_parser_base.cc.
|
overrideprotectedvirtual |
Define events used by the parser.
Reimplemented from isc::util::StateModel.
Definition at line 101 of file http_message_parser_base.cc.
References DATA_READ_OK_EVT, isc::util::StateModel::defineEvent(), isc::util::StateModel::defineEvents(), HTTP_PARSE_FAILED_EVT, HTTP_PARSE_OK_EVT, MORE_DATA_PROVIDED_EVT, and NEED_MORE_DATA_EVT.
|
overrideprotectedvirtual |
Defines states of the parser.
Reimplemented from isc::util::StateModel.
Definition at line 124 of file http_message_parser_base.cc.
References isc::util::StateModel::defineState(), isc::util::StateModel::defineStates(), HTTP_PARSE_FAILED_ST, HTTP_PARSE_OK_ST, and parseEndedHandler().
std::string isc::http::HttpMessageParserBase::getBufferAsString | ( | const size_t | limit = 0 | ) | const |
Returns parser's input buffer as string.
limit | Maximum length of the buffer to be output. If the limit is 0, the length of the output is unlimited. |
Definition at line 76 of file http_message_parser_base.cc.
References buffer_, and logFormatHttpMessage().
|
inline |
Returns error message.
Definition at line 128 of file http_message_parser_base.h.
References error_message_.
|
protected |
Retrieves next bytes of data from the buffer.
During normal operation, when there is no more data in the buffer, the parser sets NEED_MORE_DATA_EVT as next event to signal the need for calling HttpMessageParserBase::postBuffer.
[out] | bytes | Reference to the variable where read data should be stored. |
limit | Maximum number of bytes to be read. |
HttpMessageParserBaseError | If current event is already set to NEED_MORE_DATA_EVT or MORE_DATA_PROVIDED_EVT. In the former case, it indicates that the caller failed to provide new data using HttpMessageParserBase::postBuffer. The latter case is highly unlikely as it indicates that no new data were provided but the state of the parser was changed from NEED_MORE_DATA_EVT or the data were provided but the data buffer is empty. In both cases, it is an internal server error. |
Definition at line 187 of file http_message_parser_base.cc.
References isc::util::StateModel::getNextEvent(), isc_throw, MORE_DATA_PROVIDED_EVT, NEED_MORE_DATA_EVT, popNextFromBuffer(), and isc::util::StateModel::postNextEvent().
Referenced by stateWithMultiReadHandler(), and stateWithReadHandler().
bool isc::http::HttpMessageParserBase::httpParseOk | ( | ) | const |
Returns true if the message has been parsed successfully.
Definition at line 55 of file http_message_parser_base.cc.
References isc::util::StateModel::END_EVT, isc::util::StateModel::getLastEvent(), isc::util::StateModel::getNextEvent(), and HTTP_PARSE_OK_EVT.
|
protected |
This method is called when invalid event occurred in a particular parser state.
This method simply throws HttpParseError informing about invalid event occurring for the particular parser state. The error message includes the name of the handler in which the exception has been thrown. It also includes the event which caused the exception.
handler_name | Name of the handler in which the exception is thrown. |
event | An event which caused the exception. |
HttpMessageParserBaseError. |
Definition at line 223 of file http_message_parser_base.cc.
References isc::util::StateModel::getEventLabel(), and isc_throw.
Referenced by parseEndedHandler(), stateWithMultiReadHandler(), and stateWithReadHandler().
|
protected |
Checks if specified value is a character.
Definition at line 264 of file http_message_parser_base.cc.
|
protected |
Checks if specified value is a control value.
Definition at line 269 of file http_message_parser_base.cc.
|
protected |
Checks if specified value is a special character.
Definition at line 274 of file http_message_parser_base.cc.
|
static |
Formats provided HTTP message for logging.
This method is useful in cases when there is a need to log a HTTP message (as text). If the limit
is specified the message output is limited to this size. If the limit
is set to 0 (default), the whole message is output. The getBufferAsString
method calls this method internally.
message | HTTP message to be logged. |
limit | Maximum length of the buffer to be output. If the limit is 0, the length of the output is unlimited. |
Definition at line 82 of file http_message_parser_base.cc.
Referenced by getBufferAsString(), and isc::http::HttpConnection::socketReadCallback().
bool isc::http::HttpMessageParserBase::needData | ( | ) | const |
Returns true if the parser needs more data to continue.
Definition at line 49 of file http_message_parser_base.cc.
References isc::util::StateModel::getNextEvent(), NEED_MORE_DATA_EVT, and isc::util::StateModel::START_EVT.
|
overrideprotectedvirtual |
A method called when parsing fails.
explanation | Error message explaining the reason for parsing failure. |
Reimplemented from isc::util::StateModel.
Definition at line 180 of file http_message_parser_base.cc.
References error_message_.
|
protected |
Handler for HTTP_PARSE_OK_ST and HTTP_PARSE_FAILED_ST.
If parsing is successful, it calls HttpRequest::create to validate the HTTP request. In both cases it transitions the parser to the END_ST.
Definition at line 230 of file http_message_parser_base.cc.
References isc::util::StateModel::abortModel(), isc::util::StateModel::END_EVT, isc::util::StateModel::END_ST, isc::http::HttpMessage::finalize(), isc::util::StateModel::getNextEvent(), HTTP_PARSE_FAILED_EVT, HTTP_PARSE_OK_EVT, invalidEventError(), message_, and isc::util::StateModel::transition().
Referenced by defineStates().
|
protected |
Transition parser to failure state.
This method transitions the parser to HTTP_PARSE_FAILED_ST and sets next event to HTTP_PARSE_FAILED_EVT.
error_msg | Error message explaining the failure. |
Definition at line 174 of file http_message_parser_base.cc.
References error_message_, isc::util::StateModel::getContextStr(), HTTP_PARSE_FAILED_EVT, HTTP_PARSE_FAILED_ST, and isc::util::StateModel::transition().
void isc::http::HttpMessageParserBase::poll | ( | ) |
Run the parser as long as the amount of data is sufficient.
The data to be parsed should be provided by calling HttpMessageParserBase::postBuffer. When the parser reaches the end of the data buffer the HttpMessageParserBase::poll sets the next event to NEED_MORE_DATA_EVT and returns. The caller should then invoke HttpMessageParserBase::postBuffer again to provide more data to the parser, and call HttpMessageParserBase::poll to continue parsing.
This method also returns when parsing completes or fails. The last event can be examined to check whether parsing was successful or not.
Definition at line 34 of file http_message_parser_base.cc.
References isc::util::StateModel::abortModel(), isc::util::StateModel::getCurrState(), isc::util::StateModel::getNextEvent(), isc::util::StateModel::getState(), isc::util::StateModel::isModelDone(), NEED_MORE_DATA_EVT, and isc::util::StateModel::NOP_EVT.
|
protected |
Tries to read next byte from buffer.
[out] | next | A reference to the variable where read data should be stored. |
limit | Maximum number of characters to be read. |
Definition at line 246 of file http_message_parser_base.cc.
References buffer_, and buffer_pos_.
Referenced by getNextFromBuffer().
void isc::http::HttpMessageParserBase::postBuffer | ( | const void * | buf, |
const size_t | buf_size ) |
Provides more input data to the parser.
This method must be called prior to calling HttpMessageParserBase::poll to deliver data to be parsed. HTTP messages are received over TCP and multiple reads may be necessary to retrieve the entire request. There is no need to accumulate the entire request to start parsing it. A chunk of data can be provided to the parser using this method and parsed right away using HttpMessageParserBase::poll.
buf | A pointer to the buffer holding the data. |
buf_size | Size of the data within the buffer. |
Definition at line 61 of file http_message_parser_base.cc.
References buffer_, isc::util::StateModel::getCurrState(), isc::util::StateModel::getNextEvent(), MORE_DATA_PROVIDED_EVT, NEED_MORE_DATA_EVT, and isc::util::StateModel::transition().
|
protected |
Generic parser handler which reads multiple bytes of data and parses it using specified callback function.
This handler is mostly used for parsing body of the HTTP message, where we don't validate the content read. Reading multiple bytes is the most efficient. If there is no more data it simply returns. Otherwise, if the next event is DATA_READ_OK_EVT or MORE_DATA_PROVIDED_EVT, it calls the provided callback function to parse the new byte of data.
handler_name | Name of the handler function which called this method. |
after_read_logic | Callback function to parse multiple bytes of data. This callback function implements state specific logic. |
HttpRequestParserError | when invalid event occurred. |
Definition at line 155 of file http_message_parser_base.cc.
References DATA_READ_OK_EVT, isc::util::StateModel::getNextEvent(), getNextFromBuffer(), invalidEventError(), MORE_DATA_PROVIDED_EVT, and NEED_MORE_DATA_EVT.
|
protected |
Generic parser handler which reads a single byte of data and parses it using specified callback function.
This generic handler is used in most of the parser states to parse a single byte of input data. If there is no more data it simply returns. Otherwise, if the next event is DATA_READ_OK_EVT or MORE_DATA_PROVIDED_EVT, it calls the provided callback function to parse the new byte of data. For all other states it throws an exception.
handler_name | Name of the handler function which called this method. |
after_read_logic | Callback function to parse the byte of data. This callback function implements state specific logic. |
HttpRequestParserError | when invalid event occurred. |
Definition at line 136 of file http_message_parser_base.cc.
References DATA_READ_OK_EVT, isc::util::StateModel::getNextEvent(), getNextFromBuffer(), invalidEventError(), MORE_DATA_PROVIDED_EVT, and NEED_MORE_DATA_EVT.
|
overrideprotectedvirtual |
Verifies events used by the parser.
Reimplemented from isc::util::StateModel.
Definition at line 113 of file http_message_parser_base.cc.
References DATA_READ_OK_EVT, isc::util::StateModel::getEvent(), HTTP_PARSE_FAILED_EVT, HTTP_PARSE_OK_EVT, MORE_DATA_PROVIDED_EVT, NEED_MORE_DATA_EVT, and isc::util::StateModel::verifyEvents().
|
protected |
Internal buffer from which parser reads data.
Definition at line 305 of file http_message_parser_base.h.
Referenced by getBufferAsString(), popNextFromBuffer(), and postBuffer().
|
protected |
Position of the next character to read from the buffer.
Definition at line 308 of file http_message_parser_base.h.
Referenced by popNextFromBuffer().
|
static |
Chunk of data successfully read and parsed.
Definition at line 85 of file http_message_parser_base.h.
Referenced by defineEvents(), stateWithMultiReadHandler(), stateWithReadHandler(), and verifyEvents().
|
protected |
Error message set by onModelFailure.
Definition at line 311 of file http_message_parser_base.h.
Referenced by getErrorMessage(), onModelFailure(), and parseFailure().
|
static |
Parsing HTTP request failed.
Definition at line 97 of file http_message_parser_base.h.
Referenced by defineEvents(), parseEndedHandler(), parseFailure(), and verifyEvents().
|
static |
Parsing failed.
Definition at line 76 of file http_message_parser_base.h.
Referenced by defineStates(), and parseFailure().
|
static |
Parsing HTTP request successful.
Definition at line 94 of file http_message_parser_base.h.
Referenced by defineEvents(), httpParseOk(), parseEndedHandler(), and verifyEvents().
|
static |
Parsing successfully completed.
Definition at line 73 of file http_message_parser_base.h.
Referenced by defineStates().
|
protected |
Reference to the parsed HTTP message.
Definition at line 302 of file http_message_parser_base.h.
Referenced by parseEndedHandler().
|
static |
New data provided and parsing should continue.
Definition at line 91 of file http_message_parser_base.h.
Referenced by defineEvents(), getNextFromBuffer(), postBuffer(), stateWithMultiReadHandler(), stateWithReadHandler(), and verifyEvents().
|
static |
Unable to proceed with parsing until new data is provided.
Definition at line 88 of file http_message_parser_base.h.
Referenced by defineEvents(), getNextFromBuffer(), needData(), poll(), postBuffer(), stateWithMultiReadHandler(), stateWithReadHandler(), and verifyEvents().