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