ab.c revision 81bd9331da3bd0f53255d52b1475480ff3a4b395
c79e39ad568d9af854765f64049534044ef6c034nd/* Licensed to the Apache Software Foundation (ASF) under one or more
2d0611ffc9f91c5fc2ddccb93f9a3d17791ae650takashi * contributor license agreements. See the NOTICE file distributed with
c79e39ad568d9af854765f64049534044ef6c034nd * this work for additional information regarding copyright ownership.
d3e250aab242db84d14060985b5db675a731d548nd * The ASF licenses this file to You under the Apache License, Version 2.0
c79e39ad568d9af854765f64049534044ef6c034nd * (the "License"); you may not use this file except in compliance with
7add1372edb1ee95a2c4d1314df4c7567bda7c62jim * the License. You may obtain a copy of the License at
af4908211c0c00c219a691719fa9e8e12f42075dnd * Unless required by applicable law or agreed to in writing, software
c79e39ad568d9af854765f64049534044ef6c034nd * distributed under the License is distributed on an "AS IS" BASIS,
a8c35ec6f8811732d20d218531750ef139bde308nd * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem * See the License for the specific language governing permissions and
4b575a6b6704b516f22d65a3ad35696d7b9ba372rpluem * limitations under the License.
c79e39ad568d9af854765f64049534044ef6c034nd ** This program is based on ZeusBench V1.0 written by Adam Twiss
c79e39ad568d9af854765f64049534044ef6c034nd ** which is Copyright (c) 1996 by Zeus Technology Ltd. http://www.zeustech.net/
** output option, added _experimental/rudimentary_ SSL support. Added
#define NOT_ASCII
#define BSD_COMP
#include "apr.h"
#include "apr_signal.h"
#include "apr_strings.h"
#include "apr_network_io.h"
#include "apr_file_io.h"
#include "apr_time.h"
#include "apr_getopt.h"
#include "apr_general.h"
#include "apr_lib.h"
#include "apr_portable.h"
#include "ap_release.h"
#include "apr_poll.h"
#define APR_WANT_STRFUNC
#include "apr_want.h"
#include "apr_base64.h"
#ifdef NOT_ASCII
#include "apr_xlate.h"
#if APR_HAVE_STDIO_H
#include <stdio.h>
#include <stdlib.h>
#include "ap_config_auto.h"
#if defined(HAVE_SSLC)
#include <rsa.h>
#include <x509.h>
#include <pem.h>
#include <err.h>
#include <ssl.h>
#include <r_rand.h>
#include <sslc.h>
#define USE_SSL
#define RSAREF
#define USE_SSL
#include <math.h>
#if APR_HAVE_CTYPE_H
#include <ctype.h>
#ifndef LLONG_MAX
#define STATE_UNCONNECTED 0
struct connection {
int state;
int socknum;
#ifdef USE_SSL
struct data {
#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 is_ssl;
int err_response = 0;
#ifdef NOT_ASCII
static void err(char *s)
if (done)
if (done)
#ifdef USE_SSL
return(ret);
return ret;
if (w & SSL_CB_ALERT) {
} else if (w & SSL_CB_LOOP) {
#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;
int count;
while (do_next) {
switch (ecode) {
case SSL_ERROR_NONE:
ssl_print_info(c);
if (cert)
write_request(c);
do_next = 0;
case SSL_ERROR_WANT_READ:
do_next = 0;
case SSL_ERROR_WANT_WRITE:
case SSL_ERROR_WANT_CONNECT:
case SSL_ERROR_SSL:
case SSL_ERROR_SYSCALL:
close_connection(c);
do_next = 0;
if (c->rwrite == 0) {
c->rwrote = 0;
if (posting)
close_connection(c);
#ifdef USE_SSL
if (c->ssl) {
if (e_ssl != l) {
close_connection (c);
l = e_ssl;
e = APR_SUCCESS;
if (l == c->rwrite)
if (e != APR_SUCCESS) {
if (!APR_STATUS_IS_EAGAIN(e)) {
epipe++;
close_connection(c);
c->rwrote += l;
c->rwrite -= l;
float timetaken;
if (sig) {
#ifdef USE_SSL
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;
if (sig) {
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) {
if (windowsize != 0) {
#ifdef USE_SSL
if (is_ssl) {
c->rwrite = 0;
err_conn++;
start_connect(c);
started++;
#ifdef USE_SSL
if (c->ssl) {
write_request(c);
if (good)
bad++;
err_length++;
struct data s;
#ifdef USE_SSL
if (c->ssl) {
start_connect(c);
apr_size_t r;
char *part;
r = sizeof(buffer);
#ifdef USE_SSL
if (c->ssl) {
if (status <= 0) {
good++;
close_connection(c);
c->read = 0;
close_connection(c);
r = status;
good++;
close_connection(c);
err_recv++;
if (recverrok) {
bad++;
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) {
if (!cl) {
c->length = 0;
c->bread += r;
totalbread += r;
good++;
bad++;
err_length++;
struct data s;
doneka++;
c->keepalive = 0;
c->length = 0;
c->gotheader = 0;
c->cbx = 0;
write_request(c);
static void test(void)
int snprintf_res = 0;
#ifdef NOT_ASCII
if (isproxy) {
if (!use_html) {
if (isproxy)
if (posting <= 0) {
if (!buff) {
#ifdef NOT_ASCII
!= APR_SUCCESS) {
#ifdef SIGINT
for (i = 0; i < concurrency; i++) {
apr_int32_t n;
n = concurrency;
struct connection *c;
#ifdef USE_SSL
read_connection(c);
bad++;
err_except++;
start_connect(c);
err_conn++;
start_connect(c);
started++;
#ifdef USE_SSL
if (c->ssl)
write_request(c);
write_request(c);
if (heartbeatres)
if (use_html)
output_results(0);
static void copyright(void)
if (!use_html) {
printf(" This is ApacheBench, Version %s <i><%s></i><br>\n", AP_AB_BASEREVISION, "$Revision$");
#ifdef USE_SSL
#ifdef USE_SSL
char *cp;
char *scope_id;
#ifdef USE_SSL
is_ssl = 0;
#ifdef USE_SSL
#ifdef USE_SSL
if (is_ssl)
#ifdef USE_SSL
return rv;
if (!postdata) {
return APR_ENOMEM;
return rv;
const char *optarg;
#ifdef USE_SSL
#ifdef NOT_ASCII
if (status) {
if (status) {
if (status) {
#ifdef USE_SSL
if (!requests) {
heartbeatres = 0;
percentile = 0;
confidence = 0;
if (posting != 0)
else if (postdata) {
exit(r);
optarg++;
optarg++;
copyright();
#ifdef USE_SSL
heartbeatres = 0;
#ifdef USE_SSL
#ifdef RSAREF
#ifdef SIGPIPE
copyright();
test();