My Project
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
Macros | Enumerations | Functions | Variables
http_parser.c File Reference
#include "webserver/http_parser.h"
#include <assert.h>
#include <stddef.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>

Go to the source code of this file.

Macros

#define ULLONG_MAX   ((uint64_t) -1) /* 2^64-1 */
 
#define MIN(a, b)   ((a) < (b) ? (a) : (b))
 
#define ARRAY_SIZE(a)   (sizeof(a) / sizeof((a)[0]))
 
#define BIT_AT(a, i)
 
#define ELEM_AT(a, i, v)   ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v))
 
#define SET_ERRNO(e)
 
#define CURRENT_STATE()   p_state
 
#define UPDATE_STATE(V)   p_state = (enum state) (V);
 
#define RETURN(V)
 
#define REEXECUTE()   goto reexecute; \
 
#define LIKELY(X)   (X)
 
#define UNLIKELY(X)   (X)
 
#define CALLBACK_NOTIFY_(FOR, ER)
 
#define CALLBACK_NOTIFY(FOR)   CALLBACK_NOTIFY_(FOR, p - data + 1)
 
#define CALLBACK_NOTIFY_NOADVANCE(FOR)   CALLBACK_NOTIFY_(FOR, p - data)
 
#define CALLBACK_DATA_(FOR, LEN, ER)
 
#define CALLBACK_DATA(FOR)   CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)
 
#define CALLBACK_DATA_NOADVANCE(FOR)   CALLBACK_DATA_(FOR, p - FOR##_mark, p - data)
 
#define MARK(FOR)
 
#define COUNT_HEADER_SIZE(V)
 
#define PROXY_CONNECTION   "proxy-connection"
 
#define CONNECTION   "connection"
 
#define CONTENT_LENGTH   "content-length"
 
#define TRANSFER_ENCODING   "transfer-encoding"
 
#define UPGRADE   "upgrade"
 
#define CHUNKED   "chunked"
 
#define KEEP_ALIVE   "keep-alive"
 
#define CLOSE   "close"
 
#define XX(num, name, string)   #string,
 
#define T(v)   v
 
#define PARSING_HEADER(state)   (state <= s_headers_done)
 
#define CR   '\r'
 
#define LF   '\n'
 
#define LOWER(c)   (unsigned char)(c | 0x20)
 
#define IS_ALPHA(c)   (LOWER(c) >= 'a' && LOWER(c) <= 'z')
 
#define IS_NUM(c)   ((c) >= '0' && (c) <= '9')
 
#define IS_ALPHANUM(c)   (IS_ALPHA(c) || IS_NUM(c))
 
#define IS_HEX(c)   (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f'))
 
#define IS_MARK(c)
 
#define IS_USERINFO_CHAR(c)
 
#define STRICT_TOKEN(c)   (tokens[(unsigned char)c])
 
#define TOKEN(c)   ((c == ' ') ? ' ' : tokens[(unsigned char)c])
 
#define IS_URL_CHAR(c)   (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80))
 
#define IS_HOST_CHAR(c)   (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_')
 
#define IS_HEADER_CHAR(ch)   (ch == CR || ch == LF || ch == 9 || ((unsigned char)ch > 31 && ch != 127))
 Verify that a char is a valid visible (printable) US-ASCII character or x80-FF. More...
 
#define start_state   (parser->type == HTTP_REQUEST ? s_start_req : s_start_res)
 
#define STRICT_CHECK(cond)
 
#define NEW_MESSAGE()   start_state
 
#define HTTP_STRERROR_GEN(n, s)   { "HPE_" #n, s },
 
#define XX(meth, pos, ch, new_meth)
 

Enumerations

