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