libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit 8391cfa210f8e5b6cac2fff9d8e49f1003c91a44
parent d4a6985d12d56a13e0cbb4e3d8cf8879b393bc49
Author: Evgeny Grin (Karlson2k) <k2k@narod.ru>
Date:   Sat, 12 Jun 2021 20:31:42 +0300

connection.c: added detection of standard HTTP methods

Detection was added only for basic methods as defined in RFC7231

Diffstat:
Msrc/microhttpd/connection.c | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/microhttpd/internal.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 112 insertions(+), 0 deletions(-)

diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c @@ -2215,6 +2215,58 @@ parse_http_version (struct MHD_Connection *connection, /** + * Detect standard HTTP request method + * + * @param connection the connection + * @param method the pointer to HTTP request method string + * @param len the length of @a method in bytes + * @return #MHD_YES if HTTP method is valid string, + * #MHD_NO if HTTP method string is not valid. + */ +static enum MHD_Result +parse_http_std_method (struct MHD_Connection *connection, + const char *method, + size_t len) +{ + const char *const m = method; /**< short alias */ + mhd_assert (NULL != m); + + if (0 == len) + return MHD_NO; + + if ((MHD_STATICSTR_LEN_ (MHD_HTTP_METHOD_GET) == len) && + (0 == memcmp (m, MHD_HTTP_METHOD_GET, len))) + connection->http_mthd = MHD_HTTP_MTHD_GET; + else if ((MHD_STATICSTR_LEN_ (MHD_HTTP_METHOD_HEAD) == len) && + (0 == memcmp (m, MHD_HTTP_METHOD_HEAD, len))) + connection->http_mthd = MHD_HTTP_MTHD_HEAD; + else if ((MHD_STATICSTR_LEN_ (MHD_HTTP_METHOD_POST) == len) && + (0 == memcmp (m, MHD_HTTP_METHOD_POST, len))) + connection->http_mthd = MHD_HTTP_MTHD_POST; + else if ((MHD_STATICSTR_LEN_ (MHD_HTTP_METHOD_PUT) == len) && + (0 == memcmp (m, MHD_HTTP_METHOD_PUT, len))) + connection->http_mthd = MHD_HTTP_MTHD_PUT; + else if ((MHD_STATICSTR_LEN_ (MHD_HTTP_METHOD_DELETE) == len) && + (0 == memcmp (m, MHD_HTTP_METHOD_DELETE, len))) + connection->http_mthd = MHD_HTTP_MTHD_DELETE; + else if ((MHD_STATICSTR_LEN_ (MHD_HTTP_METHOD_CONNECT) == len) && + (0 == memcmp (m, MHD_HTTP_METHOD_CONNECT, len))) + connection->http_mthd = MHD_HTTP_MTHD_CONNECT; + else if ((MHD_STATICSTR_LEN_ (MHD_HTTP_METHOD_OPTIONS) == len) && + (0 == memcmp (m, MHD_HTTP_METHOD_OPTIONS, len))) + connection->http_mthd = MHD_HTTP_MTHD_OPTIONS; + else if ((MHD_STATICSTR_LEN_ (MHD_HTTP_METHOD_TRACE) == len) && + (0 == memcmp (m, MHD_HTTP_METHOD_TRACE, len))) + connection->http_mthd = MHD_HTTP_MTHD_TRACE; + else + connection->http_mthd = MHD_HTTP_MTHD_OTHER; + + /* Any method string with non-zero length is valid */ + return MHD_YES; +} + + +/** * Parse the first line of the HTTP HEADER. * * @param connection the connection (updated) @@ -2240,9 +2292,13 @@ parse_initial_message_line (struct MHD_Connection *connection, return MHD_NO; /* serious error */ uri[0] = '\0'; connection->method = line; + if (MHD_NO == parse_http_std_method (connection, connection->method, + (size_t) (uri - line))) + return MHD_NO; uri++; /* Skip any spaces. Not required by standard but allow to be more tolerant. */ + /* TODO: do not skip them in standard mode */ while ( (' ' == uri[0]) && ( (size_t) (uri - line) < line_len) ) uri++; @@ -2263,6 +2319,7 @@ parse_initial_message_line (struct MHD_Connection *connection, /* Search from back to accept malformed URI with space */ http_version = line + line_len - 1; /* Skip any trailing spaces */ + /* TODO: do not skip them in standard mode */ while ( (' ' == http_version[0]) && (http_version > uri) ) http_version--; @@ -3934,6 +3991,7 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) connection->current_chunk_size = 0; connection->current_chunk_offset = 0; connection->method = NULL; + connection->http_mthd = MHD_HTTP_MTHD_NO_METHOD; connection->url = NULL; connection->write_buffer = NULL; connection->write_buffer_size = 0; diff --git a/src/microhttpd/internal.h b/src/microhttpd/internal.h @@ -771,6 +771,55 @@ enum MHD_HTTP_Version }; /** + * The HTTP method. + * + * Only primary methods (specified in RFC7231) defined here. + */ +enum MHD_HTTP_Method +{ + /** + * No request string has been received yet + */ + MHD_HTTP_MTHD_NO_METHOD = 0, + /** + * HTTP method GET + */ + MHD_HTTP_MTHD_GET = 1, + /** + * HTTP method HEAD + */ + MHD_HTTP_MTHD_HEAD = 2, + /** + * HTTP method POST + */ + MHD_HTTP_MTHD_POST = 3, + /** + * HTTP method PUT + */ + MHD_HTTP_MTHD_PUT = 4, + /** + * HTTP method DELETE + */ + MHD_HTTP_MTHD_DELETE = 5, + /** + * HTTP method CONNECT + */ + MHD_HTTP_MTHD_CONNECT = 6, + /** + * HTTP method OPTIONS + */ + MHD_HTTP_MTHD_OPTIONS = 7, + /** + * HTTP method TRACE + */ + MHD_HTTP_MTHD_TRACE = 8, + /** + * Other HTTP method. Check the string value. + */ + MHD_HTTP_MTHD_OTHER = 1000 +}; + +/** * Returns boolean 'true' if HTTP version is supported by MHD */ #define MHD_IS_HTTP_VER_SUPPORTED(ver) (MHD_HTTP_VER_1_0 <= (ver) && \ @@ -880,6 +929,11 @@ struct MHD_Connection char *method; /** + * The request method as enum. + */ + enum MHD_HTTP_Method http_mthd; + + /** * Requested URL (everything after "GET" only). Allocated * in pool. */