Compare commits

...

11 Commits
v0.2 ... debian

Author SHA1 Message Date
Stefan Bühler 09ef98e7ae remove Makefile from debian branch 2013-05-10 14:07:11 +02:00
Stefan Bühler 6a008f7148 follow upstream fixes 2013-05-09 19:21:10 +02:00
Stefan Bühler d1913cac26 update debian changelog 2013-05-09 19:08:28 +02:00
Stefan Bühler e7dbbd757f Merge tag 'weighttp-0.3' into debian
weighttp v0.3
2013-05-09 19:06:36 +02:00
Thomas Porzelt 1bdbe4003c v0.3 2011-10-16 12:01:50 +02:00
Thomas Porzelt 0fdf9d4229 add stats about response status codes (2xx, 3xx, 4xx, 5xx) 2011-10-16 12:01:08 +02:00
Thomas Porzelt 0e287d6736 add -H commandline parameter to specify custom headers 2011-10-16 10:24:51 +02:00
Stefan d86a398452 Debianize 2010-10-24 18:59:23 +00:00
Thomas Porzelt cb720d0bf1 remove some bogus defines from wscript 2009-11-01 15:11:57 +01:00
Thomas Porzelt 5c686391cb add User-Agent header to request 2009-10-04 17:45:27 +02:00
Thomas Porzelt bdfdd127c1 add support for responses that are not keepalive, not chunked and don't have any content-length header 2009-10-04 17:45:19 +02:00
21 changed files with 433 additions and 35 deletions

View File

@ -1,7 +1,7 @@
The MIT License
Copyright (c) 2009 Thomas Porzelt
Copyright (c) 2009-2011 Thomas Porzelt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

1
TODO
View File

@ -1,4 +1,3 @@
- handle responses without content-length but connection: close
- timing statistics
- generally better statistics
- ssl support

40
debian/changelog vendored Normal file
View File