enum  state {
  s_dead = 1, s_start_req_or_res, s_res_or_resp_H, s_start_res,
  s_res_H, s_res_HT, s_res_HTT, s_res_HTTP,
  s_res_http_major, s_res_http_dot, s_res_http_minor, s_res_http_end,
  s_res_first_status_code, s_res_status_code, s_res_status_start, s_res_status,
  s_res_line_almost_done, s_start_req, s_req_method, s_req_spaces_before_url,
  s_req_schema, s_req_schema_slash, s_req_schema_slash_slash, s_req_server_start,
  s_req_server, s_req_server_with_at, s_req_path, s_req_query_string_start,
  s_req_query_string, s_req_fragment_start, s_req_fragment, s_req_http_start,
  s_req_http_H, s_req_http_HT, s_req_http_HTT, s_req_http_HTTP,
  s_req_http_major, s_req_http_dot, s_req_http_minor, s_req_http_end,
  s_req_line_almost_done, s_header_field_start, s_header_field, s_header_value_discard_ws,
  s_header_value_discard_ws_almost_done, s_header_value_discard_lws, s_header_value_start, s_header_value,
  s_header_value_lws, s_header_almost_done, s_chunk_size_start, s_chunk_size,
  s_chunk_parameters, s_chunk_size_almost_done, s_headers_almost_done, s_headers_done,
  s_chunk_data, s_chunk_data_almost_done, s_chunk_data_done, s_body_identity,
  s_body_identity_eof, s_message_done
}
 
enum  header_states {
  h_general = 0, h_C, h_CO, h_CON,
  h_matching_connection, h_matching_proxy_connection, h_matching_content_length, h_matching_transfer_encoding,
  h_matching_upgrade, h_connection, h_content_length, h_transfer_encoding,
  h_upgrade, h_matching_transfer_encoding_chunked, h_matching_connection_token_start, h_matching_connection_keep_alive,
  h_matching_connection_close, h_matching_connection_upgrade, h_matching_connection_token, h_transfer_encoding_chunked,
  h_connection_keep_alive, h_connection_close, h_connection_upgrade
}
 
enum  http_host_state {
  s_http_host_dead = 1, s_http_userinfo_start, s_http_userinfo, s_http_host_start,
  s_http_host_v6_start, s_http_host, s_http_host_v6, s_http_host_v6_end,
  s_http_host_v6_zone_start, s_http_host_v6_zone, s_http_host_port_start, s_http_host_port
}
 

Functions

int http_message_needs_eof (const http_parser *parser)
 
static enum state parse_url_char (enum state s, const char ch)
 
size_t http_parser_execute (http_parser *parser, const http_parser_settings *settings, const char *data, size_t len)
 
int http_should_keep_alive (const http_parser *parser)
 
const char * http_method_str (enum http_method m)
 
void http_parser_init (http_parser *parser, enum http_parser_type t)
 
void http_parser_settings_init (http_parser_settings *settings)
 
const char * http_errno_name (enum http_errno err)
 
const char * http_errno_description (enum http_errno err)
 
static enum http_host_state http_parse_host_char (enum http_host_state s, const char ch)
 
static int http_parse_host (const char *buf, struct http_parser_url *u, int found_at)
 
void http_parser_url_init (struct http_parser_url *u)
 
int http_parser_parse_url (const char *buf, size_t buflen, int is_connect, struct http_parser_url *u)
 
void http_parser_pause (http_parser *parser, int paused)
 
int http_body_is_final (const struct http_parser *parser)
 
unsigned long http_parser_version (void)
 

Variables

static const char * method_strings []
 
static const char tokens [256]
 
static const int8_t unhex [256]
 
static const uint8_t normal_url_char [32]
 
struct {
   const char *   name
 
   const char *   description
 
http_strerror_tab []
 

Macro Definition Documentation

#define ARRAY_SIZE (   a)    (sizeof(a) / sizeof((a)[0]))

Definition at line 60 of file http_parser.c.

#define BIT_AT (   a,
 
)
Value:
(!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \
(1 << ((unsigned int) (i) & 7))))

Definition at line 64 of file http_parser.c.

#define CALLBACK_DATA (   FOR)    CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)

Definition at line 147 of file http_parser.c.

