ext/iodine/http1_parser.h
/**
 * Returns the amount of data actually consumed by the parser.
 *
 * The value 0 indicates there wasn't enough data to be parsed and the same
 * buffer (with more data) should be resubmitted.
 *
 * A value smaller than the buffer size indicates that EITHER a request /
 * response was detected OR that the leftover could not be consumed because more
 * data was required.
 *
 * Simply resubmit the reminder of the data to continue parsing.
 *
 * A request / response callback automatically stops the parsing process,
 * allowing the user to adjust or refresh the state of the data.
 */
Returns the amount of data actually consumed by the parser.
The value 0 indicates there wasn't enough data to be parsed and the same
buffer (with more data) should be resubmitted.

A value smaller than the buffer size indicates that EITHER a request
response was detected OR that the leftover could not be consumed because more
data was required.

Simply resubmit the reminder of the data to continue parsing.

A request / response callback automatically stops the parsing process,
allowing the user to adjust or refresh the state of the data.
Returns the amount of data actually consumed by the parser . The value 0 indicates there wasn ' t enough data to be parsed and the same buffer ( with more data ) should be resubmitted . A value smaller than the buffer size indicates that EITHER a request response was detected OR that the leftover could not be consumed because more data was required . Simply resubmit the reminder of the data to continue parsing . A request / response callback automatically stops the parsing process allowing the user to adjust or refresh the state of the data .
static size_t http1_parse(http1_parser_s *parser, void *buffer, size_t length) {
  if (!length)
    return 0;
  HTTP1_ASSERT(parser && buffer);
  parser->state.next = NULL;
  uint8_t *start = (uint8_t *)buffer;
  uint8_t *end = start;
  uint8_t *const stop = start + length;
  uint8_t eol_len = 0;
#define HTTP1_CONSUMED ((size_t)((uintptr_t)start - (uintptr_t)buffer))
re_eval:
  switch ((parser->state.reserved & 7)) {
  case 0: 
    while ((start < stop) &&
           (*start == '\r' || *start == '\n' || *start == ' ' || *start == 0)) {
      ++start;
    }
    end = start;
    if (!(eol_len = seek2eol(&end, stop)))
      return HTTP1_CONSUMED;
    if (start[0] == 'H' && start[1] == 'T' && start[2] == 'T' &&
        start[3] == 'P') {
      if (http1_consume_response_line(parser, start, end - eol_len + 1))
        goto error;
    } else if (http_tolower(start[0]) >= 'a' && http_tolower(start[0]) <= 'z') {
      if (http1_consume_request_line(parser, start, end - eol_len + 1))
        goto error;
    } else
      goto error;
    end = start = end + 1;
    parser->state.reserved |= HTTP1_P_FLAG_STATUS_LINE;
  case 1: 
    do {
      if (start >= stop)
        return HTTP1_CONSUMED; 
      if (*start == '\r' || *start == '\n') {
        goto finished_headers; 
      }
      end = start;
      if (!(eol_len = seek2eol(&end, stop)))
        return HTTP1_CONSUMED;
      if (http1_consume_header(parser, start, end - eol_len + 1))
        goto error;
      end = start = end + 1;
    } while ((parser->state.reserved & HTTP1_P_FLAG_HEADER_COMPLETE) == 0);
  finished_headers:
    ++start;
    if (*start == '\n')
      ++start;
    end = start;
    parser->state.reserved |= HTTP1_P_FLAG_HEADER_COMPLETE;
  case (HTTP1_P_FLAG_HEADER_COMPLETE | HTTP1_P_FLAG_STATUS_LINE):
    {
      int t3 = http1_consume_body(parser, buffer, length, &start);
      switch (t3) {
      case -1:
        goto error;
      case -2:
        goto re_eval;
      }
      break;
    }
  }
  if (parser->state.reserved & HTTP1_P_FLAG_COMPLETE) {
    parser->state.next = start;
    if (((parser->state.reserved & HTTP1_P_FLAG_RESPONSE)
             ? http1_on_response
             : http1_on_request)(parser))
      goto error;
    parser->state = (struct http1_parser_protected_read_only_state_s){0};
  }
  return HTTP1_CONSUMED;
error:
  http1_on_error(parser);
  parser->state = (struct http1_parser_protected_read_only_state_s){0};
  return length;
#undef HTTP1_CONSUMED
}
static size_t http1_parse ( http1_parser_s * parser , void * buffer , size_t length ) { if ( ! length ) return 0 ; HTTP1_ASSERT ( parser && buffer ) ; parser -> state . next = NULL ; uint8_t * start = ( uint8_t * ) buffer ; uint8_t * end = start ; uint8_t * const stop = start + length ; uint8_t eol_len = 0 ; #define HTTP1_CONSUMED  ((size_t)((uintptr_t)start - (uintptr_t)buffer)) re_eval : switch ( ( parser -> state . reserved & 7 ) ) { case 0 : while ( ( start < stop ) && ( * start == ' \r ' || * start == ' \n ' || * start == ' ' || * start == 0 ) ) { ++ start ; } end = start ; if ( ! ( eol_len = seek2eol ( & end , stop ) ) ) return HTTP1_CONSUMED ; if ( start [ 0 ] == ' ' && start [ 1 ] == ' ' && start [ 2 ] == ' ' && start [ 3 ] == ' ' ) { if ( http1_consume_response_line ( parser , start , end - eol_len + 1 ) ) goto error ; } else if ( http_tolower ( start [ 0 ] ) >= ' ' && http_tolower ( start [ 0 ] ) <= ' ' ) { if ( http1_consume_request_line ( parser , start , end - eol_len + 1 ) ) goto error ; } else goto error ; end = start = end + 1 ; parser -> state . reserved |= HTTP1_P_FLAG_STATUS_LINE ; case 1 : do { if ( start >= stop ) return HTTP1_CONSUMED ; if ( * start == ' \r ' || * start == ' \n ' ) { goto finished_headers ; } end = start ; if ( ! ( eol_len = seek2eol ( & end , stop ) ) ) return HTTP1_CONSUMED ; if ( http1_consume_header ( parser , start , end - eol_len + 1 ) ) goto error ; end = start = end + 1 ; } while ( ( parser -> state . reserved & HTTP1_P_FLAG_HEADER_COMPLETE ) == 0 ) ; finished_headers : ++ start ; if ( * start == ' \n ' ) ++ start ; end = start ; parser -> state . reserved |= HTTP1_P_FLAG_HEADER_COMPLETE ; case ( HTTP1_P_FLAG_HEADER_COMPLETE | HTTP1_P_FLAG_STATUS_LINE ) : { int t3 = http1_consume_body ( parser , buffer , length , & start ) ; switch ( t3 ) { case -1 : goto error ; case -2 : goto re_eval ; } break ; } } if ( parser -> state . reserved & HTTP1_P_FLAG_COMPLETE ) { parser -> state . next = start ; if ( ( ( parser -> state . reserved & HTTP1_P_FLAG_RESPONSE ) ? http1_on_response : http1_on_request ) ( parser ) ) goto error ; parser -> state = ( struct http1_parser_protected_read_only_state_s ) { 0 } ; } return HTTP1_CONSUMED ; error : http1_on_error ( parser ) ; parser -> state = ( struct http1_parser_protected_read_only_state_s ) { 0 } ; return length ; #undef  HTTP1_CONSUMED }
Returns the amount of data actually consumed by the parser.
Returns the amount of data actually consumed by the parser .
/* request / response line */ /* clear out any leading white space */ /* make sure the whole line is available*/ /* HTTP response */ /* HTTP request */ /* fallthrough */ /* headers */ /* buffer ended on header line */ /* empty line, end of headers */ /* fallthrough */ /* request body */ /* are we done ? */