|
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;
}
1.7.4