|
HTTP Parser and message builder / objects in plain C Snapshot
|
parser of http requests More...
Classes | |
| struct | tagHTTP_REQUEST_PARSER |
Typedefs | |
| typedef struct tagHTTP_REQUEST_PARSER | HTTP_REQUEST_PARSER |
Functions | |
| 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 *data) |
| parse a http request | |
parser of http requests
| typedef struct tagHTTP_REQUEST_PARSER HTTP_REQUEST_PARSER |
| 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
Definition at line 646 of file http.c.
{
parser->ctx = ctx;
parser->ev_header = header_parsed;
parser->ev_body = on_message_body_data;
parser->ev_finish = on_request_finished;
if (HTTP_PARSER_init( &parser->base )) {
return -1;
}
if (init_parsers_request_header( &parser->base ) ||
init_parsers_general_header( &parser->base ) ) {
return -1;
}
return 0;
}
| PARSER_STATUS HTTP_REQUEST_PARSER_process | ( | HTTP_REQUEST_PARSER * | parser, |
| HTTP_REQUEST * | request, | ||
| BF * | data | ||
| ) |
parse a http request
Definition at line 671 of file http.c.
{
int rt, eof_header;
while(1) {
switch( parser->base.state ) {
case HTTP_STATE_PARSING_REQUEST_LINE:
rt = parse_request_line( request, bf );
if (rt != 0) {
goto req_do_return;
}
parser->base.state = HTTP_STATE_PARSING_HEADERS; //
//break; - fall through
case HTTP_STATE_PARSING_HEADERS:
rt = HTTP_parse_header_line( (HTTP_PARSER *) parser, (HTTP_MESSAGE *) request, bf, &eof_header );
if (rt != 0) {
goto req_do_return;
}
if (eof_header) {
#if 0
// this check will we done by web server; if no host header then send back HTTP status 400.
// if http 1.1 then host header is a must. no host header is an error.
if (request->version == HTTP_VERSION_1_1 &&
!request->has_host_header) {
return PARSER_STATUS_ERROR;
}
#endif
// eof parsing http header.
if (parser->ev_header( request, parser->ctx )) {
return PARSER_STATUS_ERROR;
}
BF_compact(bf);
if (request->base.flags & HTTP_MESSAGE_FLAG_TRANSFER_CHUNKED) {
HTTP_PARSER_chunked_data_init( &parser->base );
continue;
}
if (request->base.flags & HTTP_MESSAGE_FLAG_HAS_CONTENT_LENGTH) {
HTTP_PARSER_content_length_init( &parser->base, &request->base );
continue;
}
next_request:
if (parser->ev_finish( request, parser->ctx )) {
return PARSER_STATUS_ERROR;
}
parser->base.state = HTTP_STATE_PARSING_REQUEST_LINE;
HTTP_REQUEST_free(request);
return PARSER_STATUS_COMPLETED;
}
break;
case HTTP_STATE_PARSING_BODY_CONTENT_LENGTH:
rt = HTTP_PARSER_content_length_process(
&parser->base, bf,
(HTTP_PROCESS_MSG_DATA) parser->ev_body,
&request->base, parser->ctx);
if (rt != 0) {
goto req_do_return;
}
goto next_request;
default: // remaining states deal with chunks
rt = HTTP_PARSER_chunked_data_process(
&parser->base, bf,
(HTTP_PROCESS_MSG_DATA) parser->ev_body,
&request->base, parser->ctx);
if (rt != 0) {
goto req_do_return;
}
goto next_request;
}
}
req_do_return:
if (rt == PARSER_STATUS_NEED_MORE_DATA) {
BF_compact( bf );
}
return rt;
}
1.7.4