diff --git a/src/script.c b/src/script.c index 9f31cf2..b71e25d 100644 --- a/src/script.c +++ b/src/script.c @@ -3,6 +3,7 @@ #include #include #include "script.h" +#include "http_parser.h" typedef struct { char *name; @@ -177,6 +178,47 @@ void script_done(lua_State *L, stats *latency, stats *requests) { lua_pop(L, 1); } +static int verify_request(http_parser *parser) { + size_t *count = parser->data; + (*count)++; + return 0; +} + +size_t script_verify_request(lua_State *L) { + http_parser_settings settings = { + .on_message_complete = verify_request + }; + http_parser parser; + char *request; + size_t len, count = 0; + + script_request(L, &request, &len); + http_parser_init(&parser, HTTP_REQUEST); + parser.data = &count; + + size_t parsed = http_parser_execute(&parser, &settings, request, len); + + if (parsed != len || count == 0) { + enum http_errno err = HTTP_PARSER_ERRNO(&parser); + const char *desc = http_errno_description(err); + const char *msg = err != HPE_OK ? desc : "incomplete request"; + int line = 1, column = 1; + + for (char *c = request; c < request + parsed; c++) { + column++; + if (*c == '\n') { + column = 1; + line++; + } + } + + fprintf(stderr, "%s at %d:%d\n", msg, line, column); + exit(1); + } + + return count; +} + static stats *checkstats(lua_State *L) { stats **s = luaL_checkudata(L, 1, "wrk.stats"); luaL_argcheck(L, s != NULL, 1, "`stats' expected"); diff --git a/src/script.h b/src/script.h index 72fdaf9..72a3c32 100644 --- a/src/script.h +++ b/src/script.h @@ -15,6 +15,7 @@ typedef struct { lua_State *script_create(char *, char *, char *, char *); void script_headers(lua_State *, char **); +size_t script_verify_request(lua_State *L); void script_init(lua_State *, char *, int, char **); void script_done(lua_State *, stats *, stats *); diff --git a/src/wrk.c b/src/wrk.c index 37cc3d9..bc9613c 100644 --- a/src/wrk.c +++ b/src/wrk.c @@ -142,6 +142,7 @@ int main(int argc, char **argv) { script_init(t->L, cfg.script, argc - optind, &argv[optind]); if (i == 0) { + script_verify_request(t->L); cfg.dynamic = !script_is_static(t->L); if (script_want_response(t->L)) { parser_settings.on_header_field = header_field;