From 8bc5fd1ab5fd369ab8014d94b6c9d4662bfe1a86 Mon Sep 17 00:00:00 2001 From: Vladimir Chebotarev Date: Fri, 23 Aug 2024 05:30:18 +0300 Subject: [PATCH 1/2] Initialized fork and added method `-X` option. --- .gitignore | 2 +- Makefile | 2 +- src/script.c | 4 +++- src/script.h | 2 +- src/wrk.c | 13 ++++++++++--- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.gitignore b/.gitignore index e25de36..3ac4ecb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,2 @@ obj/ -wrk +wrc diff --git a/Makefile b/Makefile index 395b98a..cb13e66 100644 --- a/Makefile +++ b/Makefile @@ -19,7 +19,7 @@ endif SRC := wrk.c net.c ssl.c aprintf.c stats.c script.c units.c \ ae.c zmalloc.c http_parser.c -BIN := wrk +BIN := wrc VER ?= $(shell git describe --tags --always --dirty) ODIR := obj diff --git a/src/script.c b/src/script.c index 68a5d08..613ac7f 100644 --- a/src/script.c +++ b/src/script.c @@ -45,7 +45,7 @@ static const struct luaL_Reg threadlib[] = { { NULL, NULL } }; -lua_State *script_create(char *file, char *url, char **headers) { +lua_State *script_create(char *file, char *url, char *method, char **headers) { lua_State *L = luaL_newstate(); luaL_openlibs(L); (void) luaL_dostring(L, "wrk = require \"wrk\""); @@ -77,6 +77,8 @@ lua_State *script_create(char *file, char *url, char **headers) { set_field(L, 4, "scheme", push_url_part(L, url, &parts, UF_SCHEMA)); set_field(L, 4, "host", push_url_part(L, url, &parts, UF_HOST)); set_field(L, 4, "port", push_url_part(L, url, &parts, UF_PORT)); + lua_pushstring(L, method); + set_field(L, 4, "method", 0); set_fields(L, 4, fields); lua_getfield(L, 4, "headers"); diff --git a/src/script.h b/src/script.h index 1bf820d..98f1aae 100644 --- a/src/script.h +++ b/src/script.h @@ -9,7 +9,7 @@ #include "stats.h" #include "wrk.h" -lua_State *script_create(char *, char *, char **); +lua_State *script_create(char *, char *, char *, char **); bool script_resolve(lua_State *, char *, char *); void script_setup(lua_State *, thread *); diff --git a/src/wrk.c b/src/wrk.c index 51f46f7..00c5a0e 100644 --- a/src/wrk.c +++ b/src/wrk.c @@ -14,6 +14,7 @@ static struct config { bool dynamic; bool latency; char *host; + char *method; char *script; SSL_CTX *ctx; } cfg; @@ -49,6 +50,7 @@ static void usage() { " -t, --threads Number of threads to use \n" " \n" " -s, --script Load Lua script file \n" + " -X, --method HTTP method (default: GET) \n" " -H, --header Add header to request \n" " --latency Print latency statistics \n" " --timeout Socket/request timeout \n" @@ -92,7 +94,7 @@ int main(int argc, char **argv) { statistics.requests = stats_alloc(MAX_THREAD_RATE_S); thread *threads = zcalloc(cfg.threads * sizeof(thread)); - lua_State *L = script_create(cfg.script, url, headers); + lua_State *L = script_create(cfg.script, url, cfg.method, headers); if (!script_resolve(L, host, service)) { char *msg = strerror(errno); fprintf(stderr, "unable to connect to %s:%s %s\n", host, service, msg); @@ -106,7 +108,7 @@ int main(int argc, char **argv) { t->loop = aeCreateEventLoop(10 + cfg.connections * 3); t->connections = cfg.connections / cfg.threads; - t->L = script_create(cfg.script, url, headers); + t->L = script_create(cfg.script, url, cfg.method, headers); script_init(L, t, argc - optind, &argv[optind]); if (i == 0) { @@ -471,6 +473,7 @@ static struct option longopts[] = { { "duration", required_argument, NULL, 'd' }, { "threads", required_argument, NULL, 't' }, { "script", required_argument, NULL, 's' }, + { "method", required_argument, NULL, 'X' }, { "header", required_argument, NULL, 'H' }, { "latency", no_argument, NULL, 'L' }, { "timeout", required_argument, NULL, 'T' }, @@ -488,8 +491,9 @@ static int parse_args(struct config *cfg, char **url, struct http_parser_url *pa cfg->connections = 10; cfg->duration = 10; cfg->timeout = SOCKET_TIMEOUT_MS; + cfg->method = "GET"; - while ((c = getopt_long(argc, argv, "t:c:d:s:H:T:Lrv?", longopts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "t:c:d:s:X:H:T:Lrv?", longopts, NULL)) != -1) { switch (c) { case 't': if (scan_metric(optarg, &cfg->threads)) return -1; @@ -503,6 +507,9 @@ static int parse_args(struct config *cfg, char **url, struct http_parser_url *pa case 's': cfg->script = optarg; break; + case 'X': + cfg->method = optarg; + break; case 'H': *header++ = optarg; break; From c2716df4338b5c145c94060d32e248522913e4d8 Mon Sep 17 00:00:00 2001 From: Vladimir Chebotarev Date: Sat, 31 Aug 2024 01:44:20 +0300 Subject: [PATCH 2/2] Added body `--data` option. --- src/script.c | 4 +++- src/script.h | 2 +- src/wrk.c | 13 ++++++++++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/script.c b/src/script.c index 613ac7f..666fdba 100644 --- a/src/script.c +++ b/src/script.c @@ -45,7 +45,7 @@ static const struct luaL_Reg threadlib[] = { { NULL, NULL } }; -lua_State *script_create(char *file, char *url, char *method, char **headers) { +lua_State *script_create(char *file, char *url, char *method, char *data, char **headers) { lua_State *L = luaL_newstate(); luaL_openlibs(L); (void) luaL_dostring(L, "wrk = require \"wrk\""); @@ -79,6 +79,8 @@ lua_State *script_create(char *file, char *url, char *method, char **headers) { set_field(L, 4, "port", push_url_part(L, url, &parts, UF_PORT)); lua_pushstring(L, method); set_field(L, 4, "method", 0); + lua_pushstring(L, data); + set_field(L, 4, "body", 0); set_fields(L, 4, fields); lua_getfield(L, 4, "headers"); diff --git a/src/script.h b/src/script.h index 98f1aae..edee5c8 100644 --- a/src/script.h +++ b/src/script.h @@ -9,7 +9,7 @@ #include "stats.h" #include "wrk.h" -lua_State *script_create(char *, char *, char *, char **); +lua_State *script_create(char *, char *, char *, char *, char **); bool script_resolve(lua_State *, char *, char *); void script_setup(lua_State *, thread *); diff --git a/src/wrk.c b/src/wrk.c index 00c5a0e..3ad0f0c 100644 --- a/src/wrk.c +++ b/src/wrk.c @@ -15,6 +15,7 @@ static struct config { bool latency; char *host; char *method; + char *data; char *script; SSL_CTX *ctx; } cfg; @@ -52,6 +53,7 @@ static void usage() { " -s, --script Load Lua script file \n" " -X, --method HTTP method (default: GET) \n" " -H, --header Add header to request \n" + " --data Body \n" " --latency Print latency statistics \n" " --timeout Socket/request timeout \n" " -v, --version Print version details \n" @@ -94,7 +96,7 @@ int main(int argc, char **argv) { statistics.requests = stats_alloc(MAX_THREAD_RATE_S); thread *threads = zcalloc(cfg.threads * sizeof(thread)); - lua_State *L = script_create(cfg.script, url, cfg.method, headers); + lua_State *L = script_create(cfg.script, url, cfg.method, cfg.data, headers); if (!script_resolve(L, host, service)) { char *msg = strerror(errno); fprintf(stderr, "unable to connect to %s:%s %s\n", host, service, msg); @@ -108,7 +110,7 @@ int main(int argc, char **argv) { t->loop = aeCreateEventLoop(10 + cfg.connections * 3); t->connections = cfg.connections / cfg.threads; - t->L = script_create(cfg.script, url, cfg.method, headers); + t->L = script_create(cfg.script, url, cfg.method, cfg.data, headers); script_init(L, t, argc - optind, &argv[optind]); if (i == 0) { @@ -475,6 +477,7 @@ static struct option longopts[] = { { "script", required_argument, NULL, 's' }, { "method", required_argument, NULL, 'X' }, { "header", required_argument, NULL, 'H' }, + { "data", required_argument, NULL, 'D' }, { "latency", no_argument, NULL, 'L' }, { "timeout", required_argument, NULL, 'T' }, { "help", no_argument, NULL, 'h' }, @@ -492,8 +495,9 @@ static int parse_args(struct config *cfg, char **url, struct http_parser_url *pa cfg->duration = 10; cfg->timeout = SOCKET_TIMEOUT_MS; cfg->method = "GET"; + cfg->data = ""; - while ((c = getopt_long(argc, argv, "t:c:d:s:X:H:T:Lrv?", longopts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "t:c:d:D:s:X:H:T:Lrv?", longopts, NULL)) != -1) { switch (c) { case 't': if (scan_metric(optarg, &cfg->threads)) return -1; @@ -513,6 +517,9 @@ static int parse_args(struct config *cfg, char **url, struct http_parser_url *pa case 'H': *header++ = optarg; break; + case 'D': + cfg->data = optarg; + break; case 'L': cfg->latency = true; break;