ab.c revision 383a9c6af58f5a670e8ef8b7f222ce71dbb7bee5
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele/* ====================================================================
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * The Apache Software License, Version 1.1
5f5d1b4cc970b7f06ff8ef6526128e9a27303d88nd * Copyright (c) 2000-2002 The Apache Software Foundation. All rights
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * Redistribution and use in source and binary forms, with or without
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * modification, are permitted provided that the following conditions
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * 1. Redistributions of source code must retain the above copyright
db479b48bd4d75423ed4a45e15b75089d1a8ad72fielding * notice, this list of conditions and the following disclaimer.
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * 2. Redistributions in binary form must reproduce the above copyright
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * notice, this list of conditions and the following disclaimer in
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * the documentation and/or other materials provided with the
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * distribution.
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * 3. The end-user documentation included with the redistribution,
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * if any, must include the following acknowledgment:
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * "This product includes software developed by the
1aa933455fcd538b1ee573f4566e1a78a89fce77nd * Apache Software Foundation (http://www.apache.org/)."
7db9f691a00ead175b03335457ca296a33ddf31bnd * Alternately, this acknowledgment may appear in the software itself,
3577f1d38e53397f6b431c02011f875316b2f070nd * if and wherever such third-party acknowledgments normally appear.
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * 4. The names "Apache" and "Apache Software Foundation" must
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * not be used to endorse or promote products derived from this
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * software without prior written permission. For written
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * permission, please contact apache@apache.org.
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * 5. Products derived from this software may not be called "Apache",
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * nor may "Apache" appear in their name, without prior written
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * permission of the Apache Software Foundation.
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * SUCH DAMAGE.
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * ====================================================================
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * This software consists of voluntary contributions made by many
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * individuals on behalf of the Apache Software Foundation. For more
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * information on the Apache Software Foundation, please see
5d7e5de2da57434c8e68c8fa49cbf6d70ee0f817slive * Portions of this software are based upon public domain software
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive * originally written at the National Center for Supercomputing Applications,
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive * University of Illinois, Urbana-Champaign.
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive ** This program is based on ZeusBench V1.0 written by Adam Twiss
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive ** which is Copyright (c) 1996 by Zeus Technology Ltd. http://www.zeustech.net/
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive ** This software is provided "as is" and any express or implied waranties,
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive ** including but not limited to, the implied warranties of merchantability and
c6f41bc69d643835804e7e831776d3d46c6f5962slive ** fitness for a particular purpose are disclaimed. In no event shall
c6f41bc69d643835804e7e831776d3d46c6f5962slive ** Zeus Technology Ltd. be liable for any direct, indirect, incidental, special,
c6f41bc69d643835804e7e831776d3d46c6f5962slive ** exemplary, or consequential damaged (including, but not limited to,
c6f41bc69d643835804e7e831776d3d46c6f5962slive ** procurement of substitute good or services; loss of use, data, or profits;
d7604f90897d9b08b227c127ff5392393178911crpluem ** or business interruption) however caused and on theory of liability. Whether
d7604f90897d9b08b227c127ff5392393178911crpluem ** in contract, strict liability or tort (including negligence or otherwise)
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive ** arising in any way out of the use of this software, even if advised of the
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive ** possibility of such damage.
263168fdb45221efa79580de89bdde883b7561f7sf ** HISTORY:
263168fdb45221efa79580de89bdde883b7561f7sf ** - Originally written by Adam Twiss <adam@zeus.co.uk>, March 1996
263168fdb45221efa79580de89bdde883b7561f7sf ** with input from Mike Belshe <mbelshe@netscape.com> and
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive ** Michael Campanella <campanella@stevms.enet.dec.com>
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive ** - Enhanced by Dean Gaudet <dgaudet@apache.org>, November 1997
d7604f90897d9b08b227c127ff5392393178911crpluem ** - Cleaned up by Ralf S. Engelschall <rse@apache.org>, March 1998
d7604f90897d9b08b227c127ff5392393178911crpluem ** - POST and verbosity by Kurt Sussman <kls@merlot.com>, August 1998
d7604f90897d9b08b227c127ff5392393178911crpluem ** - HTML table output added by David N. Welton <davidw@prosa.it>, January 1999
d7604f90897d9b08b227c127ff5392393178911crpluem ** - Added Cookie, Arbitrary header and auth support. <dirkx@webweaving.org>, April 1999
d7604f90897d9b08b227c127ff5392393178911crpluem ** Version 1.3d
d7604f90897d9b08b227c127ff5392393178911crpluem ** - Increased version number - as some of the socket/error handling has
d7604f90897d9b08b227c127ff5392393178911crpluem ** fundamentally changed - and will give fundamentally different results
d7604f90897d9b08b227c127ff5392393178911crpluem ** in situations where a server is dropping requests. Therefore you can
d7604f90897d9b08b227c127ff5392393178911crpluem ** no longer compare results of AB as easily. Hence the inc of the version.
d7604f90897d9b08b227c127ff5392393178911crpluem ** They should be closer to the truth though. Sander & <dirkx@covalent.net>, End 2000.
d7604f90897d9b08b227c127ff5392393178911crpluem ** - Fixed proxy functionality, added median/mean statistics, added gnuplot
d7604f90897d9b08b227c127ff5392393178911crpluem ** output option, added _experimental/rudimentary_ SSL support. Added
d7604f90897d9b08b227c127ff5392393178911crpluem ** confidence guestimators and warnings. Sander & <dirkx@covalent.net>, End 2000
c6f41bc69d643835804e7e831776d3d46c6f5962slive ** - Fixed serious int overflow issues which would cause realistic (longer
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun ** than a few minutes) run's to have wrong (but believable) results. Added
c6f41bc69d643835804e7e831776d3d46c6f5962slive ** trapping of connection errors which influenced measurements.
c6f41bc69d643835804e7e831776d3d46c6f5962slive ** Contributed by Sander Temme, Early 2001
06d77ae37da42a6f8bbea25b7d7f8b6629245629slive ** Version 1.3e
c6f41bc69d643835804e7e831776d3d46c6f5962slive ** - Changed timeout behavour during write to work whilst the sockets
c6f41bc69d643835804e7e831776d3d46c6f5962slive ** are filling up and apr_write() does writes a few - but not all.
c6f41bc69d643835804e7e831776d3d46c6f5962slive ** This will potentially change results. <dirkx@webweaving.org>, April 2001
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive * - has various other poor buffer attacks related to the lazy parsing of
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive * response headers from the server
3fa816e4832a1c70600bdfd6fc5ef60e9f1c18bbsf * - doesn't implement much of HTTP/1.x, only accepts certain forms of
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive * responses
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive * - (performance problem) heavy use of strstr shows up top in profile
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive * only an issue for loopback usage
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive/* -------------------------------------------------------------------- */
d7604f90897d9b08b227c127ff5392393178911crpluem/* Hmmm... This source code isn't being compiled in ASCII.
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive * In order for data that flows over the network to make
67f57b90aea98fc792b6c6e67bd27ee35f7d026bigalic * sense, we need to translate to/from ASCII.
aa8cf57195dfb7fa3d0baedf81f8be377946cea8slive/* affects include files on Solaris */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun/* Libraries on most systems.. */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele/* Libraries for RSAref and SYSSSL */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele/* ------------------- DEFINITIONS -------------------------- */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun/* maximum number of requests on a time limited test */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun/* good old state hostname */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele apr_size_t rwrite, rwrote; /* keep pointers in what we write - across
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * EAGAINs */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun apr_size_t length; /* Content-Length value used for keep-alive */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun char cbuff[CBUFFSIZE]; /* a buffer to store server response header */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun int keepalive; /* non-zero if a keep-alive request */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun int gotheader; /* non-zero if we have the entire header in
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele /* XXXX insert SSL timings */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun apr_time_t starttime; /* start time of connection in seconds since
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * Jan. 1, 1970 */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun apr_interval_time_t waittime; /* Between writing request and reading
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * response */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun apr_interval_time_t ctime; /* time in ms to connect */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun apr_interval_time_t time; /* time in ms for connection */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun#define ap_min(a,b) ((a)<(b))?(a):(b)
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun#define ap_max(a,b) ((a)>(b))?(a):(b)
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele/* --------------------- GLOBALS ---------------------------- */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgunint heartbeatres = 100; /* How often do we say we're alive */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabeleint concurrency = 1; /* Number of multiple requests to make */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabeleint confidence = 1; /* Show confidence estimator and warnings */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabeleint keepalive = 0; /* try and do keepalive connections */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabelechar postfile[1024]; /* name of file containing post data */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgunchar *postdata; /* *buffer containing data from postfile */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabeleapr_size_t postlen = 0; /* length of data to be POSTed */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgunchar content_type[1024]; /* content type to put in POST header */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * authentification */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabeleapr_short_interval_time_t aprtimeout = 30 * APR_USEC_PER_SEC; /* timeout value */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * XXX - this is now a per read/write transact type of value
a3388213b2b4d46b356be205e38204e67b4304d8rbowenapr_size_t doclen = 0; /* the length the document should be */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgunlong started = 0; /* number of requests started, so no excess */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgunlong totalbread = 0; /* totoal amount of entity body read */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgunlong totalposted = 0; /* total number of bytes posted, inc. headers */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgunlong doneka = 0; /* number of keep alive connections done */
a3388213b2b4d46b356be205e38204e67b4304d8rbowenlong good = 0, bad = 0; /* number of good and bad requests */
df321386f1d9ed17a3e5e6468807996a12890d50gryzor/* store error cases */
df321386f1d9ed17a3e5e6468807996a12890d50gryzor/* global request (and its length) */
df321386f1d9ed17a3e5e6468807996a12890d50gryzor/* one global throw-away buffer to read stuff into */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun/* interesting percentiles */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabeleint percs[] = {50, 66, 75, 80, 90, 95, 98, 99, 100};
4ab980a06412fd86f52a6d054fb7e26de155c530erikabelestatic void close_connection(struct connection * c);
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun/* --------------------------------------------------------- */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele/* simple little function to write an error string and exit */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabelestatic void err(char *s)
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele printf("Total of %ld requests completed\n" , done);
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun/* simple little function to write an APR error string and exit */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele "%s: %s (%d)\n",
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele/* --------------------------------------------------------- */
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele/* write out request to a connection - assumes we can write
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * (small) request out in one go into our new socket buffer
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * First time round ?
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele if (c->rwrite == 0) {
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun * Bail early on the most common case
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun if (l == c->rwrite)
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele * Let's hope this traps EWOULDBLOCK too !
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun } while (1);
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele apr_poll_socket_add(readbits, c->aprsock, APR_POLLIN);
4ab980a06412fd86f52a6d054fb7e26de155c530erikabele/* --------------------------------------------------------- */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgun/* calculate and output results */
ad93f15b0bef55041347cdbad447d94296eb89f2nilgunstatic int compradre(struct data * a, struct data * b)
ad93f15b0bef55041347cdbad447d94296eb89f2nilgunstatic int comprando(struct data * a, struct data * b)
4ab980a06412fd86f52a6d054fb7e26de155c530erikabelestatic int compri(struct data * a, struct data * b)
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) {
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)
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\n", AP_SERVER_BASEREVISION " <$Revision: 1.92 $> apache-2.0");
printf(" This is ApacheBench, Version %s <i><%s></i> apache-2.0<br>\n", AP_SERVER_BASEREVISION, "$Revision: 1.92 $");
#if USE_SSL
#if USE_SSL
char *cp;
char *scope_id;
#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 SIGPIPE
copyright();
test();