Commit 01b2c97f authored by Thorsten Alteholz's avatar Thorsten Alteholz

Import Upstream version 0.8

parents
David Mosberger (main sources)
Martin Arlitt (SSL support)
Stephane Eranian (wlog URI generator)
Richard Carter (wsesslog workload generator)
This diff is collapsed.
This diff is collapsed.
SHELL=/bin/sh
VPATH = @srcdir@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = .
prefix = @prefix@
bindir = @bindir@
mandir = @mandir@
#DEFS += -DTIME_SYSCALLS
#DEFS += -DDONT_POLL
SUBDIRS = lib gen stat
CC = @CC@
RANLIB = @RANLIB@
MKDIR = $(top_srcdir)/mkinstalldirs
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INCLUDES = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/lib
DEFS = @DEFS@
CPPFLAGS = @CPPFLAGS@
CFLAGS = @CFLAGS@
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LINK = $(CC) $(LDFLAGS) -o $@
@SET_MAKE@
.c.o:
$(COMPILE) $<
HTTPERF_OBJS = httperf.o object.o call.o conn.o sess.o core.o event.o \
http.o timer.o
TTEST_OBJS = ttest.o timer.o
all: all-recursive httperf idleconn
httperf: $(HTTPERF_OBJS) gen/libgen.a stat/libstat.a lib/libutil.a
$(LINK) $(HTTPERF_OBJS) \
gen/libgen.a stat/libstat.a lib/libutil.a $(LIBS)
idleconn: idleconn.o
$(LINK) idleconn.o $(LIBS)
install: install-recursive httperf
$(MKDIR) $(bindir) $(mandir)/man1
$(INSTALL_PROGRAM) httperf $(bindir)/httperf
$(INSTALL_DATA) $(srcdir)/httperf.man $(mandir)/man1/httperf.1
ttest: ttest.o timer.o
clean: clean-recursive
rm -f $(HTTPERF_OBJS) $(TTEST_OBJS) idleconn.o httperf idleconn ttest
distclean: distclean-recursive
rm -f *~
all-recursive install-recursive clean-recursive distclean-recursive \
depend-recursive:
@for subdir in $(SUBDIRS); do \
target=`echo $@ | sed s/-recursive//`; \
echo making $$target in $$subdir; \
(cd $$subdir && $(MAKE) $$target) \
|| case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
.PHONY: all install clean distclean depend \
all-recursive install-recursive clean-recursive distclean-recursive \
depend-recursive
-*-Mode: outline-*-
* New in version 0.8:
** httperf is now released under the GNU General Public License (GPL).
** Preliminary support for SSL (Secure Socket Layer). See README for details.
** New options (see man-page for details):
--print-reply (replaced --print-replies)
--print-request
--ssl
--ssl-ciphers
--ssl-no-reuse
* New in version 0.7:
** New options (see man-page for details):
--add-header
--method
--retry-on-failure
** Bug fixes
- fixed some segfaults in the session workload generator
- specifying option --session-cookie when not using a session
workload generator now prints an error message instead of
core dumping
* New in version 0.6:
** New options (see man-page for details):
--max-connections
--max-piped-calls
--print-replies
--session-cookies
** Cookie support now must be requested explicitly when using a session-based
workload generator. To do this, specify option --session-cookie.
* New in version 0.5:
** Normal connection closing is the default again. To request closing TCP
connections with a RESET, specify option --close-with-reset.
** --wsesslog option added to support log-file based session
specification (contributed by Dick Carter).
** --period option added to allow a more flexible way to specify
session/connection interarrival time. Unlike the --rate
argument, this allows deterministic (fixed), uniform, and
exponentially distributed interarrival times (contributed by Dick
Carter).
** Various bug fixes (see ChangeLog for details).
* New in version 0.41:
** In basic statistic, rename "call" to "request".
* New in version 0.4:
** Option --http-version can be used to select the HTTP protocol version
used in sending requests. 1.0 and 1.0 are the only allowed values
for this option at this point.
** What used to be called a "session" is now called a "connection". This
reduces confusion between TCP connections and user sessions.
** Stephane's log-file based URL generated has been added.
** The session workload generator now supports the --burst-length
parameter to generate bursty session.
This diff is collapsed.
Some ideas (contributions/patches welcome):
- wsesspage: don't fetch same object more than once (assume the existence
of a cache)---this avoids trouble with recursive pages
- make httperf easier to use; some ideas:
o Make httperf into a network daemon that is controlled by
an httperf frontend. This would allow running tests with
a single command line even when multiple clients are involved.
The performance results should be reported both on a
per-client basis and in a summarized form reporting overall
server behavior.
o Provide (default) scripts to run certain benchmarks.
o Provide (default) scripts to produce performance graphs.
- use cycle registers to get time on CPUs that have such registers
(IA-64, PA-RISC, x86, Alpha, at least)
- randomize the uri's generated by --wset so we can defeat file prefetching
that the server (or the server's OS) may attempt to do
Done:
+ Specifying --session-cookie without specifying a session workload causes
httperf to core-dump (reported by Dick Carter, 10/13/98)
+ elevate `Session' to same level as Call and Connection
+ sample session throughput when using sessions (not just rate throughput)
+ integrate Dick's wsesslog
+ write man-page
+ chunked replies fail after the first reply (at least on HP-UX)
+ core.c does not fully support pipelined requests yet; would require
changes to the watchdog management
AC_DEFUN(AC_TYPE_LONG_LONG,
[AC_CACHE_CHECK(for long long type, ac_cv_type_long_long,
[AC_TRY_COMPILE(, [unsigned long long x, y, z; x = y/z],
ac_cv_type_long_long=yes, ac_cv_type_long_long=no)])
if test $ac_cv_type_long_long = yes; then
AC_DEFINE(u_wide,unsigned long long)
else
AC_DEFINE(u_wide,unsigned long)
fi
])
/*
httperf -- a tool for measuring web server performance
Copyright (C) 2000 Hewlett-Packard Company
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of httperf, a web server performance measurment
tool.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <httperf.h>
#include <call.h>
#include <conn.h>
static u_long next_id = 0;
void
call_init (Call *c)
{
# define DEFAULT_METHOD "GET"
c->id = next_id++;
call_set_method (c, DEFAULT_METHOD, sizeof (DEFAULT_METHOD) - 1);
c->req.version = param.http_version;
c->req.iov[IE_BLANK].iov_base = (caddr_t) " ";
c->req.iov[IE_BLANK].iov_len = 1;
c->req.iov[IE_NEWLINE1].iov_base = (caddr_t) "\r\n";
c->req.iov[IE_NEWLINE1].iov_len = 2;
c->req.iov[IE_NEWLINE2].iov_base = (caddr_t) "\r\n";
c->req.iov[IE_NEWLINE2].iov_len = 2;
}
void
call_deinit (Call *call)
{
}
int
call_append_request_header (Call *c, const char *hdr, size_t len)
{
u_int num_hdrs = c->req.num_extra_hdrs;
if (num_hdrs >= MAX_EXTRA_HEADERS)
{
fprintf (stderr, "%s.call_append_request_header: max headers "
"(%d) exceeded.\n", prog_name, MAX_EXTRA_HEADERS);
return -1;
}
c->req.iov[IE_FIRST_HEADER + num_hdrs].iov_base = (caddr_t) hdr;
c->req.iov[IE_FIRST_HEADER + num_hdrs].iov_len = len;
c->req.num_extra_hdrs = num_hdrs + 1;
return 0;
}
/*
httperf -- a tool for measuring web server performance
Copyright (C) 2000 Hewlett-Packard Company
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of httperf, a web server performance measurment
tool.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
*/
#ifndef call_h
#define call_h
#include <sys/types.h>
#include <sys/uio.h>
#include <httperf.h>
#include <conn.h>
#include <object.h>
/* Max. # of additional request header lines we allow: */
#define MAX_EXTRA_HEADERS 4
typedef enum IOV_Element
{
IE_METHOD,
IE_BLANK, /* space separating method from location */
IE_LOC, /* for proxy requests only */
IE_URI,
IE_PROTL,
IE_HOST, /* for the "Host:" header */
IE_NEWLINE1,
IE_FIRST_HEADER,
IE_LAST_HEADER = IE_FIRST_HEADER + MAX_EXTRA_HEADERS - 1,
IE_NEWLINE2,
IE_CONTENT,
IE_LEN /* must be last */
}
IOV_Element;
/* I call this a "call" because "transaction" is too long and because
it's basically a remote procedure call consisting of a request that
is answered by a reply. */
typedef struct Call
{
Object obj;
u_long id; /* unique id */
/* Connection this call is being sent on. This pointer is NOT
reference counted as otherwise we would get a recursive
dependency between connections and calls.... */
struct Conn *conn;
struct Call *sendq_next;
struct Call *recvq_next;
Time timeout; /* used for watchdog management */
struct
{
Time time_send_start;
Time time_recv_start;
}
basic;
/* the request: */
struct
{
int version; /* 0x10000*major + minor */
u_int num_extra_hdrs; /* number of additional headers in use */
int iov_index; /* first iov element that has data */
size_t size; /* # of bytes sent */
struct iovec iov_saved; /* saved copy of iov[iov_index] */
struct iovec iov[IE_LEN];
}
req;
/* the reply: */
struct
{
int status;
int version; /* 0x10000*major + minor */
size_t header_bytes; /* # of header bytes received so far */
size_t content_bytes; /* # of reply data bytes received so far */
size_t footer_bytes; /* # of footer bytes received so far */
}
reply;
}
Call;
/* Initialize the new call object C. */
extern void call_init (Call *c);
/* Destroy the call-specific state in call object C. */
extern void call_deinit (Call *c);
#define call_new() ((Call *) object_new (OBJ_CALL))
#define call_inc_ref(c) object_inc_ref ((Object *) (c))
#define call_dec_ref(c) object_dec_ref ((Object *) (c))
/* Append the additional request header line(s) HDR to the request
headers. The total length of the additional headers is LEN bytes.
The headers must be end with a carriage-return, line-feed sequence
("\r\n"). */
extern int call_append_request_header (Call *c, const char *hdr, size_t len);
#define call_set_method(c, method, method_len) \
do \
{ \
c->req.iov[IE_METHOD].iov_base = (caddr_t) method; \
c->req.iov[IE_METHOD].iov_len = method_len; \
} \
while (0)
#define call_set_location(c, loc, loc_len) \
do \
{ \
c->req.iov[IE_LOC].iov_base = (caddr_t) loc; \
c->req.iov[IE_LOC].iov_len = loc_len; \
} \
while (0)
#define call_set_uri(c, uri, uri_len) \
do \
{ \
c->req.iov[IE_URI].iov_base = (caddr_t) uri; \
c->req.iov[IE_URI].iov_len = uri_len; \
} \
while (0)
#define call_set_contents(c, content, content_len) \
do \
{ \
c->req.iov[IE_CONTENT].iov_base = (caddr_t) content; \
c->req.iov[IE_CONTENT].iov_len = content_len; \
} \
while (0)
#endif /* call_h */
This diff is collapsed.
/* config.h.in. Generated automatically from configure.in by autoheader. */
/* Define if using alloca.c. */
#undef C_ALLOCA
/* Define to empty if the keyword does not work. */
#undef const
/* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems.
This function is required for alloca.c support on those systems. */
#undef CRAY_STACKSEG_END
/* Define if you have alloca, as a function or macro. */
#undef HAVE_ALLOCA
/* Define if you have <alloca.h> and it should be used (not on Ultrix). */
#undef HAVE_ALLOCA_H
/* Define if you don't have vprintf but do have _doprnt. */
#undef HAVE_DOPRNT
/* Define if you have a working `mmap' system call. */
#undef HAVE_MMAP
/* Define if you have the vprintf function. */
#undef HAVE_VPRINTF
/* Define as the return type of signal handlers (int or void). */
#undef RETSIGTYPE
/* Define to `unsigned' if <sys/types.h> doesn't define. */
#undef size_t
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown
*/
#undef STACK_DIRECTION
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define if you have the getpagesize function. */
#undef HAVE_GETPAGESIZE
/* Define if you have the gettimeofday function. */
#undef HAVE_GETTIMEOFDAY
/* Define if you have the select function. */
#undef HAVE_SELECT
/* Define if you have the socket function. */
#undef HAVE_SOCKET
/* Define if you have the strdup function. */
#undef HAVE_STRDUP
/* Define if you have the strerror function. */
#undef HAVE_STRERROR
/* Define if you have the strtod function. */
#undef HAVE_STRTOD
/* Define if you have the strtol function. */
#undef HAVE_STRTOL
/* Define if you have the strtoul function. */
#undef HAVE_STRTOUL
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <openssl/ssl.h> header file. */
#undef HAVE_OPENSSL_SSL_H
/* Define if you have the <sys/ioctl.h> header file. */
#undef HAVE_SYS_IOCTL_H
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the crypto library (-lcrypto). */
#undef HAVE_LIBCRYPTO
/* Define if you have the m library (-lm). */
#undef HAVE_LIBM
/* Define if you have the ssl library (-lssl). */
#undef HAVE_LIBSSL
/* Define if you have Open SSL (header files, libssl.a, libcrypto.a). */
#undef HAVE_SSL
/* Define to the size of a long (in bytes). */
#undef SIZEOF_LONG
/* Define to `unsigned char' if <sys/types.h> doesn't define. */
#undef u_char
/* Define to `unsigned short' if <sys/types.h> doesn't define. */
#undef u_short
/* Define to `unsigned int' if <sys/types.h> doesn't define. */
#undef u_int
/* Define to `unsigned long' if <sys/types.h> doesn't define. */
#undef u_long
/* Define to widest `unsigned' integer type available. */
#undef u_wide
This diff is collapsed.
This diff is collapsed.
dnl Process this file with autoconf to produce a configure script.
AC_INIT(timer.h)
AC_CONFIG_HEADER(config.h)
AC_ARG_ENABLE(debug, [ --enable-debug enable debug support])
if test "$enable_debug" = yes; then
CPPFLAGS="${CPPFLAGS} -DDEBUG"
else
CPPFLAGS="${CPPFLAGS} -DNDEBUG"
fi
CPPFLAGS="${CPPFLAGS} -D_GNU_SOURCE -D_XOPEN_SOURCE"
LDFLAGS="${LDFLAGS}"
dnl Checks for programs.
AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_MAKE_SET
AC_PROG_RANLIB
AC_PROG_GCC_TRADITIONAL
AC_CANONICAL_SYSTEM
if test "$GCC" = "yes"; then
CFLAGS="${CFLAGS} -Wall"
else
# ugly, there's gotta be a better way to do this...
case "${build_os}" in
hpux*)
CPPFLAGS="${CPPFLAGS} -Ae"
CFLAGS="${CFLAGS} +ESlit"
if test "$enable_debug" != yes; then
CFLAGS="${CFLAGS} +O2"
fi
;;
esac
fi
dnl Checks for libraries.
dnl Replace `main' with a function in -lm:
AC_CHECK_LIB(m, main)
AC_CHECK_LIB(crypto, main)
AC_CHECK_LIB(ssl, SSL_version)
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h unistd.h openssl/ssl.h)
if test "$ac_cv_header_openssl_ssl_h" = "yes" \
-a "$ac_cv_lib_ssl_SSL_version" = "yes" \
-a "$ac_cv_lib_crypto_main" = "yes"; then
AC_DEFINE(HAVE_SSL)
fi
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_SIZE_T
AC_TYPE_LONG_LONG
AC_HEADER_TIME
AC_CHECK_SIZEOF(long)
AC_CHECK_TYPE(u_char, unsigned char)
AC_CHECK_TYPE(u_short, unsigned short)
AC_CHECK_TYPE(u_int, unsigned int)
AC_CHECK_TYPE(u_long, unsigned long)
dnl Checks for library functions.
AC_FUNC_ALLOCA
AC_FUNC_MMAP
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(gettimeofday select socket strdup strerror strtod strtol \
strtoul getopt_long)
AC_OUTPUT(stat/Makefile lib/Makefile Makefile gen/Makefile)
/*
httperf -- a tool for measuring web server performance
Copyright (C) 2000 Hewlett-Packard Company
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of httperf, a web server performance measurment
tool.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
*/
#include "config.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <httperf.h>
#include <conn.h>
void
conn_init (Conn *conn)
{
conn->hostname = param.server;
conn->hostname_len = strlen (param.server);
conn->port = param.port;
conn->sd = -1;
conn->myport = -1;
conn->line.iov_base = conn->line_buf;
if (param.server_name)
{
conn->fqdname = param.server_name;
conn->fqdname_len = strlen (param.server_name);
}
else
{
conn->fqdname = conn->hostname;
conn->fqdname_len = conn->hostname_len;
}
#ifdef HAVE_SSL
if (param.use_ssl)
{
conn->ssl = SSL_new (ssl_ctx);
if (!conn->ssl)
{
ERR_print_errors_fp (stderr);
exit (-1);
}
if (param.ssl_cipher_list)
{
/* set order of ciphers */
int ssl_err = SSL_set_cipher_list (conn->ssl, param.ssl_cipher_list);
if (DBG > 2)
fprintf (stderr, "core_ssl_connect: set_cipher_list returned %d\n",
ssl_err);
}
}
#endif
}
void
conn_deinit (Conn *conn)
{
assert (conn->sd < 0 && conn->state != S_FREE);
assert (!conn->sendq);
assert (!conn->recvq);
assert (!conn->watchdog);
conn->state = S_FREE;
#ifdef HAVE_SSL
if (param.use_ssl)
SSL_free (conn->ssl);
#endif
}
/*
httperf -- a tool for measuring web server performance
Copyright (C) 2000 Hewlett-Packard Company
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of httperf, a web server performance measurment
tool.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA
*/
#ifndef conn_h
#define conn_h
#include "config.h"
#include <sys/uio.h>
#include <httperf.h>
#include <object.h>
#include <timer.h>
#ifdef HAVE_SSL
# include <openssl/ssl.h>
# include <openssl/err.h>
#endif
/* Maximum header line length that we can process properly. Longer
lines will be treated as if they were only this long (i.e., they
will be truncated). */
#define MAX_HDR_LINE_LEN 1024
struct Call;
typedef enum Conn_State