From eb5f55b356bb195e1469c6638502a997eca33a91 Mon Sep 17 00:00:00 2001 From: wessels <> Date: Tue, 25 Nov 1997 06:05:16 +0000 Subject: [PATCH] adding --- test-suite/pconn-banger.c | 397 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 397 insertions(+) create mode 100644 test-suite/pconn-banger.c diff --git a/test-suite/pconn-banger.c b/test-suite/pconn-banger.c new file mode 100644 index 0000000000..a6dc064810 --- /dev/null +++ b/test-suite/pconn-banger.c @@ -0,0 +1,397 @@ +#include "config.h" + +/* + * On some systems, FD_SETSIZE is set to something lower than the + * actual number of files which can be opened. IRIX is one case, + * NetBSD is another. So here we increase FD_SETSIZE to our + * configure-discovered maximum *before* any system includes. + */ +#define CHANGE_FD_SETSIZE 1 + +/* Cannot increase FD_SETSIZE on Linux */ +#if defined(_SQUID_LINUX_) +#undef CHANGE_FD_SETSIZE +#define CHANGE_FD_SETSIZE 0 +#endif + +/* Cannot increase FD_SETSIZE on FreeBSD before 2.2.0, causes select(2) + * to return EINVAL. */ +/* Marian Durkovic */ +/* Peter Wemm */ +#if defined(_SQUID_FREEBSD_) +#include +#if __FreeBSD_version < 220000 +#undef CHANGE_FD_SETSIZE +#define CHANGE_FD_SETSIZE 0 +#endif +#endif + +/* Increase FD_SETSIZE if SQUID_MAXFD is bigger */ +#if CHANGE_FD_SETSIZE && SQUID_MAXFD > DEFAULT_FD_SETSIZE +#define FD_SETSIZE SQUID_MAXFD +#endif + +#if HAVE_UNISTD_H +#include +#endif +#if HAVE_STDLIB_H +#include +#endif +#if HAVE_STDIO_H +#include +#endif +#if HAVE_FCNTL_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STRINGS_H +#include +#endif +#ifdef HAVE_BSTRING_H +#include +#endif +#if HAVE_SYS_TYPES_H +#include +#endif +#if HAVE_SYS_SELECT_H +#include +#endif +#if HAVE_SIGNAL_H +#include +#endif +#if HAVE_TIME_H +#include +#endif +#if HAVE_SYS_TIME_H +#include +#endif +#if HAVE_SYS_SOCKET_H +#include +#endif +#if HAVE_NETINET_IN_H +#include +#endif +#if HAVE_ARPA_INET_H +#include +#endif +#if HAVE_ERRNO_H +#include +#endif +#if HAVE_CTYPE_H +#include +#endif +#if HAVE_ASSERT_H +#include +#endif + +#define PROXY_PORT 3128 +#define PROXY_ADDR "127.0.0.1" +#define MAX_FDS 1024 +#define READ_BUF_SZ 4096 +#define min(x,y) ((x)<(y)? (x) : (y)) + +static int proxy_port = PROXY_PORT; +static char *proxy_addr = PROXY_ADDR; +static char *progname; +static int noutstanding = 0; +static int done_reading_urls = 0; +static int opt_ims = 0; +static int max_connections = 64; +static time_t lifetime = 60; +static const char *const crlf = "\r\n"; + +#define REPLY_HDR_SZ 8192 + +struct _r { + char *url; + int content_length; + int hdr_length; + int hdr_offset; + int bytes_read; + char reply_hdrs[REPLY_HDR_SZ]; + struct _r *next; +}; + +static struct _r *Requests; + +char * +mkrfc850(t) + time_t *t; +{ + static char buf[128]; + struct tm *gmt = gmtime(t); + buf[0] = '\0'; + (void) strftime(buf, 127, "%A, %d-%b-%y %H:%M:%S GMT", gmt); + return buf; +} + + +char * +mime_headers_end(const char *mime) +{ + const char *p1, *p2; + const char *end = NULL; + + p1 = strstr(mime, "\n\r\n"); + p2 = strstr(mime, "\n\n"); + + if (p1 && p2) + end = p1 < p2 ? p1 : p2; + else + end = p1 ? p1 : p2; + if (end) + end += (end == p1 ? 3 : 2); + + return (char *) end; +} + +void +sig_intr(int sig) +{ + printf("\rWaiting for open connections to finish...\n"); + signal(sig, SIG_DFL); +} + +int +open_http_socket(void) +{ + int s; + struct sockaddr_in S; + if ((s = socket(PF_INET, SOCK_STREAM, 0)) < 0) { + perror("socket"); + return -1; + } + memset(&S, '\0', sizeof(struct sockaddr_in)); + S.sin_family = AF_INET; + S.sin_port = htons(proxy_port); + S.sin_addr.s_addr = inet_addr(proxy_addr); + if (connect(s, (struct sockaddr *) &S, sizeof(S)) < 0) { + close(s); + perror("connect"); + return -1; + } + return s; +} + +int +send_request(int fd, const char *url) +{ + char buf[4096]; + int len; + time_t w; + struct _r *r; + struct _r **R; + buf[0] = '\0'; + strcat(buf, "GET "); + strcat(buf, url); + strcat(buf, " HTTP/1.0\r\n"); + strcat(buf, "Accept: */*\r\n"); + strcat(buf, "Proxy-Connection: Keep-Alive\r\n"); + if (opt_ims && (lrand48() & 0x03) == 0) { + w = time(NULL) - (lrand48() & 0x3FFFF); + strcat(buf, "If-Modified-Since: "); + strcat(buf, mkrfc850(&w)); + strcat(buf, "\r\n"); + } + strcat(buf, "\r\n"); + len = strlen(buf); + if (write(fd, buf, len) < 0) { + close(fd); + perror("write"); + return -1; + } + r = calloc(1, sizeof(struct _r)); + r->url = strdup(url); + for (R = &Requests; *R; R = &(*R)->next); + *R = r; + fprintf(stderr, "REQUESTED %s\n", url); + noutstanding++; + return 0; +} + +static int +get_header_int_value(const char *hdr, const char *buf, const char *end) +{ + const char *t; + for (t = buf; t < end; t += strcspn(t, crlf), t += strspn(t, crlf)) { + if (strncasecmp(t, hdr, strlen(hdr)) == 0) { + t += strlen(hdr); + while (isspace(*t)) + t++; + return atoi(t); + } + } + return 0; +} + +int +handle_read(char *buf, int len) +{ + struct _r *r = Requests; + const char *end; + int hlen; + if (len < 0) { + perror("read"); + Requests = r->next; + return -1; + } + if (len == 0) { + fprintf(stderr, "DONE: %s, server closed socket, read %d bytes\n", r->url, r->bytes_read); + Requests = r->next; + free(r); + noutstanding--; + return -1; + } + if (r->hdr_length == 0) { + hlen = min(len, REPLY_HDR_SZ - r->hdr_length); + strncpy(r->reply_hdrs + r->hdr_length, buf, hlen); + r->hdr_offset += hlen; + *(r->reply_hdrs + REPLY_HDR_SZ - 1) = '\0'; + } + if (r->hdr_length == 0 && (end = mime_headers_end(r->reply_hdrs)) != NULL) { + fprintf(stderr, "FOUND EOH FOR %s\n", r->url); + r->hdr_length = end - r->reply_hdrs; + fprintf(stderr, "HDR_LENGTH = %d\n", r->hdr_length); + r->content_length = get_header_int_value("content-length:", r->reply_hdrs, end); + fprintf(stderr, "CONTENT_LENGTH = %d\n", r->content_length); + } + if (r->content_length && r->hdr_length) { + int bytes_left = r->content_length + r->hdr_length - r->bytes_read; + int bytes_used = len > bytes_left ? bytes_left : len; + r->bytes_read += bytes_used; + len -= bytes_used; + if (r->bytes_read == r->content_length + r->hdr_length) { + fprintf(stderr, "DONE: %s, (%d == %d+%d)\n", + r->url, + r->bytes_read, + r->hdr_length, + r->content_length); + Requests = r->next; + free(r); + noutstanding--; + } else { + assert(r->bytes_read < r->content_length + r->hdr_length); + } + if (len) { + assert(bytes_used > 0); + memmove(buf, buf + bytes_used, len); + return handle_read(buf, len); + } + } + return 0; +} + +int +read_reply(int fd) +{ + static char buf[READ_BUF_SZ]; + int len; + int x; + len = read(fd, buf, READ_BUF_SZ); + x = handle_read(buf, len); + if (x < 0) + close(fd); + return x; +} + +void +main_loop(void) +{ + static int pconn_fd = -1; + static char buf[8192]; + struct timeval to; + fd_set R; + struct _r *r; + struct _r *nextr; + int x; + while (!done_reading_urls || noutstanding) { + if (pconn_fd < 0) { + pconn_fd = open_http_socket(); + if (pconn_fd < 0) { + perror("socket"); + exit(1); + } + nextr = Requests; + Requests = NULL; + while ((r = nextr) != NULL) { + nextr = r->next; + send_request(pconn_fd, r->url); + free(r); + noutstanding--; + } + } + if (noutstanding < 10 && !done_reading_urls) { + char *t; + if (fgets(buf, 8191, stdin) == NULL) { + printf("Done Reading URLS\n"); + done_reading_urls = 1; + break; + } + if ((t = strchr(buf, '\n'))) + *t = '\0'; + send_request(pconn_fd, buf); + } + FD_ZERO(&R); + to.tv_sec = 1; + to.tv_usec = 0; + FD_SET(pconn_fd, &R); + x = select(pconn_fd + 1, &R, NULL, NULL, &to); + if (x < 0) { + if (errno != EINTR) + perror("select"); + continue; + } else if (x == 0) { + assert(Requests != NULL); + fprintf(stderr, "TIMEOUT waiting for %s\n", Requests->url); + continue; + } + if (FD_ISSET(pconn_fd, &R)) { + if (read_reply(pconn_fd) != 0) + pconn_fd = -1; + } + } +} + +void +usage(void) +{ + fprintf(stderr, "usage: %s: -p port -h host -n max\n", progname); +} + +int +main(argc, argv) + int argc; + char *argv[]; +{ + int c; + setbuf(stdout, NULL); + setbuf(stderr, NULL); + progname = strdup(argv[0]); + while ((c = getopt(argc, argv, "p:h:n:il:")) != -1) { + switch (c) { + case 'p': + proxy_port = atoi(optarg); + break; + case 'h': + proxy_addr = strdup(optarg); + break; + case 'n': + max_connections = atoi(optarg); + break; + case 'i': + opt_ims = 1; + break; + case 'l': + lifetime = (time_t) atoi(optarg); + break; + default: + usage(); + return 1; + } + } + signal(SIGINT, sig_intr); + main_loop(); + return 0; +} -- 2.39.5