#define CALLBACK_DATA_ (   FOR,
  LEN,
  ER 
)
Value:
do { \
assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \
\
if (FOR##_mark) { \
if (LIKELY(settings->on_##FOR)) { \
parser->state = CURRENT_STATE(); \
if (UNLIKELY(0 != \
settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \
SET_ERRNO(HPE_CB_##FOR); \
} \
UPDATE_STATE(parser->state); \
\
/* We either errored above or got paused; get out */ \
if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \
return (ER); \
} \
} \
FOR##_mark = NULL; \
} \
} while (0)
#define UNLIKELY(X)
Definition: http_parser.c:94
#define LIKELY(X)
Definition: http_parser.c:93
#define CURRENT_STATE()
Definition: http_parser.c:78
#define UPDATE_STATE(V)
Definition: http_parser.c:79
#define HTTP_PARSER_ERRNO(p)
Definition: http_parser.h:304
#define SET_ERRNO(e)
Definition: http_parser.c:73

Definition at line 124 of file http_parser.c.

#define CALLBACK_DATA_NOADVANCE (   FOR)    CALLBACK_DATA_(FOR, p - FOR##_mark, p - data)

Definition at line 151 of file http_parser.c.

#define CALLBACK_NOTIFY (   FOR)    CALLBACK_NOTIFY_(FOR, p - data + 1)

Definition at line 118 of file http_parser.c.

#define CALLBACK_NOTIFY_ (   FOR,
  ER 
)
Value:
do { \
assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \
\
if (LIKELY(settings->on_##FOR)) { \
parser->state = CURRENT_STATE(); \
if (UNLIKELY(0 != settings->on_##FOR(parser))) { \
SET_ERRNO(HPE_CB_##FOR); \
} \
UPDATE_STATE(parser->state); \
\
/* We either errored above or got paused; get out */ \
if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \
return (ER); \
} \
} \
} while (0)
#define UNLIKELY(X)
Definition: http_parser.c:94
#define LIKELY(X)
Definition: http_parser.c:93
#define CURRENT_STATE()
Definition: http_parser.c:78
#define UPDATE_STATE(V)
Definition: http_parser.c:79
#define HTTP_PARSER_ERRNO(p)
Definition: http_parser.h:304
#define SET_ERRNO(e)
Definition: http_parser.c:73

Definition at line 99 of file http_parser.c.

#define CALLBACK_NOTIFY_NOADVANCE (   FOR)    CALLBACK_NOTIFY_(FOR, p - data)

Definition at line 121 of file http_parser.c.

#define CHUNKED   "chunked"

Definition at line 188 of file http_parser.c.

#define CLOSE   "close"

Definition at line 190 of file http_parser.c.

#define CONNECTION   "connection"

Definition at line 184 of file http_parser.c.

#define CONTENT_LENGTH   "content-length"

Definition at line 185 of file http_parser.c.

#define COUNT_HEADER_SIZE (   V)
Value:
do { \
parser->nread += (V); \
if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) { \
goto error; \
} \
} while (0)
#define HTTP_MAX_HEADER_SIZE
Definition: http_parser.h:82
#define UNLIKELY(X)
Definition: http_parser.c:94
#define SET_ERRNO(e)
Definition: http_parser.c:73

Definition at line 173 of file http_parser.c.

#define CR   '\r'

Definition at line 429 of file http_parser.c.

#define CURRENT_STATE ( )    p_state

Definition at line 78 of file http_parser.c.

#define ELEM_AT (   a,
  i,
 
)    ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v))

Definition at line 70 of file http_parser.c.

