ab.c revision 1f8197849972ee6ad6c25036e72ab50ff153052b
6ae232055d4d8a97267517c5e50074c2c819941and/* ====================================================================
6ae232055d4d8a97267517c5e50074c2c819941and * The Apache Software License, Version 1.1
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * Copyright (c) 2000-2004 The Apache Software Foundation. All rights
fd9abdda70912b99b24e3bf1a38f26fde908a74cnd * reserved.
6ae232055d4d8a97267517c5e50074c2c819941and * Redistribution and use in source and binary forms, with or without
6ae232055d4d8a97267517c5e50074c2c819941and * modification, are permitted provided that the following conditions
6ae232055d4d8a97267517c5e50074c2c819941and * are met:
6ae232055d4d8a97267517c5e50074c2c819941and * 1. Redistributions of source code must retain the above copyright
6ae232055d4d8a97267517c5e50074c2c819941and * notice, this list of conditions and the following disclaimer.
2e545ce2450a9953665f701bb05350f0d3f26275nd * 2. Redistributions in binary form must reproduce the above copyright
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * notice, this list of conditions and the following disclaimer in
d29d9ab4614ff992b0e8de6e2b88d52b6f1f153erbowen * the documentation and/or other materials provided with the
6ae232055d4d8a97267517c5e50074c2c819941and * distribution.
af33a4994ae2ff15bc67d19ff1a7feb906745bf8rbowen * 3. The end-user documentation included with the redistribution,
3f08db06526d6901aa08c110b5bc7dde6bc39905nd * if any, must include the following acknowledgment:
6ae232055d4d8a97267517c5e50074c2c819941and * "This product includes software developed by the
6ae232055d4d8a97267517c5e50074c2c819941and * Apache Software Foundation (http://www.apache.org/)."
6ae232055d4d8a97267517c5e50074c2c819941and * Alternately, this acknowledgment may appear in the software itself,
b43f840409794ed298e8634f6284741f193b6c4ftakashi * if and wherever such third-party acknowledgments normally appear.
b43f840409794ed298e8634f6284741f193b6c4ftakashi * 4. The names "Apache" and "Apache Software Foundation" must
27dcd8d81085fd60aadcd8a9bad35a607b26b758nilgun * not be used to endorse or promote products derived from this
6ae232055d4d8a97267517c5e50074c2c819941and * software without prior written permission. For written
e609c337f729875bc20e01096c7e610f45356f54nilgun * permission, please contact apache@apache.org.
6ae232055d4d8a97267517c5e50074c2c819941and * 5. Products derived from this software may not be called "Apache",
b43f840409794ed298e8634f6284741f193b6c4ftakashi * nor may "Apache" appear in their name, without prior written
b43f840409794ed298e8634f6284741f193b6c4ftakashi * permission of the Apache Software Foundation.
b43f840409794ed298e8634f6284741f193b6c4ftakashi * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
6ae232055d4d8a97267517c5e50074c2c819941and * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
6ae232055d4d8a97267517c5e50074c2c819941and * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
6ae232055d4d8a97267517c5e50074c2c819941and * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
6ae232055d4d8a97267517c5e50074c2c819941and * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
6ae232055d4d8a97267517c5e50074c2c819941and * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
6ae232055d4d8a97267517c5e50074c2c819941and * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
6ae232055d4d8a97267517c5e50074c2c819941and * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6ae232055d4d8a97267517c5e50074c2c819941and * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
6ae232055d4d8a97267517c5e50074c2c819941and * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
6ae232055d4d8a97267517c5e50074c2c819941and * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
6ae232055d4d8a97267517c5e50074c2c819941and * SUCH DAMAGE.
6ae232055d4d8a97267517c5e50074c2c819941and * ====================================================================
30471a4650391f57975f60bbb6e4a90be7b284bfhumbedooh * This software consists of voluntary contributions made by many
6ae232055d4d8a97267517c5e50074c2c819941and * individuals on behalf of the Apache Software Foundation. For more
6ae232055d4d8a97267517c5e50074c2c819941and * information on the Apache Software Foundation, please see
6ae232055d4d8a97267517c5e50074c2c819941and * Portions of this software are based upon public domain software
6ae232055d4d8a97267517c5e50074c2c819941and * originally written at the National Center for Supercomputing Applications,
6ae232055d4d8a97267517c5e50074c2c819941and * University of Illinois, Urbana-Champaign.
6ae232055d4d8a97267517c5e50074c2c819941and ** This program is based on ZeusBench V1.0 written by Adam Twiss
6ae232055d4d8a97267517c5e50074c2c819941and ** which is Copyright (c) 1996 by Zeus Technology Ltd. http://www.zeustech.net/
6ae232055d4d8a97267517c5e50074c2c819941and ** This software is provided "as is" and any express or implied waranties,
6ae232055d4d8a97267517c5e50074c2c819941and ** including but not limited to, the implied warranties of merchantability and
6ae232055d4d8a97267517c5e50074c2c819941and ** fitness for a particular purpose are disclaimed. In no event shall
6ae232055d4d8a97267517c5e50074c2c819941and ** Zeus Technology Ltd. be liable for any direct, indirect, incidental, special,
6ae232055d4d8a97267517c5e50074c2c819941and ** exemplary, or consequential damaged (including, but not limited to,
6ae232055d4d8a97267517c5e50074c2c819941and ** procurement of substitute good or services; loss of use, data, or profits;
6ae232055d4d8a97267517c5e50074c2c819941and ** or business interruption) however caused and on theory of liability. Whether
6ae232055d4d8a97267517c5e50074c2c819941and ** in contract, strict liability or tort (including negligence or otherwise)
6ae232055d4d8a97267517c5e50074c2c819941and ** arising in any way out of the use of this software, even if advised of the
6ae232055d4d8a97267517c5e50074c2c819941and ** possibility of such damage.
6ae232055d4d8a97267517c5e50074c2c819941and ** HISTORY:
6ae232055d4d8a97267517c5e50074c2c819941and ** - Originally written by Adam Twiss <adam@zeus.co.uk>, March 1996
6ae232055d4d8a97267517c5e50074c2c819941and ** with input from Mike Belshe <mbelshe@netscape.com> and
6ae232055d4d8a97267517c5e50074c2c819941and ** Michael Campanella <campanella@stevms.enet.dec.com>
6ae232055d4d8a97267517c5e50074c2c819941and ** - Enhanced by Dean Gaudet <dgaudet@apache.org>, November 1997
6ae232055d4d8a97267517c5e50074c2c819941and ** - Cleaned up by Ralf S. Engelschall <rse@apache.org>, March 1998
6ae232055d4d8a97267517c5e50074c2c819941and ** - POST and verbosity by Kurt Sussman <kls@merlot.com>, August 1998
6ae232055d4d8a97267517c5e50074c2c819941and ** - HTML table output added by David N. Welton <davidw@prosa.it>, January 1999
6ae232055d4d8a97267517c5e50074c2c819941and ** - Added Cookie, Arbitrary header and auth support. <dirkx@webweaving.org>, April 1999
6ae232055d4d8a97267517c5e50074c2c819941and ** Version 1.3d
6ae232055d4d8a97267517c5e50074c2c819941and ** - Increased version number - as some of the socket/error handling has
6ae232055d4d8a97267517c5e50074c2c819941and ** fundamentally changed - and will give fundamentally different results
6ae232055d4d8a97267517c5e50074c2c819941and ** in situations where a server is dropping requests. Therefore you can
6ae232055d4d8a97267517c5e50074c2c819941and ** no longer compare results of AB as easily. Hence the inc of the version.
6ae232055d4d8a97267517c5e50074c2c819941and ** They should be closer to the truth though. Sander & <dirkx@covalent.net>, End 2000.
6ae232055d4d8a97267517c5e50074c2c819941and ** - Fixed proxy functionality, added median/mean statistics, added gnuplot
6ae232055d4d8a97267517c5e50074c2c819941and ** output option, added _experimental/rudimentary_ SSL support. Added
6ae232055d4d8a97267517c5e50074c2c819941and ** confidence guestimators and warnings. Sander & <dirkx@covalent.net>, End 2000
6ae232055d4d8a97267517c5e50074c2c819941and ** - Fixed serious int overflow issues which would cause realistic (longer
6ae232055d4d8a97267517c5e50074c2c819941and ** than a few minutes) run's to have wrong (but believable) results. Added
6ae232055d4d8a97267517c5e50074c2c819941and ** trapping of connection errors which influenced measurements.
6ae232055d4d8a97267517c5e50074c2c819941and ** Contributed by Sander Temme, Early 2001
6ae232055d4d8a97267517c5e50074c2c819941and ** Version 1.3e
6ae232055d4d8a97267517c5e50074c2c819941and ** - Changed timeout behavour during write to work whilst the sockets
6ae232055d4d8a97267517c5e50074c2c819941and ** are filling up and apr_write() does writes a few - but not all.
6ae232055d4d8a97267517c5e50074c2c819941and ** This will potentially change results. <dirkx@webweaving.org>, April 2001
6ae232055d4d8a97267517c5e50074c2c819941and ** Version 2.0.36-dev
6ae232055d4d8a97267517c5e50074c2c819941and ** Improvements to concurrent processing:
6ae232055d4d8a97267517c5e50074c2c819941and ** - Enabled non-blocking connect()s.
6ae232055d4d8a97267517c5e50074c2c819941and ** - Prevent blocking calls to apr_socket_recv() (thereby allowing AB to
6ae232055d4d8a97267517c5e50074c2c819941and ** manage its entire set of socket descriptors).
6ae232055d4d8a97267517c5e50074c2c819941and ** - Any error returned from apr_socket_recv() that is not EAGAIN or EOF
6ae232055d4d8a97267517c5e50074c2c819941and ** is now treated as fatal.
6ae232055d4d8a97267517c5e50074c2c819941and ** Contributed by Aaron Bannert, April 24, 2002
6ae232055d4d8a97267517c5e50074c2c819941and ** Version 2.0.36-2
6ae232055d4d8a97267517c5e50074c2c819941and ** Internalized the version string - this string is part
6ae232055d4d8a97267517c5e50074c2c819941and ** of the Agent: header and the result output.
6ae232055d4d8a97267517c5e50074c2c819941and ** Version 2.0.37-dev
6ae232055d4d8a97267517c5e50074c2c819941and ** Adopted SSL code by Madhu Mathihalli <madhusudan_mathihalli@hp.com>
6ae232055d4d8a97267517c5e50074c2c819941and ** [PATCH] ab with SSL support Posted Wed, 15 Aug 2001 20:55:06 GMT
6ae232055d4d8a97267517c5e50074c2c819941and ** Introduces four 'if (int == value)' tests per non-ssl request.
6ae232055d4d8a97267517c5e50074c2c819941and ** Version 2.0.40-dev
1d980e5489836e977ba59b419e27b0ec875c4bd3takashi ** Switched to the new abstract pollset API, allowing ab to
1d980e5489836e977ba59b419e27b0ec875c4bd3takashi ** take advantage of future apr_pollset_t scalability improvements.
1d980e5489836e977ba59b419e27b0ec875c4bd3takashi ** Contributed by Brian Pane, August 31, 2002
6ae232055d4d8a97267517c5e50074c2c819941and/* Note: this version string should start with \d+[\d\.]* and be a valid
6ae232055d4d8a97267517c5e50074c2c819941and * string for an HTTP Agent: header when prefixed with 'ApacheBench/'.
1d980e5489836e977ba59b419e27b0ec875c4bd3takashi * It should reflect the version of AB - and not that of the apache server
1d980e5489836e977ba59b419e27b0ec875c4bd3takashi * it happens to accompany. And it should be updated or changed whenever
1d980e5489836e977ba59b419e27b0ec875c4bd3takashi * the results are no longer fundamentally comparable to the results of
1d980e5489836e977ba59b419e27b0ec875c4bd3takashi * a previous version of ab. Either due to a change in the logic of
6ae232055d4d8a97267517c5e50074c2c819941and * ab - or to due to a change in the distribution it is compiled with
6ae232055d4d8a97267517c5e50074c2c819941and * (such as an APR change in for example blocking).
6ae232055d4d8a97267517c5e50074c2c819941and * - has various other poor buffer attacks related to the lazy parsing of
6ae232055d4d8a97267517c5e50074c2c819941and * response headers from the server
6ae232055d4d8a97267517c5e50074c2c819941and * - doesn't implement much of HTTP/1.x, only accepts certain forms of
6ae232055d4d8a97267517c5e50074c2c819941and * responses
6ae232055d4d8a97267517c5e50074c2c819941and * - (performance problem) heavy use of strstr shows up top in profile
6ae232055d4d8a97267517c5e50074c2c819941and * only an issue for loopback usage
6ae232055d4d8a97267517c5e50074c2c819941and/* -------------------------------------------------------------------- */
6ae232055d4d8a97267517c5e50074c2c819941and/* Hmmm... This source code isn't being compiled in ASCII.
6ae232055d4d8a97267517c5e50074c2c819941and * In order for data that flows over the network to make
6ae232055d4d8a97267517c5e50074c2c819941and * sense, we need to translate to/from ASCII.
6ae232055d4d8a97267517c5e50074c2c819941and/* affects include files on Solaris */
6ae232055d4d8a97267517c5e50074c2c819941and#if defined(HAVE_SSLC)
6ae232055d4d8a97267517c5e50074c2c819941and/* Libraries for RSA SSL-C */
6ae232055d4d8a97267517c5e50074c2c819941and/* Libraries on most systems.. */
6ae232055d4d8a97267517c5e50074c2c819941and/* ------------------- DEFINITIONS -------------------------- */
6ae232055d4d8a97267517c5e50074c2c819941and/* maximum number of requests on a time limited test */
6ae232055d4d8a97267517c5e50074c2c819941and/* good old state hostname */
6ae232055d4d8a97267517c5e50074c2c819941and#define STATE_CONNECTING 1 /* TCP connect initiated, but we don't
6ae232055d4d8a97267517c5e50074c2c819941and * know if it worked yet
6ae232055d4d8a97267517c5e50074c2c819941and#define STATE_CONNECTED 2 /* we know TCP connect completed */
0d0ba3a410038e179b695446bb149cce6264e0abnd apr_size_t rwrite, rwrote; /* keep pointers in what we write - across
727872d18412fc021f03969b8641810d8896820bhumbedooh * EAGAINs */
cc7e1025de9ac63bd4db6fe7f71c158b2cf09fe4humbedooh apr_size_t length; /* Content-Length value used for keep-alive */
0d0ba3a410038e179b695446bb149cce6264e0abnd char cbuff[CBUFFSIZE]; /* a buffer to store server response header */
727872d18412fc021f03969b8641810d8896820bhumbedooh int keepalive; /* non-zero if a keep-alive request */
0d0ba3a410038e179b695446bb149cce6264e0abnd int gotheader; /* non-zero if we have the entire header in
0d0ba3a410038e179b695446bb149cce6264e0abnd * cbuff */
7fec19672a491661b2fe4b29f685bc7f4efa64d4nd /* XXXX insert SSL timings */
#define ap_min(a,b) ((a)<(b))?(a):(b)
#define ap_max(a,b) ((a)>(b))?(a):(b)
char *connecthost;
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)
static void ssl_rand_seed(void)
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);
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) {
if (!buff) {
#ifdef NOT_ASCII
#ifdef USE_SSL
!= APR_SUCCESS) {
for (i = 0; i < concurrency; i++) {
apr_int32_t n;
n = concurrency;
#ifdef USE_SSL
struct connection *c;
#ifdef USE_SSL
if (ssl)
c = &con[i];
#ifdef USE_SSL
read_connection(c);
bad++;
err_except++;
start_connect(c);
err_conn++;
start_connect(c);
write_request(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.134 $");
#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();