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; }
/** * call-seq: * parser.finish -> true/false * * Finishes a parser early which could put in a "good" or bad state. * You should call reset after finish it or bad things will happen. */ VALUE HttpParser_finish(VALUE self) { http_parser *http = NULL; DATA_GET(self, http_parser, http); http_parser_finish(http); return http_parser_is_finished(http) ? Qtrue : Qfalse; }
int Request_parse(Request *req, char *buf, size_t nread, size_t *out_nparsed) { assert(req && "NULL pointer error."); *out_nparsed = http_parser_execute(&(req->parser), buf, nread, *out_nparsed); int finished = http_parser_finish(&(req->parser)); return finished; }
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; }
static ngx_int_t ngx_tcp_check_http_parse(ngx_tcp_check_peer_conf_t *peer_conf) { ssize_t n, offset, length; http_parser *hp; ngx_tcp_check_ctx *ctx; ngx_tcp_upstream_srv_conf_t *uscf; uscf = peer_conf->conf; ctx = peer_conf->check_data; hp = ctx->parser; if ((ctx->recv.last - ctx->recv.pos) > 0) { offset = ctx->recv.pos - ctx->recv.start; length = ctx->recv.last - ctx->recv.start; n = http_parser_execute(hp, (signed char *)ctx->recv.start, length, offset); ctx->recv.pos += n; if (http_parser_finish(hp) == -1) { ngx_log_error(NGX_LOG_ERR, ngx_cycle->log, 0, "http parse error with peer: %V, recv data: %s", &peer_conf->peer->name, ctx->recv.start); return NGX_ERROR; } ngx_log_debug2(NGX_LOG_DEBUG_TCP, ngx_cycle->log, 0, "http_parse: hp->status_code_n: %d, conf: %d", hp->status_code_n, uscf->status_alive); if (hp->status_code_n == 0) { return NGX_AGAIN; } else if (hp->status_code_n & uscf->status_alive) { return NGX_OK; } else { return NGX_ERROR; } } else { return NGX_AGAIN; } return NGX_OK; }