ab.c revision 5f6e75bc39f8d95c7495ed17e585597cd6bd7fba
7202N/A/* ==================================================================== 7202N/A * The Apache Software License, Version 1.1 7202N/A * Copyright (c) 2000 The Apache Software Foundation. All rights 7202N/A * Redistribution and use in source and binary forms, with or without 7202N/A * modification, are permitted provided that the following conditions 7202N/A * 1. Redistributions of source code must retain the above copyright 7202N/A * notice, this list of conditions and the following disclaimer. 7202N/A * 2. Redistributions in binary form must reproduce the above copyright 7202N/A * notice, this list of conditions and the following disclaimer in 7202N/A * the documentation and/or other materials provided with the 7202N/A * 3. The end-user documentation included with the redistribution, 7202N/A * if any, must include the following acknowledgment: 7202N/A * "This product includes software developed by the 7202N/A * Alternately, this acknowledgment may appear in the software itself, 7202N/A * if and wherever such third-party acknowledgments normally appear. 7202N/A * 4. The names "Apache" and "Apache Software Foundation" must 7202N/A * not be used to endorse or promote products derived from this 7202N/A * software without prior written permission. For written 7202N/A * permission, please contact apache@apache.org. 7202N/A * 5. Products derived from this software may not be called "Apache", 7202N/A * nor may "Apache" appear in their name, without prior written 7202N/A * permission of the Apache Software Foundation. 7202N/A * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED 7202N/A * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 7202N/A * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 7202N/A * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR 7202N/A * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 7202N/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 7202N/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 7202N/A * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 7202N/A * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 7202N/A * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 7202N/A * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 7202N/A * ==================================================================== 7202N/A * This software consists of voluntary contributions made by many 7202N/A * individuals on behalf of the Apache Software Foundation. For more 7202N/A * information on the Apache Software Foundation, please see 7202N/A * Portions of this software are based upon public domain software 7202N/A * originally written at the National Center for Supercomputing Applications, 7202N/A * University of Illinois, Urbana-Champaign. 7202N/A ** This program is based on ZeusBench V1.0 written by Adam Twiss 7202N/A ** This software is provided "as is" and any express or implied waranties, 7202N/A ** including but not limited to, the implied warranties of merchantability and 7202N/A ** fitness for a particular purpose are disclaimed. In no event shall 7202N/A ** Zeus Technology Ltd. be liable for any direct, indirect, incidental, special, 7202N/A ** exemplary, or consequential damaged (including, but not limited to, 7202N/A ** procurement of substitute good or services; loss of use, data, or profits; 7202N/A ** or business interruption) however caused and on theory of liability. Whether 7202N/A ** in contract, strict liability or tort (including negligence or otherwise) 7202N/A ** arising in any way out of the use of this software, even if advised of the 7202N/A ** possibility of such damage. 7202N/A ** - Originally written by Adam Twiss <adam@zeus.co.uk>, March 1996 7202N/A ** with input from Mike Belshe <mbelshe@netscape.com> and 7202N/A ** Michael Campanella <campanella@stevms.enet.dec.com> 7202N/A ** - Enhanced by Dean Gaudet <dgaudet@apache.org>, November 1997 ** - Cleaned up by Ralf S. Engelschall <rse@apache.org>, March 1998 ** - POST and verbosity by Kurt Sussman <kls@merlot.com>, August 1998 ** - HTML table output added by David N. Welton <davidw@prosa.it>, January 1999 ** - Added Cookie, Arbitrary header and auth support. <dirkx@webweaving.org>, April 199 * - has various other poor buffer attacks related to the lazy parsing of * response headers from the server * - doesn't implement much of HTTP/1.x, only accepts certain forms of * - (performance problem) heavy use of strstr shows up top in profile * only an issue for loopback usage /* -------------------------------------------------------------------- */ /* Hmmm... This source code isn't being compiled in ASCII. * In order for data that flows over the network to make * sense, we need to translate to/from ASCII. /* affects include files on Solaris */ /* ------------------- DEFINITIONS -------------------------- */ /* maximum number of requests on a time limited test */ /* good old state hostname */ int read;
/* amount of bytes read */ int bread;
/* amount of body read */ int length;
/* Content-Length value used for keep-alive */ int cbx;
/* offset in cbuffer */ int keepalive;
/* non-zero if a keep-alive request */ int gotheader;
/* non-zero if we have the entire header in int read;
/* number of bytes read */ int ctime;
/* time in ms to connect */ int time;
/* time in ms for connection */ #
define ap_min(a,b) ((a)<(b))?(a):(b)
#
define ap_max(a,b) ((a)>(b))?(a):(b)
/* --------------------- GLOBALS ---------------------------- */ int verbosity = 0;
/* no verbosity by default */ int posting = 0;
/* GET by default */ int requests =
1;
/* Number of requests to make */ int concurrency =
1;
/* Number of multiple requests to make */ int tlimit = 0;
/* time limit in cs */ int keepalive = 0;
/* try and do keepalive connections */ char servername[
1024];
/* name that server reports */ char path[
1024];
/* path name */ char postfile[
1024];
/* name of file containing post data */ char *
postdata;
/* *buffer containing data from postfile */ char content_type[
1024];
/* content type to put in POST header */ char cookie[
1024],
/* optional cookie line */ hdrs[
4096];
/* optional arbitrary headers */ int port =
80;
/* port number */ int use_html = 0;
/* use html in the report */ int doclen = 0;
/* the length the document should be */ int totalread = 0;
/* total number of bytes read */ int totalbread = 0;
/* totoal amount of entity body read */ int totalposted = 0;
/* total number of bytes posted, inc. headers */ int done = 0;
/* number of requests we have done */ int doneka = 0;
/* number of keep alive connections done */ int good = 0,
bad = 0;
/* number of good and bad requests */ /* global request (and its length) */ /* one global throw-away buffer to read stuff into */ struct data *
stats;
/* date for each request */ /* --------------------------------------------------------- */ /* simple little function to perror and exit */ /* --------------------------------------------------------- */ /* write out request to a connection - assumes we can write (small) request out in one go into our new socket buffer */ printf(
"Send request failed!\n");
/* --------------------------------------------------------- */ /* calculate and output results */ printf(
"Time taken for tests: %d.%03d seconds\n",
printf(
" (Connect: %d, Length: %d, Exceptions: %d)\n",
/* avoid divide by zero */ printf(
"Transfer rate: %.2f kb/s received\n",
/* work out connection times */ if (
requests > 0) {
/* avoid division by zero (if 0 requests) */ printf(
"\nConnnection Times (ms)\n");
printf(
"Processing: %5d %5d %5d\n",
/* --------------------------------------------------------- */ /* calculate and output results in HTML */ printf(
"<tr %s><th colspan=2 %s>Server Software:</th>" "<td colspan=2 %s>%s</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Server Hostname:</th>" "<td colspan=2 %s>%s</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Server Port:</th>" "<td colspan=2 %s>%d</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Document Path:</th>" "<td colspan=2 %s>%s</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Document Length:</th>" "<td colspan=2 %s>%d bytes</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Concurrency Level:</th>" "<td colspan=2 %s>%d</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Time taken for tests:</th>" "<td colspan=2 %s>%d.%03d seconds</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Complete requests:</th>" "<td colspan=2 %s>%d</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Failed requests:</th>" "<td colspan=2 %s>%d</td></tr>\n",
printf(
"<tr %s><td colspan=4 %s > (Connect: %d, Length: %d, Exceptions: %d)</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Non-2xx responses:</th>" "<td colspan=2 %s>%d</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Keep-Alive requests:</th>" "<td colspan=2 %s>%d</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Total transferred:</th>" "<td colspan=2 %s>%d bytes</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Total POSTed:</th>" "<td colspan=2 %s>%d</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>HTML transferred:</th>" "<td colspan=2 %s>%d bytes</td></tr>\n",
/* avoid divide by zero */ printf(
"<tr %s><th colspan=2 %s>Requests per second:</th>" "<td colspan=2 %s>%.2f</td></tr>\n",
printf(
"<tr %s><th colspan=2 %s>Transfer rate:</th>" "<td colspan=2 %s>%.2f kb/s received</td></tr>\n",
printf(
"<tr %s><td colspan=2 %s> </td>" "<td colspan=2 %s>%.2f kb/s sent</td></tr>\n",
printf(
"<tr %s><td colspan=2 %s> </td>" "<td colspan=2 %s>%.2f kb/s total</td></tr>\n",
/* work out connection times */ if (
requests > 0) {
/* avoid division by zero (if 0 requests) */ printf(
"<tr %s><th %s colspan=4>Connnection Times (ms)</th></tr>\n",
printf(
"<tr %s><th %s> </th> <th %s>min</th> <th %s>avg</th> <th %s>max</th></tr>\n",
printf(
"<tr %s><th %s>Connect:</th>" "<td %s>%5d</td></tr>\n",
printf(
"<tr %s><th %s>Processing:</th>" "<td %s>%5d</td></tr>\n",
printf(
"<tr %s><th %s>Total:</th>" "<td %s>%5d</td></tr>\n",
/* --------------------------------------------------------- */ /* start asnchronous non-blocking connection */ err(
"\nTest aborted after 10 failures\n\n");
/* connected first time */ /* --------------------------------------------------------- */ /* close down connection and save stats */ /* server has legitimately shut down an idle keep alive request */ good--;
/* connection never happend */ /* --------------------------------------------------------- */ /* read data from connection */ char respcode[
4];
/* 3 digits and null */ fprintf(
stderr,
"only simple translation is supported (%d/%u/%u)\n",
c->
cbuff[c->
cbx] = 0;
/* terminate for benefit of strstr */ /* this next line is so that we talk to NCSA 1.5 which blatantly * breaks the http specifaction /* read rest next time */ /* header is in invalid or too big - close connection */ err(
"\nTest aborted after 10 failures\n\n");
/* this is first time, extract some interesting info */ /* XXX: this parsing isn't even remotely HTTP compliant... * but in the interest of speed it doesn't totally have to be, * it just needs to be extended to handle whatever servers * folks want to test against. -djg */ /* check response code */ *s = 0;
/* terminate at end of header */ ||
strstr(c->
cbuff,
"keep-alive"))) {
/* for benefit of MSIIS */ /* handle NCSA, which sends Content-length: */ /* outside header, everything we have read is entity body */ /* finished a keep-alive connection */ c->
start = c->
connect;
/* zero connect time with keep-alive *//* --------------------------------------------------------- */ "User-Agent: ApacheBench/%s\r\n" keepalive ?
"Connection: Keep-Alive\r\n" :
"",
"User-Agent: ApacheBench/%s\r\n" keepalive ?
"Connection: Keep-Alive\r\n" :
"",
fprintf(
stderr,
"only simple translation is supported (%d/%u/%u)\n",
/* initialise lots of requests */ /* check for time limit expiry */ /* Timeout of 30 seconds. */ err(
"\nServer timed out\n\n");
/* Note: APR_POLLHUP is set after FIN is received on some * systems, so treat that like APR_POLLIN so that we try /* ------------------------------------------------------- */ /* display copyright information */ printf(
"This is ApacheBench, Version %s\n",
VERSION " <$Revision: 1.11 $> apache-2.0");
printf(
" This is ApacheBench, Version %s <i><%s></i> apache-2.0<br>\n",
VERSION,
"$Revision: 1.11 $");
/* display usage information */ fprintf(
stderr,
" -c concurrency Number of multiple requests to make\n");
fprintf(
stderr,
" -t timelimit Seconds to max. wait for responses\n");
fprintf(
stderr,
" -T content-type Content-type header for POSTing\n");
fprintf(
stderr,
" -v verbosity How much troubleshooting info to print\n");
fprintf(
stderr,
" -x attributes String to insert as table attributes\n");
fprintf(
stderr,
" -y attributes String to insert as tr attributes\n");
fprintf(
stderr,
" -z attributes String to insert as td or th attributes\n");
fprintf(
stderr,
" -C attribute Add cookie, eg. 'Apache=1234. (repeatable)\n");
fprintf(
stderr,
" -H attribute Add Arbitrary header line, eg. 'Accept-Encoding: zop'\n");
fprintf(
stderr,
" Inserted after all normal header lines. (repeatable)\n");
fprintf(
stderr,
" -A attribute Add Basic WWW Authentication, the attributes\n");
fprintf(
stderr,
" are a colon separated username and password.\n");
fprintf(
stderr,
" -p attribute Add Basic Proxy Authentication, the attributes\n");
fprintf(
stderr,
" are a colon separated username and password.\n");
fprintf(
stderr,
" -h Display usage information (this message)\n");
/* ------------------------------------------------------- */ /* split URL into parts */ char *p =
NULL;
/* points to port if url has it */ /* ------------------------------------------------------- */ /* read data to POST from file, save contents and length */ printf(
"Can\'t alloc postfile buffer\n");
printf(
"error reading postfilen");
/* ------------------------------------------------------- */ /* sort out command-line args and call test */ err(
"Invalid number of requests\n");
err(
"Cannot mix POST and HEAD");
err(
"Cannot mix POST and HEAD");
/* assume username passwd already to be in colon separated form. * Ready to be uu-encoded. * assume username passwd already to be in colon separated form.