HTTP Parser and message builder / objects in plain C Snapshot
|
Go to the source code of this file.
Classes | |
struct | tagHEADER_HASH_ACTION |
Defines | |
#define | S_METHOD_GET "GET" |
#define | S_METHOD_GET_LEN 3 |
#define | S_METHOD_POST "POST" |
#define | S_METHOD_POST_LEN 4 |
#define | S_METHOD_PUT "PUT" |
#define | S_METHOD_PUT_LEN 3 |
#define | S_METHOD_DELETE "DELETE" |
#define | S_METHOD_DELETE_LEN 6 |
#define | S_METHOD_HEAD "HEAD" |
#define | S_METHOD_HEAD_LEN 4 |
#define | S_METHOD_OPTIONS "OPTIONS" |
#define | S_METHOD_OPTIONS_LEN 7 |
#define | S_METHOD_TRACE "TRACE" |
#define | S_METHOD_TRACE_LEN 5 |
#define | S_METHOD_CONNECT "CONNECT" |
#define | S_METHOD_CONNECT_LEN 7 |
#define | HTTP_START_S "HTTP/1." |
#define | HTTP_START_S_LEN 7 |
#define | HTTP_EOF_LINE "\r\n" |
#define | HTTP_EOF_LINE_LEN 2 |
#define | to_lower(pos) |
#define | MAX_HTTP_TOKEN_SIZE 120 |
#define | S_CONNECTION_CLOSE "Connection: close\r\n" |
#define | S_CONNECTION_CLOSE_LEN 19 |
#define | S_TRANSFER_CHUNKED "Transfer-encoding: chunked\r\n" |
#define | S_TRANSFER_CHUNKED_LEN 28 |
#define | RETURN_WRITER_MORE_DATA |
Typedefs | |
typedef struct tagHEADER_HASH_ACTION | HEADER_HASH_ACTION |
Functions | |
int | init_parsers_request_header (HTTP_PARSER *parser) |
int | init_parsers_general_header (HTTP_PARSER *parser) |
M_INLINE int | http_is_ctl (char ch) |
M_INLINE int | http_is_ctl_or_space (char ch) |
M_INLINE int | http_is_space (char ch) |
M_INLINE int | http_is_separator (char ch) |
static void | free_stringpair (DLISTUNR *list, void *entry, void *context) |
int | HTTP_MESSAGE_init (HTTP_MESSAGE *message) |
void | HTTP_MESSAGE_free (HTTP_MESSAGE *message) |
int | HTTP_MESSAGE_add_header (HTTP_MESSAGE *message, const char *name, const char *value) |
const char * | HTTP_MESSAGE_find_header (HTTP_MESSAGE *message, const char *name) |
STRINGPAIR * | HTTP_MESSAGE_first_header (HTTP_MESSAGE *message, DLISTUNR_position *pos) |
STRINGPAIR * | HTTP_MESSAGE_next_header (HTTP_MESSAGE *message, DLISTUNR_position *pos) |
static int | hash_compare (HASH_Entry *entry, void *key, ssize_t key_length) |
int | HTTP_PARSER_init (HTTP_PARSER *parser) |
int | HTTP_PARSER_free (HTTP_PARSER *parser) |
int | HTTP_add_header_parser (HTTP_PARSER *parser, const char *header_name, HEADER_ACTION action_func) |
add a parser for a specific http header type | |
PARSER_STATUS | HTTP_get_line (BF *bf, char **start_line) |
returns next raw line from http header, adjoins line continuations. | |
int | HTTP_get_header_token (HTTP_PARSER *parser) |
return next token while parsing http header value. | |
PARSER_STATUS | HTTP_parse_header_line (HTTP_PARSER *parser, HTTP_MESSAGE *request, BF *bf, int *eof_header) |
dispatch parsing of one http header | |
int | HTTP_PARSER_content_length_init (HTTP_PARSER *parser, HTTP_MESSAGE *msg) |
start parsing content length message body | |
int | HTTP_PARSER_content_length_process (HTTP_PARSER *parser, BF *bf, HTTP_PROCESS_MSG_DATA cb, HTTP_MESSAGE *msg, void *ctx) |
consume content length message body. | |
int | HTTP_PARSER_chunked_data_init (HTTP_PARSER *parser) |
start parsing chunked data | |
PARSER_STATUS | HTTP_PARSER_chunked_data_process (HTTP_PARSER *parser, BF *bf, HTTP_PROCESS_MSG_DATA cb, HTTP_MESSAGE *msg, void *ctx) |
finish parsind chunked content data. | |
static PARSER_STATUS | parse_request_line (HTTP_REQUEST *request, BF *bf) |
int | HTTP_REQUEST_PARSER_init (HTTP_REQUEST_PARSER *parser, HTTP_REQ_HEADER_PARSED header_parsed, HTTP_REQ_MESSAGE_BODY_DATA on_message_body_data, HTTP_REQ_FINISHED on_request_finished, void *ctx) |
initialise request parser object | |
PARSER_STATUS | HTTP_REQUEST_PARSER_process (HTTP_REQUEST_PARSER *parser, HTTP_REQUEST *request, BF *bf) |
parse a http request | |
int | HTTP_REQUEST_is_persistent (HTTP_REQUEST *message) |
static PARSER_STATUS | parse_response_line (HTTP_RESPONSE *response, BF *bf) |
int | HTTP_RESPONSE_PARSER_init (HTTP_RESPONSE_PARSER *parser, HTTP_RESP_HEADER_PARSED header_parsed, HTTP_RESP_MESSAGE_BODY_DATA on_message_body_data, HTTP_RESP_FINISHED on_request_finished, void *ctx) |
initialise request parser object | |
PARSER_STATUS | HTTP_RESPONSE_PARSER_process (HTTP_RESPONSE_PARSER *parser, HTTP_RESPONSE *response, BF *bf) |
parse a http response | |
static const char * | http_version_to_str (Http_version_type ver) |
static const char * | get_reason_phrase (int code) |
PARSER_STATUS | HTTP_RESPONSE_WRITER_write (HTTP_RESPONSE_WRITER *writer, BF *bf) |
#define RETURN_WRITER_MORE_DATA |
if (bf->start == bf->put_pos) { \ return PARSER_STATUS_ERROR; /* the buffer can't hold a single value */ \ } \ return PARSER_STATUS_NEED_MORE_DATA;
#define to_lower | ( | pos | ) |
if (is_upper_case( *pos )) { \ *pos = *pos - 'A' + 'a'; \ }
typedef struct tagHEADER_HASH_ACTION HEADER_HASH_ACTION |
static void free_stringpair | ( | DLISTUNR * | list, |
void * | entry, | ||
void * | context | ||
) | [static] |
Definition at line 73 of file http.c.
{ STRINGPAIR *pair = (STRINGPAIR *) entry; M_UNUSED(list); M_UNUSED(context); free( pair->key ); free( pair->value ); }
static const char* get_reason_phrase | ( | int | code | ) | [static] |
Definition at line 945 of file http.c.
{ switch( code ) { case 100: return "Continue"; case 101: return "Switching Protocols"; case 200: return "OK"; case 201: return "Created"; case 202: return "Accepted"; case 203: return "Non-Authoritative Information"; case 204: return "No Content"; case 205: return "Reset Content"; case 206: return "Partial Content"; case 300: return "Multiple Choices"; case 301: return "Moved Permanently"; case 302: return "Found"; case 303: return "See Other"; case 304: return "Not Modified"; case 305: return "Use Proxy"; case 307: return "Temporary Redirect"; case 400: return "Bad Request"; case 401: return "Unauthorized"; case 402: return "Payment Required"; case 403: return "Forbidden"; case 404: return "Not Found"; case 405: return "Method Not Allowed"; case 406: return "Not Acceptable"; case 407: return "Proxy Authentication Required"; case 408: return "Request Time-out"; case 409: return "Conflict"; case 410: return "Gone"; case 411: return "Length Required"; case 412: return "Precondition Failed"; case 413: return "Request Entity Too Large"; case 414: return "Request-URI Too Large"; case 415: return "Unsupported Media Type"; case 416: return "Requested range not satisfiable"; case 417: return "Expectation Failed"; case 500: return "Internal Server Error"; case 501: return "Not Implemented"; case 502: return "Bad Gateway"; case 503: return "Service Unavailable"; case 504: return "Gateway Time-out"; case 505: return "HTTP Version not supported"; } return ""; }
static int hash_compare | ( | HASH_Entry * | entry, |
void * | key, | ||
ssize_t | key_length | ||
) | [static] |
Definition at line 156 of file http.c.
{ HEADER_HASH_ACTION *lhs; lhs = (HEADER_HASH_ACTION *) entry; return strncmp(lhs->key, key, key_length); }
M_INLINE int http_is_ctl | ( | char | ch | ) |
M_INLINE int http_is_ctl_or_space | ( | char | ch | ) |
M_INLINE int http_is_separator | ( | char | ch | ) |
M_INLINE int http_is_space | ( | char | ch | ) |
static const char* http_version_to_str | ( | Http_version_type | ver | ) | [static] |
Definition at line 921 of file http.c.
{ switch(ver) { case HTTP_VERSION_1_0: return "1.0"; case HTTP_VERSION_1_1: return "1.1"; } return ""; }
int init_parsers_general_header | ( | HTTP_PARSER * | parser | ) |
Definition at line 113 of file hparse.c.
{ if (HTTP_add_header_parser( parser, "content-length", parser_content_length_header) || HTTP_add_header_parser( parser, "connection", parser_connection_header) || HTTP_add_header_parser( parser, "transfer-encoding", parser_transfer_encoding_header) ) { return -1; } return 0; }
int init_parsers_request_header | ( | HTTP_PARSER * | parser | ) |
Definition at line 123 of file hparse.c.
{ if (HTTP_add_header_parser( parser, "expect", parser_expect_header) || HTTP_add_header_parser( parser, "host", parser_host_header) ) { return -1; } return 0; }
static PARSER_STATUS parse_request_line | ( | HTTP_REQUEST * | request, |
BF * | bf | ||
) | [static] |
Definition at line 544 of file http.c.
{ Http_method_type method; char *eof,*tok, *line; PARSER_STATUS rt; rt = HTTP_get_line( bf, &line ); if (rt != PARSER_STATUS_COMPLETED) { return rt; } switch( *line ) { case 'G': if (strncmp( line, S_METHOD_GET, S_METHOD_GET_LEN ) != 0) { return PARSER_STATUS_ERROR; } method = HTTP_METHOD_GET; line += S_METHOD_GET_LEN; break; case 'P': if (strncmp( line, S_METHOD_POST, S_METHOD_POST_LEN ) == 0) { method = HTTP_METHOD_POST; line += S_METHOD_POST_LEN; } else if (strncmp( line, S_METHOD_PUT, S_METHOD_PUT_LEN ) == 0) { method = HTTP_METHOD_PUT; line += S_METHOD_PUT_LEN; } else { return PARSER_STATUS_ERROR; } break; case 'H': if (strncmp( line, S_METHOD_HEAD, S_METHOD_HEAD_LEN ) != 0) { return PARSER_STATUS_ERROR; } method = HTTP_METHOD_HEAD; line += S_METHOD_HEAD_LEN ; break; case 'D': if (strncmp( line, S_METHOD_DELETE, S_METHOD_DELETE_LEN ) != 0) { return PARSER_STATUS_ERROR; } method = HTTP_METHOD_DELETE; line += S_METHOD_DELETE_LEN ; break; case 'T': if (strncmp( line, S_METHOD_TRACE, S_METHOD_TRACE_LEN ) != 0) { return PARSER_STATUS_ERROR; } method = HTTP_METHOD_TRACE; line += S_METHOD_TRACE_LEN ; break; case 'C': if (strncmp( line, S_METHOD_CONNECT, S_METHOD_CONNECT_LEN ) != 0) { return PARSER_STATUS_ERROR; } method = HTTP_METHOD_CONNECT; line += S_METHOD_CONNECT_LEN; break; default: return -1; } request->method = method; tok = get_token( line, &eof ); if (!tok) { return PARSER_STATUS_ERROR; } *eof = 0; request->raw_url = strdup( tok ); if (method != HTTP_METHOD_CONNECT) { if (URI_parse( &request->url, tok )) { return PARSER_STATUS_ERROR; } } else { if (strcmp(tok, "*") != 0) { return PARSER_STATUS_ERROR; } URI_init( &request->url ); } tok = get_token( eof+1, &eof ); if (strncmp( tok, HTTP_START_S, HTTP_START_S_LEN ) != 0) { return PARSER_STATUS_ERROR; } tok += HTTP_START_S_LEN; switch(tok[0]) { case '0': request->version = HTTP_VERSION_1_0; break; case '1': request->version = HTTP_VERSION_1_1; break; default: return PARSER_STATUS_ERROR; } return PARSER_STATUS_COMPLETED; }
static PARSER_STATUS parse_response_line | ( | HTTP_RESPONSE * | response, |
BF * | bf | ||
) | [static] |
Definition at line 779 of file http.c.
{ PARSER_STATUS rt; char *line, *tok, *eof; int st; rt = HTTP_get_line( bf, &line ); if (rt != PARSER_STATUS_COMPLETED) { return rt; } tok = line; if (strncmp( tok, HTTP_START_S, HTTP_START_S_LEN ) != 0) { return PARSER_STATUS_ERROR; } tok += HTTP_START_S_LEN; switch(tok[0]) { case '0': response->version = HTTP_VERSION_1_0; break; case '1': response->version = HTTP_VERSION_1_1; break; default: return PARSER_STATUS_ERROR; } tok = get_token( line, &eof ); if (!tok) { return PARSER_STATUS_ERROR; } st = atoi( tok ); if (st < 100 || st >= 600) { return PARSER_STATUS_ERROR; } response->status_code = st; return PARSER_STATUS_COMPLETED; }