#define HTTP_STRERROR_GEN (   n,
 
)    { "HPE_" #n, s },

Definition at line 483 of file http_parser.c.

#define IS_ALPHA (   c)    (LOWER(c) >= 'a' && LOWER(c) <= 'z')

Definition at line 432 of file http_parser.c.

#define IS_ALPHANUM (   c)    (IS_ALPHA(c) || IS_NUM(c))

Definition at line 434 of file http_parser.c.

#define IS_HEADER_CHAR (   ch)    (ch == CR || ch == LF || ch == 9 || ((unsigned char)ch > 31 && ch != 127))

Verify that a char is a valid visible (printable) US-ASCII character or x80-FF.

Definition at line 461 of file http_parser.c.

#define IS_HEX (   c)    (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f'))

Definition at line 435 of file http_parser.c.

#define IS_HOST_CHAR (   c)    (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_')

Definition at line 453 of file http_parser.c.

#define IS_MARK (   c)
Value:
((c) == '-' || (c) == '_' || (c) == '.' || \
(c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \
(c) == ')')

Definition at line 436 of file http_parser.c.

#define IS_NUM (   c)    ((c) >= '0' && (c) <= '9')

Definition at line 433 of file http_parser.c.

#define IS_URL_CHAR (   c)    (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80))

Definition at line 451 of file http_parser.c.

#define IS_USERINFO_CHAR (   c)
Value:
(IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \
(c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \
(c) == '$' || (c) == ',')
#define IS_ALPHANUM(c)
Definition: http_parser.c:434
#define IS_MARK(c)
Definition: http_parser.c:436

Definition at line 439 of file http_parser.c.

#define KEEP_ALIVE   "keep-alive"

Definition at line 189 of file http_parser.c.

#define LF   '\n'

Definition at line 430 of file http_parser.c.

#define LIKELY (   X)    (X)

Definition at line 93 of file http_parser.c.

#define LOWER (   c)    (unsigned char)(c | 0x20)

Definition at line 431 of file http_parser.c.

#define MARK (   FOR)
Value:
do { \
if (!FOR##_mark) { \
FOR##_mark = p; \
} \
} while (0)

Definition at line 155 of file http_parser.c.

#define MIN (   a,
 
)    ((a) < (b) ? (a) : (b))

Definition at line 56 of file http_parser.c.

#define NEW_MESSAGE ( )    start_state

Definition at line 478 of file http_parser.c.

#define PARSING_HEADER (   state)    (state <= s_headers_done)

Definition at line 379 of file http_parser.c.

#define PROXY_CONNECTION   "proxy-connection"

Definition at line 183 of file http_parser.c.

#define REEXECUTE ( )    goto reexecute; \

Definition at line 85 of file http_parser.c.

#define RETURN (   V)
Value:
do { \
parser->state = CURRENT_STATE(); \
return (V); \
} while (0);
#define CURRENT_STATE()
Definition: http_parser.c:78

Definition at line 80 of file http_parser.c.

#define SET_ERRNO (   e)
Value:
do { \
parser->http_errno = (e); \
} while(0)

Definition at line 73 of file http_parser.c.

#define start_state   (parser->type == HTTP_REQUEST ? s_start_req : s_start_res)

Definition at line 464 of file http_parser.c.

#define STRICT_CHECK (   cond)

Definition at line 477 of file http_parser.c.

#define STRICT_TOKEN (   c)    (tokens[(unsigned char)c])

Definition at line 443 of file http_parser.c.

#define T (   v)    v

Definition at line 258 of file http_parser.c.

#define TOKEN (   c)    ((c == ' ') ? ' ' : tokens[(unsigned char)c])

Definition at line 450 of file http_parser.c.

#define TRANSFER_ENCODING   "transfer-encoding"

Definition at line 186 of file http_parser.c.

#define ULLONG_MAX   ((uint64_t) -1) /* 2^64-1 */

Definition at line 52 of file http_parser.c.

#define UNLIKELY (   X)    (X)

Definition at line 94 of file http_parser.c.

#define UPDATE_STATE (   V)    p_state = (enum state) (V);

Definition at line 79 of file http_parser.c.

#define UPGRADE   "upgrade"

Definition at line 187 of file http_parser.c.

#define XX (   num,
  name,
  string 
)    #string,
#define XX (   meth,
  pos,
  ch,
  new_meth 
)
Value:
case (HTTP_##meth << 16 | pos << 8 | ch): \
parser->method = HTTP_##new_meth; break;

Enumeration Type Documentation

Enumerator
h_general 
h_C 
h_CO 
h_CON 
h_matching_connection 
h_matching_proxy_connection 
h_matching_content_length 
h_matching_transfer_encoding 
h_matching_upgrade 
h_connection 
h_content_length 
h_transfer_encoding 
h_upgrade 
h_matching_transfer_encoding_chunked 
h_matching_connection_token_start 
h_matching_connection_keep_alive 
h_matching_connection_close 
h_matching_connection_upgrade 
h_matching_connection_token 
h_transfer_encoding_chunked 
h_connection_keep_alive 
h_connection_close 
h_connection_upgrade 

Definition at line 382 of file http_parser.c.

Enumerator
s_http_host_dead 
s_http_userinfo_start 
s_http_userinfo 
s_http_host_start 
s_http_host_v6_start 
s_http_host 
s_http_host_v6 
s_http_host_v6_end 
s_http_host_v6_zone_start 
s_http_host_v6_zone 
s_http_host_port_start 
s_http_host_port 

Definition at line 412 of file http_parser.c.

enum state
Enumerator
s_dead 
s_start_req_or_res 
s_res_or_resp_H 
s_start_res 
s_res_H 
s_res_HT 
s_res_HTT 
s_res_HTTP 
s_res_http_major 
s_res_http_dot 
s_res_http_minor 
s_res_http_end 
s_res_first_status_code 
s_res_status_code 
s_res_status_start 
s_res_status 
s_res_line_almost_done 
s_start_req 
s_req_method 
s_req_spaces_before_url 
s_req_schema 
s_req_schema_slash 
s_req_schema_slash_slash 
s_req_server_start 
s_req_server 
s_req_server_with_at 
s_req_path 
s_req_query_string_start 
s_req_query_string 
s_req_fragment_start 
s_req_fragment 
s_req_http_start 
s_req_http_H 
s_req_http_HT 
s_req_http_HTT 
s_req_http_HTTP 
s_req_http_major 
s_req_http_dot 
s_req_http_minor 
s_req_http_end 
s_req_line_almost_done 
s_header_field_start 
s_header_field 
s_header_value_discard_ws 
s_header_value_discard_ws_almost_done 
s_header_value_discard_lws 
s_header_value_start 
s_header_value 
s_header_value_lws 
s_header_almost_done 
s_chunk_size_start 
s_chunk_size 
s_chunk_parameters 
s_chunk_size_almost_done 
s_headers_almost_done 
s_headers_done 
s_chunk_data 
s_chunk_data_almost_done 
s_chunk_data_done 
s_body_identity 
s_body_identity_eof 
s_message_done 

Definition at line 298 of file http_parser.c.

Function Documentation

int http_body_is_final ( const struct http_parser parser)

Definition at line 2421 of file http_parser.c.

const char* http_errno_description ( enum http_errno  err)

Definition at line 2128 of file http_parser.c.

const char* http_errno_name ( enum http_errno  err)

Definition at line 2122 of file http_parser.c.

int http_message_needs_eof ( const http_parser parser)

Definition at line 2056 of file http_parser.c.

const char* http_method_str ( enum http_method  m)

Definition at line 2098 of file http_parser.c.

static int http_parse_host ( const char *  buf,
struct http_parser_url u,
int  found_at 
)
static

Definition at line 2216 of file http_parser.c.

static enum http_host_state http_parse_host_char ( enum http_host_state  s,
const char  ch 
)
static

Definition at line 2134 of file http_parser.c.

size_t http_parser_execute ( http_parser parser,
const http_parser_settings settings,
const char *  data,
size_t  len 
)

Definition at line 653 of file http_parser.c.

void http_parser_init ( http_parser parser,
enum http_parser_type  t 
)

Definition at line 2105 of file http_parser.c.

int http_parser_parse_url ( const char *  buf,
size_t  buflen,
int  is_connect,
struct http_parser_url u 
)

Definition at line 2303 of file http_parser.c.

void http_parser_pause ( http_parser parser,
int  paused 
)

Definition at line 2407 of file http_parser.c.

void http_parser_settings_init ( http_parser_settings settings)

Definition at line 2116 of file http_parser.c.

void http_parser_url_init ( struct http_parser_url u)

Definition at line 2298 of file http_parser.c.

unsigned long http_parser_version ( void  )

Definition at line 2426 of file http_parser.c.

int http_should_keep_alive ( const http_parser parser)

Definition at line 2079 of file http_parser.c.

static enum state parse_url_char ( enum state  s,
const char  ch 
)
static

Definition at line 506 of file http_parser.c.

Variable Documentation

const char* description

Definition at line 486 of file http_parser.c.

struct { ... } http_strerror_tab[]
Initial value:
= {
}
const char* method_strings[]
static
Initial value:
=
{
#define XX(num, name, string)
}

Definition at line 193 of file http_parser.c.

const char* name

Definition at line 485 of file http_parser.c.

const uint8_t normal_url_char[32]
static

Definition at line 262 of file http_parser.c.

const char tokens[256]
static

Definition at line 208 of file http_parser.c.

const int8_t unhex[256]
static
Initial value:
=
{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1
,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
}

Definition at line 243 of file http_parser.c.