Example #1
0
char *test_parser_thrashing()
{
    glob_t test_files;
    unsigned int i = 0;
    int nparsed = 0;
    int delta = 0;
    int tests_run = 0;
    int execs_run = 0;
    int unfinished = 0;
    int errors = 0;

    int rc = glob("tests/and_suite/*", 0, NULL, &test_files);
    mu_assert(rc == 0, "Failed to glob file sin tests/and_suite/*");

    for(i = 0; i < test_files.gl_pathc; i++) {
        FILE *infile = fopen(test_files.gl_pathv[i], "r");
        mu_assert(infile != NULL, "Failed to open test file.");

        bstring data = bread((bNread)fread, infile);
        fclose(infile);
        mu_assert(data != NULL, "Failed to read test file.");

        tests_run++;

        http_parser p = setup_parser();

        nparsed = 0;
        delta = 0;

        while(nparsed < blength(data)) {
            debug("json PARSING: %d of %d at %s", nparsed, blength(data), bdataofs(data, nparsed));

            delta = http_parser_execute(&p, bdata(data), blength(data), nparsed);
            execs_run++;

            if(delta == 0) { break; }

            if(!http_parser_finish(&p)) {
                unfinished++;
            }

            nparsed += delta;

            if(http_parser_has_error(&p)) {
                errors++;
            }

            debug("TEST %s results: delta %d, has_error: %d, is_finished: %d",
                    test_files.gl_pathv[i],
                    nparsed, http_parser_has_error(&p), http_parser_is_finished(&p));

            http_parser_init(&p);  // reset for the next try
        }
    }

    debug("HTTP PARSING: tests_run: %d, execs_run: %d, unfinished: %d, errors: %d",
            tests_run, execs_run, unfinished, errors);

    return NULL;
}
Example #2
0
/**
 * call-seq:
 *    parser.error? -> true/false
 *
 * Tells you whether the parser is in an error state.
 */
VALUE HttpParser_has_error(VALUE self)
{
  http_parser *http = NULL;
  DATA_GET(self, http_parser, http);

  return http_parser_has_error(http) ? Qtrue : Qfalse;
}
Example #3
0
/**
 * call-seq:
 *    parser.execute(req_hash, data, start) -> Integer
 *
 * Takes a Hash and a String of data, parses the String of data filling in the Hash
 * returning an Integer to indicate how much of the data has been read.  No matter
 * what the return value, you should call HttpParser#finished? and HttpParser#error?
 * to figure out if it's done parsing or there was an error.
 * 
 * This function now throws an exception when there is a parsing error.  This makes 
 * the logic for working with the parser much easier.  You can still test for an 
 * error, but now you need to wrap the parser with an exception handling block.
 *
 * The third argument allows for parsing a partial request and then continuing
 * the parsing from that position.  It needs all of the original data as well 
 * so you have to append to the data buffer as you read.
 */
VALUE HttpParser_execute(VALUE self, VALUE req_hash, VALUE data, VALUE start)
{
  http_parser *http = NULL;
  int from = 0;
  char *dptr = NULL;
  long dlen = 0;

  DATA_GET(self, http_parser, http);

  from = FIX2INT(start);
  dptr = RSTRING_PTR(data);
  dlen = RSTRING_LEN(data);

  if(from >= dlen) {
    rb_raise(eHttpParserError, "Requested start is after data buffer end.");
  } else {
    http->data = (void *)req_hash;
    http_parser_execute(http, dptr, dlen, from);

    VALIDATE_MAX_LENGTH(http_parser_nread(http), HEADER);

    if(http_parser_has_error(http)) {
      rb_raise(eHttpParserError, "Invalid HTTP format, parsing fails.");
    } else {
      return INT2FIX(http_parser_nread(http));
    }
  }
}
Example #4
0
static PyObject *
HttpParserObject_has_error(HttpParserObject* self)
{
    if (http_parser_has_error(self->http)) {
        Py_RETURN_TRUE;
    } else {
        Py_RETURN_FALSE;
    }
}
Example #5
0
char *test_http11_parser_basics() 
{
    http_parser p = setup_parser();
    int rc = 0;

    rc = http_parser_finish(&p);
    mu_assert(rc == 0, "Should NOT be finished if nothing parsed.");

    rc = http_parser_has_error(&p);
    mu_assert(rc == 0, "Should not have an error at the beginning.");

    rc = http_parser_is_finished(&p);
    mu_assert(rc == 0, "Should not be finished since never handed anything.");
    return NULL;
}
Example #6
0
static void
on_read_cb(uv_stream_t *stream, ssize_t nread, uv_buf_t buf)
{
  Connection *conn = (Connection*) stream;

  assert(conn->read_clear == false);

  if (nread < 0) {
    //
    // XXX: Do we have to call uv_read_stop(), or is it implicit?
    //
    // on_read_cb will never be called again for this connection, so we don't
    // have to reset anything.
    //
    uv_close((uv_handle_t*) conn, on_close_cb);
  }
  else if (nread > 0) {
    conn->read_buffer.increase_size(nread);
    conn->read_clear = true;

    if (conn->in_body) {
      // We are reading in the body. No need to call the parser!
      handle_http_body(conn);
    }
    else {
      conn->parse_offset = 
        http_parser_run(&conn->parser, &conn->req, conn->read_buffer.data(), conn->read_buffer.size(), conn->parse_offset);

      if (http_parser_is_finished(&conn->parser)) {
        handle_http_header_parsed(conn);
      }
      else if (http_parser_has_error(&conn->parser)) {
        handle_http_error(conn);
      }
    }
  }
  else {
    //
    // This happens when libuv calls alloc_read_buffer, but does not need the buffer.
    // We don't have to free the buffer, as it is part of the connection.
    //
    assert(nread == 0);
    conn->read_clear = true;
  }
}
Example #7
0
int http_parser_finish(http_parser *parser)
{
    int cs = parser->cs;
    
    
#line 1202 "http11_parser.c"
#line 134 "http11_parser.rl"
    
    parser->cs = cs;
    
    if (http_parser_has_error(parser) ) {
        return -1;
    } else if (http_parser_is_finished(parser) ) {
        return 1;
    } else {
        return 0;
    }
}
Example #8
0
int HTTPParser_parseErrorOccured(HTTPParser *self)
{
	return http_parser_has_error(self->parser);
}