@ -0,0 +1,40 @@
weighttp (0.3-3) unstable; urgency=low
* remove Makefile from debian branch, use quilt. fix Makefile.
-- Stefan Bühler <stbuehler@web.de> Fri, 10 May 2013 13:54:24 +0200
weighttp (0.3-2) unstable; urgency=low
[ Jyri J. Virkki ]
* Fix header parsing to compare HTTP header field names case insensitively. This fixes the problem where responses get incorrectly marked as errors if the response header field name case doesn't happen to match to what is in the code.
[ Ben Brown ]
* Corrected Host header handling (fixes #2477)
* User-Agent header no longer needs a leading space
-- Stefan Bühler <stbuehler@web.de> Thu, 09 May 2013 19:17:14 +0200
weighttp (0.3-1) unstable; urgency=low
* New upstream release
-- Stefan Bühler <stbuehler@web.de> Thu, 09 May 2013 19:07:56 +0200
weighttp (0.2-2) unstable; urgency=low
* Use old debhelper for backports
-- Stefan Bühler <source@stbuehler.de> Sun, 24 Oct 2010 18:49:44 +0000
weighttp (0.2-1) unstable; urgency=low
* Initial release
-- Stefan Bühler <source@stbuehler.de> Mon, 23 Aug 2010 12:58:47 +0000
weighttp (0.2-0) unstable; urgency=low
* Initial release
-- Stefan Bühler <source@stbuehler.de> Mon, 23 Aug 2010 12:58:46 +0000

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
9

26
debian/control vendored Normal file
View File

@ -0,0 +1,26 @@
Source: weighttp
Section: net
Priority: extra
Maintainer: Stefan Bühler <stbuehler@web.de>
Build-Depends: debhelper (>= 9), libev-dev
Standards-Version: 3.9.4
Homepage: http://weighttp.lighttpd.net/
Vcs-Git: git://git.lighttpd.net/weighttp
Vcs-Browser: http://cgit.lighttpd.net/weighttp/
Package: weighttp
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: lightweight and simple webserver benchmarking tool
weighttp was designed to be very fast and easy to use and only supports a
tiny fraction of the HTTP protocol in order to be lean and simple.
.
weighttp supports multithreading to make good use of modern CPUs with
multiple cores as well as asynchronous i/o for concurrent requests
within a single thread.
.
For event handling, weighty relies on libev which fits the design perfectly,
being lightweight and fast itself.
.
Thanks to that, weighty supports all modern high-performance event
interfaces like epoll or kqueue, that the major OSs provide.

44
debian/copyright vendored Normal file
View File

@ -0,0 +1,44 @@
This work was packaged for Debian by:
Stefan Bühler <source@stbuehler.de> on Mon, 23 Aug 2010 12:58:46 +0000
It was downloaded from:
http://weighttp.lighttpd.net/
Upstream Author:
Thomas Porzelt <tp@cryosphere.de>
Copyright:
Copyright (c) 2009 Thomas Porzelt
License:
The MIT License
Copyright (c) 2009 Thomas Porzelt
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
The Debian packaging is:
Copyright (C) 2010 Stefan Bühler <source@stbuehler.de>

2
debian/docs vendored Normal file
View File

@ -0,0 +1,2 @@
README
TODO

View File

@ -0,0 +1,37 @@
From: =?UTF-8?q?Stefan=20B=C3=BChler?= <stbuehler@web.de>
Date: Fri, 10 May 2013 13:48:29 +0200
Subject: Makefile to replace waf handling
---
Makefile | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
create mode 100644 Makefile
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..741b8a1
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,22 @@
+
+all: weighttp
+
+override SOURCES := $(wildcard src/*.c)
+override OBJECTS := $(patsubst %.c,%.o,$(SOURCES))
+
+# VERSION must be set in env
+
+LIBS += -lev -lpthread
+override CFLAGS += '-DVERSION="$(VERSION)"'
+
+weighttp: $(OBJECTS)
+ $(CC) $(LDFLAGS) -o weighttp $^ $(LIBS)
+
+install: weighttp
+ mkdir -p $(DESTDIR)/usr/bin
+ cp weighttp $(DESTDIR)/usr/bin/
+
+clean:
+ rm -f weighttp $(OBJECTS)
+
+.PHONY: all install clean

View File

@ -0,0 +1,57 @@
From: "Jyri J. Virkki" <jyri@virkki.com>
Date: Sun, 6 Jan 2013 02:21:09 -0800
Subject: =?UTF-8?q?Fix=20header=20parsing=20to=20compare=20HTTP=20header=20f?=
=?UTF-8?q?ield=20names=20case=0Ainsensitively.=20This=20fixes=20the=20probl?=
=?UTF-8?q?em=20where=20responses=20get=20incorrectly=0Amarked=20as=20errors?=
=?UTF-8?q?=20if=20the=20response=20header=20field=20name=20case=20doesn't=20?=
=?UTF-8?q?happen=0Ato=20match=20to=20what=20is=20in=20the=20code.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Also compare connection and transfer-encoding tokens case insensitively.
(Reference: RFC 2616: header field names are not case sensitive.)
Co-authored-by: Stefan Bühler <stbuehler@web.de>
---
src/client.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/src/client.c b/src/client.c
index f8875e4..dd48265 100644
--- a/src/client.c
+++ b/src/client.c
@@ -379,26 +379,24 @@ static uint8_t client_parse(Client *client, int size) {
str = &client->buffer[client->parser_offset];
//printf("checking header: '%s'\n", str);
- if (strncmp(str, "Content-Length: ", sizeof("Content-Length: ")-1) == 0) {
+ if (strncasecmp(str, "Content-Length: ", sizeof("Content-Length: ")-1) == 0) {
/* content length header */
client->content_length = str_to_uint64(str + sizeof("Content-Length: ") - 1);
- } else if (strncmp(str, "Connection: ", sizeof("Connection: ")-1) == 0) {
+ } else if (strncasecmp(str, "Connection: ", sizeof("Connection: ")-1) == 0) {
/* connection header */
str += sizeof("Connection: ") - 1;
- if (strncmp(str, "close", sizeof("close")-1) == 0)
+ if (strncasecmp(str, "close", sizeof("close")-1) == 0)
client->keepalive = 0;
- else if (strncmp(str, "Keep-Alive", sizeof("Keep-Alive")-1) == 0)
- client->keepalive = client->worker->config->keep_alive;
- else if (strncmp(str, "keep-alive", sizeof("keep-alive")-1) == 0)
+ else if (strncasecmp(str, "keep-alive", sizeof("keep-alive")-1) == 0)
client->keepalive = client->worker->config->keep_alive;
else
return 0;
- } else if (strncmp(str, "Transfer-Encoding: ", sizeof("Transfer-Encoding: ")-1) == 0) {
+ } else if (strncasecmp(str, "Transfer-Encoding: ", sizeof("Transfer-Encoding: ")-1) == 0) {
/* transfer encoding header */
str += sizeof("Transfer-Encoding: ") - 1;
- if (strncmp(str, "chunked", sizeof("chunked")-1) == 0)
+ if (strncasecmp(str, "chunked", sizeof("chunked")-1) == 0)
client->chunked = 1;
else
return 0;

View File

@ -0,0 +1,76 @@
From: Ben Brown <ben@427.org.uk>
Date: Tue, 19 Feb 2013 20:03:57 +0000
Subject: Corrected Host header handling (fixes #2477)
---
src/weighttp.c | 33 ++++++++++++++++++++++++++++++---
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/src/weighttp.c b/src/weighttp.c
index 77504f1..a7744b5 100644
--- a/src/weighttp.c
+++ b/src/weighttp.c
@@ -76,9 +76,11 @@ static char *forge_request(char *url, char keep_alive, char **host, uint16_t *po
uint32_t len;
uint8_t i;
uint8_t have_user_agent;
+ char *header_host;
*host = NULL;
*port = 0;
+ header_host = NULL;
if (strncmp(url, "http://", 7) == 0)
url += 7;
@@ -137,6 +139,25 @@ static char *forge_request(char *url, char keep_alive, char **host, uint16_t *po
have_user_agent = 0;
for (i = 0; i < headers_num; i++) {
+ if (strncmp(headers[i], "Host:", sizeof("Host:")-1) == 0) {
+ if (header_host) {
+ W_ERROR("%s", "Duplicate Host header");
+ free(*host);
+ return NULL;
+ }
+ header_host = headers[i] + 5;
+ if (*header_host == ' ')
+ header_host++;
+
+ if (strlen(header_host) == 0) {
+ W_ERROR("%s", "Invalid Host header");
+ free(*host);
+ return NULL;
+ }
+
+ len += strlen(header_host);
+ continue;
+ }
len += strlen(headers[i]) + strlen("\r\n");
if (strncmp(headers[i], "User-Agent: ", sizeof("User-Agent: ")-1) == 0)
have_user_agent = 1;
@@ -150,9 +171,13 @@ static char *forge_request(char *url, char keep_alive, char **host, uint16_t *po
strcpy(req, "GET ");
strcat(req, url);
strcat(req, " HTTP/1.1\r\nHost: ");
- strcat(req, *host);
- if (*port != 80)
- sprintf(req + strlen(req), ":%"PRIu16, *port);
+ if (header_host) {
+ strcat(req, header_host);
+ } else {
+ strcat(req, *host);
+ if (*port != 80)
+ sprintf(req + strlen(req), ":%"PRIu16, *port);
+ }
strcat(req, "\r\n");
@@ -160,6 +185,8 @@ static char *forge_request(char *url, char keep_alive, char **host, uint16_t *po
sprintf(req + strlen(req), "User-Agent: weighttp/" VERSION "\r\n");
for (i = 0; i < headers_num; i++) {
+ if (strncmp(headers[i], "Host:", sizeof("Host:")-1) == 0)
+ continue;
strcat(req, headers[i]);
strcat(req, "\r\n");
}

View File

@ -0,0 +1,21 @@
From: Ben Brown <ben@427.org.uk>
Date: Tue, 19 Feb 2013 20:08:13 +0000
Subject: User-Agent header no longer needs a leading space
---
src/weighttp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/weighttp.c b/src/weighttp.c
index a7744b5..fa6af29 100644
--- a/src/weighttp.c
+++ b/src/weighttp.c
@@ -159,7 +159,7 @@ static char *forge_request(char *url, char keep_alive, char **host, uint16_t *po
continue;
}
len += strlen(headers[i]) + strlen("\r\n");
- if (strncmp(headers[i], "User-Agent: ", sizeof("User-Agent: ")-1) == 0)
+ if (strncmp(headers[i], "User-Agent:", sizeof("User-Agent:")-1) == 0)
have_user_agent = 1;
}

4
debian/patches/series vendored Normal file
View File

@ -0,0 +1,4 @@
0001-Makefile-to-replace-waf-handling.patch
0002-Fix-header-parsing-to-compare-HTTP-header-field-name.patch
0003-Corrected-Host-header-handling-fixes-2477.patch
0004-User-Agent-header-no-longer-needs-a-leading-space.patch

7
debian/rules vendored Executable file
View File

@ -0,0 +1,7 @@
#!/usr/bin/make -f
VERSION := $(shell dpkg-parsechangelog | awk '/Version:/ { print $2 }' | sed -e 's/-[^-]*$$//')
export VERSION
%:
dh $@

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
3.0 (quilt)

View File

@ -2,7 +2,7 @@
* weighttp - a lightweight and simple webserver benchmarking tool
*
* Author:
* Copyright (c) 2009 Thomas Porzelt
* Copyright (c) 2009-2011 Thomas Porzelt
*
* License:
* MIT, see COPYING file
@ -106,7 +106,7 @@ static void client_reset(Client *client) {
client->request_offset = 0;
client->ts_start = 0;
client->ts_end = 0;
client->status_200 = 0;
client->status_success = 0;
client->success = 0;
client->content_length = -1;
client->bytes_received = 0;
@ -259,8 +259,15 @@ void client_state_machine(Client *client) {
}
} else {
/* disconnect */
client->state = CLIENT_ERROR;
break;
if (client->parser_state == PARSER_BODY && !client->keepalive && client->status_success
&& !client->chunked && client->content_length == -1) {
client->success = 1;
client->state = CLIENT_END;
} else {
client->state = CLIENT_ERROR;
}
goto start;
}
}
@ -307,27 +314,50 @@ void client_state_machine(Client *client) {
static uint8_t client_parse(Client *client, int size) {
char *end, *str;
uint16_t status_code;
switch (client->parser_state) {
case PARSER_START:
//printf("parse (START):\n%s\n", &client->buffer[client->parser_offset]);
/* look for HTTP/1.1 200 OK */
if (client->buffer_offset < sizeof("HTTP/1.1 200 OK\r\n"))
if (client->buffer_offset < sizeof("HTTP/1.1 200\r\n"))
return 1;
if (strncmp(client->buffer, "HTTP/1.1 200 OK\r\n", sizeof("HTTP/1.1 200 OK\r\n")-1) == 0) {
client->status_200 = 1;
client->parser_offset = sizeof("HTTP/1.1 200 ok\r\n") - 1;
} else {
client->status_200 = 0;
end = strchr(client->buffer, '\r');
if (strncmp(client->buffer, "HTTP/1.1 ", sizeof("HTTP/1.1 ")-1) != 0)
return 0;
if (!end || *(end+1) != '\n')
// now the status code
status_code = 0;
str = client->buffer + sizeof("HTTP/1.1 ")-1;
for (end = str + 3; str != end; str++) {
if (*str < '0' || *str > '9')
return 0;
client->parser_offset = end + 2 - client->buffer;
status_code *= 10;
status_code += *str - '0';
}
if (status_code >= 200 && status_code < 300) {
client->worker->stats.req_2xx++;
client->status_success = 1;
} else if (status_code < 400) {
client->worker->stats.req_3xx++;
client->status_success = 1;
} else if (status_code < 500) {
client->worker->stats.req_4xx++;
} else if (status_code < 600) {
client->worker->stats.req_5xx++;
} else {
// invalid status code
return 0;
}
// look for next \r\n
end = strchr(end, '\r');
if (!end || *(end+1) != '\n')
return 0;
client->parser_offset = end + 2 - client->buffer;
client->parser_state = PARSER_HEADER;
case PARSER_HEADER:
//printf("parse (HEADER)\n");
@ -434,7 +464,7 @@ static uint8_t client_parse(Client *client, int size) {
if (client->chunk_size == 0) {
/* chunk of size 0 marks end of content body */
client->state = CLIENT_END;
client->success = client->status_200 ? 1 : 0;
client->success = client->status_success ? 1 : 0;
return 1;
}
@ -483,7 +513,7 @@ static uint8_t client_parse(Client *client, int size) {
if (client->bytes_received == (uint64_t) (client->header_size + client->content_length)) {
/* full response received */
client->state = CLIENT_END;
client->success = client->status_200 ? 1 : 0;
client->success = client->status_success ? 1 : 0;
}
}

View File

@ -2,7 +2,7 @@
* weighttp - a lightweight and simple webserver benchmarking tool
*
* Author:
* Copyright (c) 2009 Thomas Porzelt
* Copyright (c) 2009-2011 Thomas Porzelt
*
* License:
* MIT, see COPYING file
@ -33,7 +33,7 @@ struct Client {
ev_tstamp ts_end;
uint8_t keepalive;
uint8_t success;
uint8_t status_200;
uint8_t status_success;
uint8_t chunked;
int64_t chunk_size;
int64_t chunk_received;

View File

@ -2,7 +2,7 @@
* weighttp - a lightweight and simple webserver benchmarking tool
*
* Author:
* Copyright (c) 2009 Thomas Porzelt
* Copyright (c) 2009-2011 Thomas Porzelt
*
* License:
* MIT, see COPYING file
@ -19,8 +19,10 @@ static void show_help(void) {
printf(" -c num concurrent clients (default: 1)\n");
printf(" -k keep alive (default: no)\n");
printf(" -6 use ipv6 (default: no)\n");
printf(" -H str add header to request\n");
printf(" -h show help and exit\n");
printf(" -v show version and exit\n\n");
printf("example: weighttpd -n 10000 -c 10 -t 2 -k -H \"User-Agent: foo\" localhost/index.html\n\n");
}
static struct addrinfo *resolve_host(char *hostname, uint16_t port, uint8_t use_ipv6) {
@ -68,10 +70,12 @@ static struct addrinfo *resolve_host(char *hostname, uint16_t port, uint8_t use_
return res;
}
static char *forge_request(char *url, char keep_alive, char **host, uint16_t *port) {
static char *forge_request(char *url, char keep_alive, char **host, uint16_t *port, char **headers, uint8_t headers_num) {
char *c, *end;
char *req;
uint32_t len;
uint8_t i;
uint8_t have_user_agent;
*host = NULL;
*port = 0;
@ -126,7 +130,22 @@ static char *forge_request(char *url, char keep_alive, char **host, uint16_t *po
if (*url == '\0')
url = "/";
req = W_MALLOC(char, sizeof("GET HTTP/1.1\r\nHost: :65536\r\nConnection: keep-alive\r\n\r\n") + strlen(*host) + strlen(url));
// total request size
len = strlen("GET HTTP/1.1\r\nHost: :65536\r\nConnection: keep-alive\r\n\r\n") + 1;
len += strlen(*host);
len += strlen(url);
have_user_agent = 0;
for (i = 0; i < headers_num; i++) {
len += strlen(headers[i]) + strlen("\r\n");
if (strncmp(headers[i], "User-Agent: ", sizeof("User-Agent: ")-1) == 0)
have_user_agent = 1;
}
if (!have_user_agent)
len += strlen("User-Agent: weighttp/" VERSION "\r\n");
req = W_MALLOC(char, len);
strcpy(req, "GET ");
strcat(req, url);
@ -134,10 +153,21 @@ static char *forge_request(char *url, char keep_alive, char **host, uint16_t *po
strcat(req, *host);
if (*port != 80)
sprintf(req + strlen(req), ":%"PRIu16, *port);
strcat(req, "\r\n");
if (!have_user_agent)
sprintf(req + strlen(req), "User-Agent: weighttp/" VERSION "\r\n");
for (i = 0; i < headers_num; i++) {
strcat(req, headers[i]);
strcat(req, "\r\n");
}
if (keep_alive)
strcat(req, "\r\nConnection: keep-alive\r\n\r\n");
strcat(req, "Connection: keep-alive\r\n\r\n");
else
strcat(req, "\r\nConnection: close\r\n\r\n");
strcat(req, "Connection: close\r\n\r\n");
return req;
}
@ -175,10 +205,14 @@ int main(int argc, char *argv[]) {
int sec, millisec, microsec;
uint64_t rps;
uint64_t kbps;
char **headers;
uint8_t headers_num;
printf("weighttp - a lightweight and simple webserver benchmarking tool\n\n");
headers = NULL;
headers_num = 0;
/* default settings */
use_ipv6 = 0;
config.thread_count = 1;
@ -186,7 +220,7 @@ int main(int argc, char *argv[]) {
config.req_count = 0;
config.keep_alive = 0;
while ((c = getopt(argc, argv, ":hv6kn:t:c:")) != -1) {
while ((c = getopt(argc, argv, ":hv6kn:t:c:H:")) != -1) {
switch (c) {
case 'h':
show_help();
@ -210,6 +244,11 @@ int main(int argc, char *argv[]) {
case 'c':
config.concur_count = atoi(optarg);
break;
case 'H':
headers = W_REALLOC(headers, char*, headers_num+1);
headers[headers_num] = optarg;
headers_num++;
break;
case '?':
W_ERROR("unkown option: -%c", optopt);
show_help();
@ -256,7 +295,7 @@ int main(int argc, char *argv[]) {
return 2;
}
if (NULL == (config.request = forge_request(argv[optind], config.keep_alive, &host, &port))) {
if (NULL == (config.request = forge_request(argv[optind], config.keep_alive, &host, &port, headers, headers_num))) {
return 1;
}
@ -330,6 +369,10 @@ int main(int argc, char *argv[]) {
stats.req_failed += worker->stats.req_failed;
stats.bytes_total += worker->stats.bytes_total;
stats.bytes_body += worker->stats.bytes_body;
stats.req_2xx += worker->stats.req_2xx;
stats.req_3xx += worker->stats.req_3xx;
stats.req_4xx += worker->stats.req_4xx;
stats.req_5xx += worker->stats.req_5xx;
worker_free(worker);
}
@ -348,6 +391,9 @@ int main(int argc, char *argv[]) {
printf("requests: %"PRIu64" total, %"PRIu64" started, %"PRIu64" done, %"PRIu64" succeeded, %"PRIu64" failed, %"PRIu64" errored\n",
config.req_count, stats.req_started, stats.req_done, stats.req_success, stats.req_failed, stats.req_error
);
printf("status codes: %"PRIu64" 2xx, %"PRIu64" 3xx, %"PRIu64" 4xx, %"PRIu64" 5xx\n",
stats.req_2xx, stats.req_3xx, stats.req_4xx, stats.req_5xx
);
printf("traffic: %"PRIu64" bytes total, %"PRIu64" bytes http, %"PRIu64" bytes data\n",
stats.bytes_total, stats.bytes_total - stats.bytes_body, stats.bytes_body
);
@ -358,6 +404,7 @@ int main(int argc, char *argv[]) {
free(workers);
free(config.request);
free(host);
free(headers);
freeaddrinfo(config.saddr);
return 0;

View File

@ -2,7 +2,7 @@
* weighttp - a lightweight and simple webserver benchmarking tool
*
* Author:
* Copyright (c) 2009 Thomas Porzelt
* Copyright (c) 2009-2011 Thomas Porzelt
*
* License:
* MIT, see COPYING file
@ -30,6 +30,7 @@
#define CLIENT_BUFFER_SIZE 32 * 1024
#define W_MALLOC(t, n) ((t*) calloc((n), sizeof(t)))
#define W_REALLOC(p, t, n) ((t*) realloc(p, (n) * sizeof(t)))
#define W_ERROR(f, ...) fprintf(stderr, "error: " f "\n", __VA_ARGS__)
#define UNUSED(x) ( (void)(x) )

View File

@ -2,7 +2,7 @@
* weighttp - a lightweight and simple webserver benchmarking tool
*
* Author:
* Copyright (c) 2009 Thomas Porzelt
* Copyright (c) 2009-2011 Thomas Porzelt
*
* License:
* MIT, see COPYING file
@ -52,7 +52,8 @@ void *worker_thread(void* arg) {
/* start all clients */
for (i = 0; i < worker->num_clients; i++) {
client_state_machine(worker->clients[i]);
if (worker->stats.req_started < worker->stats.req_todo)
client_state_machine(worker->clients[i]);
}
ev_loop(worker->loop, 0);

View File

@ -2,7 +2,7 @@
* weighttp - a lightweight and simple webserver benchmarking tool
*
* Author:
* Copyright (c) 2009 Thomas Porzelt
* Copyright (c) 2009-2011 Thomas Porzelt
*
* License:
* MIT, see COPYING file
@ -20,6 +20,11 @@ struct Stats {
uint64_t req_error; /* total number of error'd requests */
uint64_t bytes_total; /* total number of bytes received (html+body) */
uint64_t bytes_body; /* total number of bytes received (body) */
uint64_t req_1xx;
uint64_t req_2xx;
uint64_t req_3xx;
uint64_t req_4xx;
uint64_t req_5xx;
};
struct Worker {

View File

@ -5,7 +5,7 @@
* weighttp - a lightweight and simple webserver benchmarking tool
*
* Author:
* Copyright (c) 2009 Thomas Porzelt
* Copyright (c) 2009-2011 Thomas Porzelt
*
* License:
* MIT, see COPYING file
@ -14,7 +14,7 @@
import Options
# the following two variables are used by the target "waf dist"
VERSION='0.2'
VERSION='0.3'
APPNAME='weighttp'
# these variables are mandatory ('/' are converted automatically)
@ -34,8 +34,7 @@ def configure(conf):
'-std=gnu99', '-Wall', '-Wshadow', '-W', '-pedantic', '-g', '-g2', '-O2', '-Wmissing-declarations',
'-Wdeclaration-after-statement', '-Wno-pointer-sign', '-Wcast-align', '-Winline', '-Wsign-compare',
'-Wnested-externs', '-Wpointer-arith', '-Wbad-function-cast', '-Wmissing-prototypes',
'-fPIC', '-D_GNU_SOURCE', '-D_FILE_OFFSET_BITS=64', '-D_LARGEFILE_SOURCE',
'-D_LARGE_FILES', '-fno-strict-aliasing',
'-fPIC', '-fno-strict-aliasing',
]
conf.check_tool('compiler_cc')