From 1b7161cf0e45e5f23b599a8e76e4513ca353fa70 Mon Sep 17 00:00:00 2001 From: Will Date: Fri, 24 May 2013 12:00:12 +0900 Subject: [PATCH] support setting request method & body --- README | 18 +++++++++--------- src/wrk.c | 46 +++++++++++++++++++++++++++++++++------------- src/wrk.h | 2 +- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/README b/README index ed6fb89..0900901 100644 --- a/README +++ b/README @@ -6,21 +6,21 @@ wrk - a HTTP benchmarking tool Basic Usage - wrk -t8 -c400 -d30 http://localhost:8080/index.html + wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html - This runs a benchmark for 30 seconds, using 8 threads, and keeping + This runs a benchmark for 30 seconds, using 12 threads, and keeping 400 HTTP connections open. Output: - Running 30s test @ http://localhost:8080/index.html - 8 threads and 400 connections + Running 30s test @ http://127.0.0.1:8080/index.html + 12 threads and 400 connections Thread Stats Avg Stdev Max +/- Stdev - Latency 439.75us 350.49us 7.60ms 92.88% - Req/Sec 61.13k 8.26k 72.00k 87.54% - 10000088 requests in 19.87s, 3.42GB read - Requests/sec: 503396.23 - Transfer/sec: 176.16MB + Latency 635.91us 0.89ms 12.92ms 93.69% + Req/Sec 56.20k 8.07k 62.00k 86.54% + 22464657 requests in 30.00s, 17.76GB read + Requests/sec: 748868.53 + Transfer/sec: 606.33MB Benchmarking Tips diff --git a/src/wrk.c b/src/wrk.c index 578ad0c..26c405b 100644 --- a/src/wrk.c +++ b/src/wrk.c @@ -38,9 +38,11 @@ static struct config { } cfg; static struct { + char *method; + char *body; size_t size; char *buf; -} request; +} req; static struct { stats *latency; @@ -66,6 +68,8 @@ static void usage() { " -t, --threads Number of threads to use \n" " \n" " -H, --header Add header to request \n" + " -M, --method HTTP method \n" + " --body Request body \n" " --latency Print latency statistics \n" " --timeout Socket/request timeout \n" " -v, --version Print version details \n" @@ -128,9 +132,9 @@ int main(int argc, char **argv) { signal(SIGPIPE, SIG_IGN); signal(SIGINT, SIG_IGN); - cfg.addr = *addr; - request.buf = format_request(host, port, path, headers); - request.size = strlen(request.buf); + cfg.addr = *addr; + req.buf = format_request(host, port, path, headers); + req.size = strlen(req.buf); pthread_mutex_init(&statistics.mutex, NULL); statistics.latency = stats_alloc(SAMPLES); @@ -351,7 +355,7 @@ static int check_timeouts(aeEventLoop *loop, long long id, void *data) { static void socket_writeable(aeEventLoop *loop, int fd, void *data, int mask) { connection *c = data; - if (write(fd, request.buf, request.size) < request.size) goto error; + if (write(fd, req.buf, req.size) < req.size) goto error; c->start = time_us(); aeDeleteFileEvent(loop, fd, AE_WRITABLE); @@ -406,7 +410,7 @@ static char *extract_url_part(char *url, struct http_parser_url *parser_url, enu } static char *format_request(char *host, char *port, char *path, char **headers) { - char *req = NULL; + char *buf = NULL; char *head = NULL; for (char **h = headers; *h != NULL; h++) { @@ -417,14 +421,21 @@ static char *format_request(char *host, char *port, char *path, char **headers) } } - aprintf(&req, "GET %s HTTP/1.1\r\n", path); - if (host) aprintf(&req, "Host: %s", host); - if (port) aprintf(&req, ":%s", port); - if (host) aprintf(&req, "\r\n"); - aprintf(&req, "%s\r\n", head ? head : ""); + if (req.body) { + size_t len = strlen(req.body); + aprintf(&head, "Content-Length: %zd\r\n", len); + } + + aprintf(&buf, "%s %s HTTP/1.1\r\n", req.method, path); + if (host) aprintf(&buf, "Host: %s", host); + if (port) aprintf(&buf, ":%s", port); + if (host) aprintf(&buf, "\r\n"); + + aprintf(&buf, "%s\r\n", head ? head : ""); + aprintf(&buf, "%s", req.body ? req.body : ""); free(head); - return req; + return buf; } static struct option longopts[] = { @@ -432,6 +443,8 @@ static struct option longopts[] = { { "duration", required_argument, NULL, 'd' }, { "threads", required_argument, NULL, 't' }, { "header", required_argument, NULL, 'H' }, + { "method", required_argument, NULL, 'M' }, + { "body", required_argument, NULL, 'B' }, { "latency", no_argument, NULL, 'L' }, { "timeout", required_argument, NULL, 'T' }, { "help", no_argument, NULL, 'h' }, @@ -447,8 +460,9 @@ static int parse_args(struct config *cfg, char **url, char **headers, int argc, cfg->connections = 10; cfg->duration = 10; cfg->timeout = SOCKET_TIMEOUT_MS; + req.method = "GET"; - while ((c = getopt_long(argc, argv, "t:c:d:H:T:Lrv?", longopts, NULL)) != -1) { + while ((c = getopt_long(argc, argv, "t:c:d:H:M:B:T:Lrv?", longopts, NULL)) != -1) { switch (c) { case 't': if (scan_metric(optarg, &cfg->threads)) return -1; @@ -462,6 +476,12 @@ static int parse_args(struct config *cfg, char **url, char **headers, int argc, case 'H': *header++ = optarg; break; + case 'M': + req.method = optarg; + break; + case 'B': + req.body = optarg; + break; case 'L': cfg->latency = true; break; diff --git a/src/wrk.h b/src/wrk.h index 114ee74..8e4dd84 100644 --- a/src/wrk.h +++ b/src/wrk.h @@ -11,7 +11,7 @@ #include "http_parser.h" #include "tinymt64.h" -#define VERSION "2.0.0" +#define VERSION "2.1.0" #define RECVBUF 8192 #define SAMPLES 100000