29 #include "http_parser.h"
141 static int parser_url (http_parser *parser,
const char *buf,
size_t len);
142 static int parser_hdr_field(http_parser *parser,
const char *buf,
size_t len);
143 static int parser_hdr_value(http_parser *parser,
const char *buf,
size_t len);
145 static int parser_body (http_parser *parser,
const char *buf,
size_t len);
174 char *newUrl = realloc(req->
url,
sizeof(
char)*(segment_length+1));
177 strncpy(req->
url, parsedSegment, segment_length);
178 req->
url[segment_length] =
'\0';
221 const char *existing;
231 if (strncmp(field,
"Cookie", 6) == 0) {
232 size_t key_s = 0, key_e, val_s, val_e;
234 while (key_s < value_length) {
235 for (key_e = key_s; key_e < value_length && value[key_e] !=
'='; key_e++);
238 for (val_e = val_s; val_e < value_length && value[val_e] !=
';'; val_e++);
239 if (key_e-key_s > 0 && val_e-val_s > 0) {
240 if ((rc =
hpd_map_set_n(req->
cookies, &value[key_s], (
size_t) key_e - key_s, &value[val_s], val_e - val_s)))
return rc;
251 size_t new_len = strlen(existing) + 1 + value_length + 1;
252 char *
new = malloc(new_len *
sizeof(
char));
254 strcpy(
new, existing);
256 strncat(
new, value, value_length);
257 new[new_len-1] =
'\0';
290 switch (req->
state) {
321 static int parser_url(http_parser *parser,
const char *buf,
size_t len)
328 switch ((
enum http_method) req->
parser.method) {
343 switch (req->
state) {
387 switch (req->
state) {
440 switch (req->
state) {
483 switch (req->
state) {
528 static int parser_body(http_parser *parser,
const char *buf,
size_t len)
534 switch (req->
state) {
567 switch (req->
state) {
614 (*req)->webserver = httpd;
619 http_parser_init(&((*req)->parser), HTTP_REQUEST);
620 (*req)->parser.data = (*req);
627 if ((rc =
up_create(&(*req)->url_parser, &up_settings, context, (*req))))
goto error;
631 hp_settings.
data = (*req);
633 if ((rc =
hp_create(&(*req)->header_parser, &hp_settings, context)))
goto error;
648 HPD_LOG_ERROR(context,
"Failed to destroy request (code: %d)\n", rc2);
701 enum http_errno err = HTTP_PARSER_ERRNO(&req->
parser);
706 case HPE_CB_message_begin:
708 case HPE_CB_header_field:
709 case HPE_CB_header_value:
710 case HPE_CB_headers_complete:
712 case HPE_CB_message_complete:
714 case HPE_CB_chunk_header:
715 case HPE_CB_chunk_complete:
717 case HPE_INVALID_EOF_STATE:
718 case HPE_HEADER_OVERFLOW:
719 case HPE_CLOSED_CONNECTION:
720 case HPE_INVALID_VERSION:
721 case HPE_INVALID_STATUS:
722 case HPE_INVALID_METHOD:
723 case HPE_INVALID_URL:
724 case HPE_INVALID_HOST:
725 case HPE_INVALID_PORT:
726 case HPE_INVALID_PATH:
727 case HPE_INVALID_QUERY_STRING:
728 case HPE_INVALID_FRAGMENT:
729 case HPE_LF_EXPECTED:
730 case HPE_INVALID_HEADER_TOKEN:
731 case HPE_INVALID_CONTENT_LENGTH:
732 case HPE_UNEXPECTED_CONTENT_LENGTH:
733 case HPE_INVALID_CHUNK_SIZE:
734 case HPE_INVALID_CONSTANT:
735 case HPE_INVALID_INTERNAL_STATE:
740 http_errno_description(err), err);
struct hp * header_parser
Header Parser.
hpd_error_t hp_on_header_field(struct hp *instance, const char *field_chunk, size_t length)
hpd_map_t * cookies
Cookie Pairs.
#define HPD_LOG_RETURN(CONTEXT, E, FMT,...)
hpd_error_t hp_destroy(struct hp *instance)
static hpd_error_t header_parser_field_value_pair_complete(void *data, const char *field, size_t field_length, const char *value, size_t value_length)
Callback for the header parser.
hpd_tcpd_conn_t * conn
Connection to client.
hpd_error_t hpd_httpd_request_get_method(hpd_httpd_request_t *req, hpd_httpd_method_t *method)
Get the method of the http request.
up_string_cb on_path_complete
hpd_httpd_data_f on_req_hdr_field
hpd_error_t hpd_httpd_request_get_header(hpd_httpd_request_t *req, const char *key, const char **value)
Get a specific header of a request.
#define HP_SETTINGS_DEFAULT
static int parser_hdr_value(http_parser *parser, const char *buf, size_t len)
Header value callback for http_parser.
static int parser_hdr_field(http_parser *parser, const char *buf, size_t len)
Header field callback for http_parser.
static int parser_msg_cmpl(http_parser *parser)
Messages complete callback for http_parser.
hpd_error_t hpd_map_get_n(hpd_map_t *map, const char *k, size_t k_len, const char **v)
hpd_httpd_t * webserver
HTTP Webserver.
hpd_error_t http_request_get_context(hpd_httpd_request_t *req, const hpd_module_t **context)
hpd_map_t * headers
Header Pairs.
hpd_error_t hpd_httpd_request_get_cookies(hpd_httpd_request_t *req, hpd_map_t **cookies)
Get a all cookies for a request.
hpd_error_t up_add_chunk(struct up *instance, const char *chunk, size_t len)
Parse a chunk of an URL.
static int parser_msg_begin(http_parser *parser)
Message begin callback for http_parser.
struct hp_settings settings
hpd_error_t hpd_map_free(hpd_map_t *map)
static hpd_error_t url_parser_path_complete(void *data, const char *parsedSegment, size_t segment_length)
Callback for URL parser.
hpd_error_t hpd_tcpd_conn_keep_open(hpd_tcpd_conn_t *conn)
Disable timeout on connection.
hpd_httpd_settings_t * settings
Settings.
hpd_error_t hpd_tcpd_conn_get_ip(hpd_tcpd_conn_t *conn, const char **ip)
Get the IP address of the client.
hpd_error_t http_request_get_connection(hpd_httpd_request_t *req, hpd_tcpd_conn_t **conn)
Get the connection of a request.
hpd_error_t hpd_httpd_request_get_url(hpd_httpd_request_t *req, const char **url)
Get the URL of this request.
hpd_error_t hpd_httpd_request_get_cookie(hpd_httpd_request_t *req, const char *key, const char **val)
Get a specific cookie for a request.
hpd_error_t hpd_map_set_n(hpd_map_t *map, const char *k, size_t k_len, const char *v, size_t v_len)
#define UP_SETTINGS_DEFAULT
struct up * url_parser
URL Parser.
hpd_httpd_nodata_f on_req_url_cmpl
hp_string_cb on_field_value_pair
enum state state
Current state.
hpd_error_t up_destroy(struct up *instance)
Destroy URL parser instance.
enum hpd_error hpd_error_t
#define HPD_LOG_RETURN_E_ALLOC(CONTEXT)
hpd_httpd_nodata_f on_req_begin
hpd_error_t hpd_httpd_request_get_argument(hpd_httpd_request_t *req, const char *key, const char **val)
Get a specific argument of a request.
hpd_map_t * arguments
URL Arguments.
hpd_error_t http_request_destroy(hpd_httpd_request_t *req)
Destroy a ws_request.
#define HPD_LOG_RETURN_E_NULL(CONTEXT)
http_parser parser
HTTP parser.
hpd_httpd_method_t method
hpd_httpd_nodata_f on_req_hdr_cmpl
hpd_error_t hpd_httpd_request_keep_open(hpd_httpd_request_t *req)
Keep the connection for a request open.
hpd_error_t hpd_map_get(hpd_map_t *map, const char *k, const char **v)
All data to represent a connection.
Settings struct for webserver.
hpd_error_t hp_create(struct hp **instance, struct hp_settings *settings, const hpd_module_t *context)
hpd_error_t http_request_create(hpd_httpd_request_t **req, hpd_httpd_t *httpd, hpd_httpd_settings_t *settings, hpd_tcpd_conn_t *conn, const hpd_module_t *context)
Create a new ws_request.
static int parser_url(http_parser *parser, const char *buf, size_t len)
URL callback for http_parser.
enum hpd_httpd_return hpd_httpd_return_t
hpd_error_t up_complete(struct up *instance)
Informs the parser that the URL is complete.
static int parser_body(http_parser *parser, const char *buf, size_t len)
Body callback for http_parser.
hpd_error_t hpd_httpd_request_get_headers(hpd_httpd_request_t *req, hpd_map_t **headers)
Get a linked map of all headers for a request.
hpd_error_t hpd_map_alloc(hpd_map_t **map)
hpd_error_t http_request_parse(hpd_httpd_request_t *req, const char *buf, size_t len)
Parse a new chunk of the message.
hpd_httpd_nodata_f on_req_destroy
hpd_httpd_nodata_f on_req_cmpl
state
The possible states of a request.
const hpd_module_t * context
Receiving a header field.
hpd_error_t hpd_httpd_request_get_arguments(hpd_httpd_request_t *req, hpd_map_t **arguments)
Get a linked map of all URL arguements for a request.
Settings struct for the URL Parser.
hpd_error_t hp_on_header_complete(struct hp *instance)
Callback requested a stop.
hpd_httpd_data_f on_req_body
static http_parser_settings parser_settings
Global settings for http_parser.
hpd_error_t up_create(struct up **instance, struct up_settings *settings, const hpd_module_t *context, void *data)
Create URL parser instance.
enum hpd_httpd_method hpd_httpd_method_t
Receiving a header value.
static int parser_hdr_cmpl(http_parser *parser)
Header complete callback for http_parser.
#define HPD_LOG_ERROR(CONTEXT, FMT,...)
hpd_error_t hpd_httpd_request_get_ip(hpd_httpd_request_t *req, const char **ip)
Get the IP of a request.
hpd_httpd_data_f on_req_url
hpd_httpd_data_f on_req_hdr_value
static hpd_error_t url_parser_key_value(void *data, const char *key, size_t key_len, const char *value, size_t value_len)
Callback for URL parser.
hpd_error_t hp_on_header_value(struct hp *instance, const char *value_chunk, size_t length)
const hpd_module_t * context