ab.c revision 56b4c2f79f228da54b5815060ec3eb809dd9dcf9
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere/* ====================================================================
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * The Apache Software License, Version 1.1
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * reserved.
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * Redistribution and use in source and binary forms, with or without
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * modification, are permitted provided that the following conditions
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * 1. Redistributions of source code must retain the above copyright
2e545ce2450a9953665f701bb05350f0d3f26275nd * notice, this list of conditions and the following disclaimer.
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * 2. Redistributions in binary form must reproduce the above copyright
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * notice, this list of conditions and the following disclaimer in
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * the documentation and/or other materials provided with the
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen * distribution.
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * 3. The end-user documentation included with the redistribution,
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * if any, must include the following acknowledgment:
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * "This product includes software developed by the
3f08db06526d6901aa08c110b5bc7dde6bc39905nd * Apache Software Foundation (http://www.apache.org/)."
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * Alternately, this acknowledgment may appear in the software itself,
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * if and wherever such third-party acknowledgments normally appear.
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * 4. The names "Apache" and "Apache Software Foundation" must
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * not be used to endorse or promote products derived from this
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * software without prior written permission. For written
fac8c35bfb158112226ab43ddf84d59daca5dc30nd * permission, please contact apache@apache.org.
d474d8ef01ec5c2a09341cd148851ed383c3287crbowen * 5. Products derived from this software may not be called "Apache",
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * nor may "Apache" appear in their name, without prior written
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * permission of the Apache Software Foundation.
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * SUCH DAMAGE.
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * ====================================================================
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * This software consists of voluntary contributions made by many
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * individuals on behalf of the Apache Software Foundation. For more
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * information on the Apache Software Foundation, please see
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * Portions of this software are based upon public domain software
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * originally written at the National Center for Supercomputing Applications,
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * University of Illinois, Urbana-Champaign.
fabd4bc0c499704e644a74f78cc3871436824ea0jim ** This program is based on ZeusBench V1.0 written by Adam Twiss
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** which is Copyright (c) 1996 by Zeus Technology Ltd. http://www.zeustech.net/
bed3c2e56e8f3328e780200466b9d009093db468sf ** This software is provided "as is" and any express or implied waranties,
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** including but not limited to, the implied warranties of merchantability and
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** fitness for a particular purpose are disclaimed. In no event shall
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** Zeus Technology Ltd. be liable for any direct, indirect, incidental, special,
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** exemplary, or consequential damaged (including, but not limited to,
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** procurement of substitute good or services; loss of use, data, or profits;
591f748210dc55f2972482dddc84bb6bac61d6b9noodl ** or business interruption) however caused and on theory of liability. Whether
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** in contract, strict liability or tort (including negligence or otherwise)
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** arising in any way out of the use of this software, even if advised of the
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** possibility of such damage.
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** HISTORY:
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** - Originally written by Adam Twiss <adam@zeus.co.uk>, March 1996
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** with input from Mike Belshe <mbelshe@netscape.com> and
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** Michael Campanella <campanella@stevms.enet.dec.com>
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** - Enhanced by Dean Gaudet <dgaudet@apache.org>, November 1997
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** - Cleaned up by Ralf S. Engelschall <rse@apache.org>, March 1998
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** - POST and verbosity by Kurt Sussman <kls@merlot.com>, August 1998
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** - HTML table output added by David N. Welton <davidw@prosa.it>, January 1999
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** - Added Cookie, Arbitrary header and auth support. <dirkx@webweaving.org>, April 1999
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** Version 1.3d
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** - Increased version number - as some of the socket/error handling has
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** fundamentally changed - and will give fundamentally different results
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** in situations where a server is dropping requests. Therefore you can
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** no longer compare results of AB as easily. Hence the inc of the version.
fabd4bc0c499704e644a74f78cc3871436824ea0jim ** They should be closer to the truth though. Sander & <dirkx@covalent.net>, End 2000.
fabd4bc0c499704e644a74f78cc3871436824ea0jim ** - Fixed proxy functionality, added median/mean statistics, added gnuplot
4126704c4950bfd46d32ad54e3b106ac6d868a73sf ** output option, added _experimental/rudimentary_ SSL support. Added
fabd4bc0c499704e644a74f78cc3871436824ea0jim ** confidence guestimators and warnings. Sander & <dirkx@covalent.net>, End 2000
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** - Fixed serious int overflow issues which would cause realistic (longer
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** than a few minutes) run's to have wrong (but believable) results. Added
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** trapping of connection errors which influenced measurements.
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** Contributed by Sander Temme, Early 2001
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** Version 1.3e
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** - Changed timeout behavour during write to work whilst the sockets
fabd4bc0c499704e644a74f78cc3871436824ea0jim ** are filling up and apr_write() does writes a few - but not all.
fabd4bc0c499704e644a74f78cc3871436824ea0jim ** This will potentially change results. <dirkx@webweaving.org>, April 2001
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere ** Version 2.0.36-dev
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** Improvements to concurrent processing:
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** - Enabled non-blocking connect()s.
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** - Prevent blocking calls to apr_recv() (thereby allowing AB to
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** manage its entire set of socket descriptors).
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** - Any error returned from apr_recv() that is not EAGAIN or EOF
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor ** is now treated as fatal.
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf ** Contributed by Aaron Bannert, April 24, 2002
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf ** Version 2.0.36-2
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf ** Internalized the version string - this string is part
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf ** of the Agent: header and the result output.
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf ** Version 2.0.37-dev
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf ** Adopted SSL code by Madhu Mathihalli <madhusudan_mathihalli@hp.com>
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf ** [PATCH] ab with SSL support Posted Wed, 15 Aug 2001 20:55:06 GMT
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf ** Introduces four 'if (int == value)' tests per non-ssl request.
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf ** Version 2.0.40-dev
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf ** Switched to the new abstract pollset API, allowing ab to
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf ** take advantage of future apr_pollset_t scalability improvements.
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf ** Contributed by Brian Pane, August 31, 2002
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf/* Note: this version string should start with \d+[\d\.]* and be a valid
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf * string for an HTTP Agent: header when prefixed with 'ApacheBench/'.
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf * It should reflect the version of AB - and not that of the apache server
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf * it happens to accompany. And it should be updated or changed whenever
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf * the results are no longer fundamentally comparable to the results of
173e5f4d5ec46b5febb74ce860d753bb1faaba0fsf * a previous version of ab. Either due to a change in the logic of
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * ab - or to due to a change in the distribution it is compiled with
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * (such as an APR change in for example blocking).
fabd4bc0c499704e644a74f78cc3871436824ea0jim * - has various other poor buffer attacks related to the lazy parsing of
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * response headers from the server
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * - doesn't implement much of HTTP/1.x, only accepts certain forms of
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor * responses
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * - (performance problem) heavy use of strstr shows up top in profile
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * only an issue for loopback usage
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere/* -------------------------------------------------------------------- */
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere/* Hmmm... This source code isn't being compiled in ASCII.
9a58dc6a2b26ec128b1270cf48810e705f1a90dbsf * In order for data that flows over the network to make
e3659090e9bb9934465dbb6c6212ba4c512190b0jfclere * sense, we need to translate to/from ASCII.
999942e8e84bcae9b439ab30a040b1b997b343c9gryzor/* affects include files on Solaris */
727872d18412fc021f03969b8641810d8896820bhumbedooh/* Libraries on most systems.. */
0d0ba3a410038e179b695446bb149cce6264e0abnd/* Libraries for RSAref and SYSSSL */
#ifndef LLONG_MAX
#define STATE_UNCONNECTED 0
struct connection {
int state;
int socknum;
#ifdef USE_SSL
struct data {
#ifdef USE_SSL
#define ap_min(a,b) ((a)<(b))?(a):(b)
#define ap_max(a,b) ((a)>(b))?(a):(b)
int isproxy = 0;
const char *tablestring;
const char *trstring;
const char *tdstring;
#ifdef USE_SSL
int ssl = 0;
int err_response = 0;
#ifdef NOT_ASCII
static void err(char *s)
if (done)
if (done)
static int lock_num_locks;
static unsigned long ssl_util_thr_id(void)
#ifdef __MVS__
struct PSA {
unsigned long PSATOLD;
} *psaptr = 0;
return (unsigned long) apr_os_thread_current();
return APR_SUCCESS;
for (i = 0; i < lock_num_locks; i++) {
#ifdef USE_SSL
return(ret);
return(ret);
#ifndef RAND_MAX
#include <limits.h>
static int ssl_rand_choosenum(int l, int h)
void ssl_rand_seed()
int nDone = 0;
time_t t;
l = sizeof(time_t);
RAND_seed((unsigned char *)&t, l);
nDone += l;
l = sizeof(pid_t);
nDone += l;
SSL_CIPHER *c;
#ifdef RSAREF
c->read = 0;
c->bread = 0;
c->keepalive = 0;
c->cbx = 0;
c->gotheader = 0;
c->rwrite = 0;
if (c->ctx)
while (!hdone)
case SSL_ERROR_NONE:
case SSL_ERROR_SSL:
case SSL_ERROR_SYSCALL:
err_conn++;
case SSL_ERROR_WANT_READ:
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_CONNECT:
c->rwrite = 0;
case SSL_ERROR_ZERO_RETURN:
#ifdef RSAREF
#ifdef RSAREF
started++;
write_request(c);
apr_status_t e;
if (c->rwrite == 0) {
#ifdef USE_SSL
c->rwrote = 0;
if (posting)
close_connection(c);
#ifdef USE_SSL
if (e_ssl != l)
close_connection (c);
l = e_ssl;
if (l == c->rwrite)
#ifdef USE_SSL
if (e != APR_SUCCESS) {
if (!APR_STATUS_IS_EAGAIN(e)) {
epipe++;
close_connection(c);
c->rwrote += l;
c->rwrite -= l;
#ifdef USE_SSL
static void output_results(void)
float timetaken;
if (bad)
if (err_response)
if (keepalive)
if (posting > 0)
if (timetaken) {
if (posting > 0) {
if (requests) {
for (i = 0; i < requests; i++) {
for (i = 0; i < requests; i++) {
sdtot += a * a;
sdcon += a * a;
sdd += a * a;
sdwait += a * a;
if (gnuplot) {
if (!out) {
for (i = 0; i < requests; i++) {
fprintf(out, "%s\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\t%" APR_TIME_T_FMT "\n",
diff,
(int (*) (const void *, const void *)) compradre);
(int (*) (const void *, const void *)) compri);
(int (*) (const void *, const void *)) compwait);
(int (*) (const void *, const void *)) comprando);
if (confidence) {
#define CONF_FMT_STRING "%5" APR_TIME_T_FMT " %4d %5.1f %6" APR_TIME_T_FMT " %7" APR_TIME_T_FMT "\n"
else if (d > sd ) \
for (i = 0; i < sizeof(percs) / sizeof(int); i++)
if (percs[i] <= 0)
if (csvperc) {
if (!out) {
apr_time_t t;
static void output_html_results(void)
long timetaken;
if (bad)
if (err_response)
if (keepalive)
if (posting > 0)
if (timetaken) {
if (posting > 0) {
for (i = 0; i < requests; i++) {
#ifdef USE_SSL
c->read = 0;
c->bread = 0;
c->keepalive = 0;
c->cbx = 0;
c->gotheader = 0;
c->rwrite = 0;
if (c->ctx)
!= APR_SUCCESS) {
c->rwrite = 0;
err_conn++;
start_connect(c);
started++;
write_request(c);
if (good)
bad++;
err_length++;
struct data s;
#ifdef USE_SSL
start_connect(c);
apr_size_t r;
char *part;
r = sizeof(buffer);
#ifdef USE_SSL
if (status <= 0) {
close_connection(c);
r = status;
good++;
close_connection(c);
#ifdef USE_SSL
totalread += r;
if (c->read == 0) {
c->read += r;
if (!c->gotheader) {
#ifdef NOT_ASCII
if (space) {
err_response++;
start_connect(c);
if (!good) {
q = servername;
err_response++;
if (keepalive &&
char *cl;
if (!cl)
if (cl) {
c->bread += r;
totalbread += r;
good++;
doneka++;
bad++;
err_length++;
struct data s;
c->keepalive = 0;
c->length = 0;
c->gotheader = 0;
c->cbx = 0;
write_request(c);
static void test(void)
#ifdef NOT_ASCII
if (isproxy) {
if (!use_html) {
if (isproxy)
if (posting <= 0) {
#ifdef NOT_ASCII
#ifdef USE_SSL
!= APR_SUCCESS) {
for (i = 0; i < concurrency; i++) {
apr_int32_t n;
n = concurrency;
#ifdef USE_SSL
#ifdef USE_SSL
read_connection(c);
bad++;
err_except++;
start_connect(c);
write_request(c);
#ifdef USE_SSL
if (heartbeatres)
if (use_html)
static void copyright(void)
if (!use_html) {
printf(" This is ApacheBench, Version %s <i><%s></i> apache-2.0<br>\n", AP_AB_BASEREVISION, "$Revision: 1.119 $");
#ifdef USE_SSL
#ifdef USE_SSL
char *cp;
char *scope_id;
#ifdef USE_SSL
ssl = 0;
#ifdef USE_SSL
#ifdef USE_SSL
#ifdef USE_SSL
return rv;
if (!postdata) {
return APR_ENOMEM;
return rv;
length);
return APR_EINVAL;
const char *optarg;
#ifdef NOT_ASCII
if (status) {
if (status) {
if (status) {
#ifdef USE_SSL
#ifdef USE_SSL
if (!requests) {
heartbeatres = 0;
percentile = 0;
confidence = 0;
if (posting != 0)
else if (postdata) {
exit(r);
optarg++;
optarg++;
copyright();
heartbeatres = 0;
#ifdef USE_SSL
#ifdef RSAREF
#ifdef USE_THREADS
#ifdef SIGPIPE
copyright();
test();