HTTP Parser and message builder / objects in plain C Snapshot
Classes | Typedefs | Functions
HTTP_RESPONSE_PARSER

parser of http responses More...

Classes

struct  tagHTTP_RESPONSE_PARSER

Typedefs

typedef struct
tagHTTP_RESPONSE_PARSER 
HTTP_RESPONSE_PARSER

Functions

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 *data)
 parse a http response

Detailed Description

parser of http responses


Typedef Documentation


Function Documentation

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

Definition at line 822 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_general_header( &parser->base ) ) {
    return -1;
  }
  return 0;
}
PARSER_STATUS HTTP_RESPONSE_PARSER_process ( HTTP_RESPONSE_PARSER parser,
HTTP_RESPONSE response,
BF *  data 
)

parse a http response

Returns:
0 - done parsing, 1 need more data, -1 error occured.

Definition at line 845 of file http.c.

{
  int rt, eof_header;

  while(1) {
   switch( parser->base.state ) {
    case HTTP_STATE_PARSING_REQUEST_LINE:
      rt = parse_response_line( response, bf );
      if (rt != 0) {
        goto resp_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 *) response, bf, &eof_header );
      if (rt != 0) {
       goto resp_do_return; 
      }

      if (eof_header) {
          // eof parsing http header.
          parser->ev_header( response, parser->ctx ); 
        
          if (response->base.flags & HTTP_MESSAGE_FLAG_TRANSFER_CHUNKED) {
             parser->base.state = HTTP_STATE_PARSING_BODY_CHUNK_HEADER;
             continue;  
          }

 
          if (response->base.flags & HTTP_MESSAGE_FLAG_HAS_CONTENT_LENGTH) {
             HTTP_PARSER_content_length_init( &parser->base, &response->base );
             continue;  
          }

next_response:
          HTTP_RESPONSE_free( response );
          parser->ev_finish( response, parser->ctx ); 
          parser->base.state = HTTP_STATE_PARSING_REQUEST_LINE; 
          BF_compact(bf);
          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, 
                &response->base, parser->ctx);
      if (rt != 0) {
        goto resp_do_return; 
      }
      goto next_response;

    default: // remaining states deal with chunks
      rt =  HTTP_PARSER_chunked_data_process( 
                &parser->base, bf, 
                (HTTP_PROCESS_MSG_DATA) parser->ev_body, 
                &response->base, parser->ctx);

      if (rt != 0) {
        goto resp_do_return; 
      }
      goto next_response;
    }
  }
resp_do_return:
  if (rt ==  PARSER_STATUS_NEED_MORE_DATA) {
    BF_compact( bf );
  }
  return rt;
}