class H1P::Parser

Public Class Methods

new(p1) click to toggle source
VALUE Parser_initialize(VALUE self, VALUE io) {
  Parser_t *parser;
  GetParser(self, parser);

  parser->io = io;
  parser->buffer = rb_str_new_literal("");
  parser->headers = Qnil;
  parser->pos = 0;

  // pre-allocate the buffer
  rb_str_modify_expand(parser->buffer, INITIAL_BUFFER_SIZE);

  parser->read_method = detect_read_method(io);
  parser->body_read_mode = BODY_READ_MODE_UNKNOWN;
  parser->body_left = 0;
  return self;
}

Public Instance Methods

complete?() click to toggle source
VALUE Parser_complete_p(VALUE self) {
  Parser_t *parser;
  GetParser(self, parser);

  if (parser->body_read_mode == BODY_READ_MODE_UNKNOWN)
    detect_body_read_mode(parser);

  return parser->request_completed ? Qtrue : Qfalse;
}
parse_headers() click to toggle source
VALUE Parser_parse_headers(VALUE self) {
  struct parser_state state;
  GetParser(self, state.parser);
  state.parser->headers = rb_hash_new();

  buffer_trim(&state);
  int initial_pos = state.parser->pos;
  INIT_PARSER_STATE(&state);
  state.parser->current_request_rx = 0;

  if (!parse_request_line(&state, state.parser->headers)) goto eof;

  int header_count = 0;
  while (1) {
    if (header_count > MAX_HEADER_COUNT) RAISE_BAD_REQUEST("Too many headers");
    switch (parse_header(&state, state.parser->headers)) {
      case -1: goto done; // empty header => end of headers
      case 0: goto eof;
    }
    header_count++;
  }
eof:
  state.parser->headers = Qnil;
done:
  state.parser->body_read_mode = BODY_READ_MODE_UNKNOWN;
  int read_bytes = BUFFER_POS(&state) - initial_pos;

  state.parser->current_request_rx += read_bytes;
  if (state.parser->headers != Qnil)
    rb_hash_aset(state.parser->headers, STR_pseudo_rx, INT2NUM(read_bytes));
  return state.parser->headers;
}
read_body() click to toggle source
VALUE Parser_read_body(VALUE self) {
  return read_body(self, 1, 0);
}
read_body_chunk(p1) click to toggle source
VALUE Parser_read_body_chunk(VALUE self, VALUE buffered_only) {
  return read_body(self, 0, buffered_only == Qtrue);
}