/[hyperestraier]/upstream/0.5.3/estload.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /upstream/0.5.3/estload.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10 - (hide annotations)
Wed Aug 3 15:25:48 2005 UTC (18 years, 9 months ago) by dpavlin
File MIME type: text/plain
File size: 9739 byte(s)
import of upstream 0.5.3

1 dpavlin 2 /*************************************************************************************************
2     * The load tester for web applications
3     * Copyright (C) 2004-2005 Mikio Hirabayashi
4     * This file is part of Hyper Estraier.
5     * Hyper Estraier is free software; you can redistribute it and/or modify it under the terms of
6     * the GNU Lesser General Public License as published by the Free Software Foundation; either
7     * version 2.1 of the License or any later version. Hyper Estraier is distributed in the hope
8     * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
9     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
10     * License for more details.
11     * You should have received a copy of the GNU Lesser General Public License along with Hyper
12     * Estraier; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
13     * Boston, MA 02111-1307 USA.
14     *************************************************************************************************/
15    
16    
17     #include "estraier.h"
18     #include "estmtdb.h"
19     #include "estnode.h"
20     #include "myconf.h"
21    
22 dpavlin 9 #define AGENTNAME "EstLoad" /* name of the user agent */
23 dpavlin 2 #define IOBUFSIZ 8192 /* size of a buffer for I/O */
24    
25     typedef struct { /* type of structure for a target URL */
26     char *host; /* hostname */
27     char *addr; /* IP address */
28     int port; /* port number */
29     char *auth; /* authority */
30     char *path; /* path */
31     char *query; /* query string */
32     } TARGET;
33    
34     typedef struct { /* type of structure for a worker thread */
35     int id; /* ID number */
36     int ims; /* interval time in milliseconds */
37     int pb; /* to print received data */
38     int qb; /* to be quiet */
39     CBLIST *targets; /* list of targets */
40     int alive; /* to be alive */
41     } MISSION;
42    
43    
44     /* global variables */
45     const char *g_progname; /* program name */
46    
47    
48     /* function prototypes */
49     int main(int argc, char **argv);
50     static void usage(void);
51     static void printferror(const char *format, ...);
52     static void printfinfo(const char *format, ...);
53     static int procmain(const char *file, int tnum, int lnum, int ims, int pb, int qb);
54     static void *procthread(void *arg);
55    
56    
57     /* main routine */
58     int main(int argc, char **argv){
59     char *file;
60     int i, tnum, lnum, ims, pb, qb, rv;
61     cbstdiobin();
62     g_progname = argv[0];
63     if(!est_init_net_env()){
64     printferror("could not initialize network environment");
65     exit(1);
66     }
67     atexit(est_free_net_env);
68     file = NULL;
69     tnum = 1;
70     lnum = 1;
71     ims = 0;
72     pb = FALSE;
73     qb = FALSE;
74     for(i = 1; i < argc; i++){
75     if(!file && argv[i][0] == '-'){
76     if(!strcmp(argv[i], "-t")){
77     if(++i >= argc) usage();
78     tnum = atoi(argv[i]);
79     } else if(!strcmp(argv[i], "-l")){
80     if(++i >= argc) usage();
81     lnum = atoi(argv[i]);
82     } else if(!strcmp(argv[i], "-i")){
83     if(++i >= argc) usage();
84     ims = atoi(argv[i]);
85     } else if(!strcmp(argv[i], "-p")){
86     pb = TRUE;
87     } else if(!strcmp(argv[i], "-q")){
88     qb = TRUE;
89     } else {
90     usage();
91     }
92     } else if(!file){
93     file = argv[i];
94     } else {
95     usage();
96     }
97     }
98     if(!file || tnum < 1 || lnum < 1) usage();
99     rv = procmain(file, tnum, lnum, ims, pb, qb);
100     return rv;
101     }
102    
103    
104     /* print the usage and exit */
105     static void usage(void){
106     fprintf(stderr, "%s: stresser for web applications\n", g_progname);
107     fprintf(stderr, "\n");
108     fprintf(stderr, "usage:\n");
109     fprintf(stderr, " %s [-t num] [-l num] [-i num] [-p] [-q] [file|url]\n", g_progname);
110     fprintf(stderr, "\n");
111     exit(1);
112     }
113    
114    
115     /* print formatted error string and flush the buffer */
116     static void printferror(const char *format, ...){
117     va_list ap;
118     va_start(ap, format);
119     fprintf(stderr, "%s: ERROR: ", g_progname);
120     vfprintf(stderr, format, ap);
121     fputc('\n', stderr);
122     fflush(stderr);
123     va_end(ap);
124     }
125    
126    
127     /* print formatted information string and flush the buffer */
128     static void printfinfo(const char *format, ...){
129     va_list ap;
130     va_start(ap, format);
131     printf("%s: INFO: ", g_progname);
132     vprintf(format, ap);
133     putchar('\n');
134     fflush(stdout);
135     va_end(ap);
136     }
137    
138    
139     /* proc the main command */
140     static int procmain(const char *file, int tnum, int lnum, int ims, int pb, int qb){
141     pthread_t *threads;
142     MISSION *missions;
143     TARGET target;
144     CBLIST *list;
145     CBMAP *elems;
146     const char *line, *host, *pstr, *auth, *path, *query;
147     int i, j, cnt, pnum, err;
148     double etime;
149     if(cbstrfwimatch(file, "http://")){
150     list = cblistopen();
151     cblistpush(list, file, -1);
152     } else if(!(list = cbreadlines(file))){
153     printferror("%s: could not open", file);
154     return 1;
155     }
156     threads = cbmalloc(tnum * sizeof(pthread_t));
157     missions = cbmalloc(tnum * sizeof(MISSION));
158     for(i = 0; i < tnum; i++){
159     missions[i].id = i + 1;
160     missions[i].ims = ims;
161     missions[i].pb = pb;
162     missions[i].qb = qb;
163     missions[i].targets = cblistopen();
164     }
165     cnt = 0;
166     for(i = 0; i < lnum; i++){
167     for(j = 0; j < cblistnum(list); j++){
168     line = cblistval(list, j, NULL);
169     if((line[0] == '\0')) continue;
170     elems = cburlbreak(line);
171     host = cbmapget(elems, "host", -1, NULL);
172     pnum = (pstr = cbmapget(elems, "port", -1, NULL)) ? atoi(pstr) : 80;
173     auth = cbmapget(elems, "authority", -1, NULL);
174     path = cbmapget(elems, "path", -1, NULL);
175     query = cbmapget(elems, "query", -1, NULL);
176     if(!host || pnum < 1){
177     printferror("%s: invalid URL", line);
178     cbmapclose(elems);
179     continue;
180     }
181     if(!auth) auth = "";
182     if(!path) path = "/";
183     if(!query) query = "";
184     if(!(target.addr = est_get_host_addr(host))){
185     printferror("%s: unknown host", host);
186     cbmapclose(elems);
187     continue;
188     }
189     target.host = cbmemdup(host, -1);
190     target.port = pnum;
191     target.auth = cbmemdup(auth, -1);
192     target.path = cbmemdup(path, -1);
193     target.query = cbmemdup(query, -1);
194     cblistpush(missions[cnt++%tnum].targets, (char *)&target, sizeof(TARGET));
195     cbmapclose(elems);
196     }
197     }
198     cblistclose(list);
199     err = FALSE;
200     etime = est_gettimeofday();
201     if(tnum > 1){
202     for(i = 0; i < tnum; i++){
203     missions[i].alive = FALSE;
204     if(pthread_create(threads + i, NULL, procthread, missions + i) == 0){
205     missions[i].alive = TRUE;
206     } else {
207     printferror("thread creation failed");
208     err = TRUE;
209     }
210     }
211     for(i = 0; i < tnum; i++){
212     if(!missions[i].alive) continue;
213     if(pthread_join(threads[i], NULL) != 0){
214     printferror("thread join failed");
215     err = TRUE;
216     }
217     }
218     } else {
219     procthread(missions);
220     }
221     etime = est_gettimeofday() - etime;
222     if(cnt > 0 && !err)
223     printfinfo("finished: elepsed time: %.3f sec. (average: %.3f)",
224     etime / 1000, etime / cnt / 1000);
225     for(i = 0; i < tnum; i++){
226     for(j = 0; j < cblistnum(missions[i].targets); j++){
227     target = *(TARGET *)cblistval(missions[i].targets, j, NULL);
228     free(target.query);
229     free(target.path);
230     free(target.auth);
231     free(target.addr);
232     free(target.host);
233     }
234     cblistclose(missions[i].targets);
235     }
236     free(missions);
237     free(threads);
238     return err ? 1 : 0;
239     }
240    
241    
242     /* process as a child thread */
243     static void *procthread(void *arg){
244     CBLIST *targets;
245     TARGET target;
246     char iobuf[IOBUFSIZ], *wp, *tmp;
247     int i, id, ims, pb, qb, clsock, size;
248     double etime;
249     targets = ((MISSION *)arg)->targets;
250     id = ((MISSION *)arg)->id;
251     ims = ((MISSION *)arg)->ims;
252     pb = ((MISSION *)arg)->pb;
253     qb = ((MISSION *)arg)->qb;
254     if(cblistnum(targets) < 1) return NULL;
255     printfinfo("%d: started", id);
256     etime = est_gettimeofday();
257     for(i = 0; i < cblistnum(targets); i++){
258     target = *(TARGET *)cblistval(targets, i, NULL);
259     if(!qb) printfinfo("%d(%d/%d): http://%s:%d%s%s%s",
260     id, i + 1, cblistnum(targets), target.host, target.port,
261     target.path, target.query[0] != '\0' ? "?" : "", target.query);
262     if((clsock = est_get_client_sock(target.addr, target.port)) != -1){
263     wp = iobuf;
264     wp += sprintf(wp, "GET %s%s%s HTTP/1.0\r\n",
265     target.path, target.query[0] != '\0' ? "?" : "", target.query);
266     wp += sprintf(wp, "Host: %s:%d\r\n", target.host, target.port);
267     wp += sprintf(wp, "Connection: close\r\n");
268     if(target.auth[0] != '\0'){
269     tmp = cbbaseencode(target.auth, -1);
270     wp += sprintf(wp, "Authorization: Basic %s\r\n", tmp);
271     free(tmp);
272     }
273     wp += sprintf(wp, "Referer: http://%s:%d%s%s%s\r\n", target.host, target.port,
274     target.path, target.query[0] != '\0' ? "?" : "", target.query);
275     wp += sprintf(wp, "User-Agent: %s/%s\r\n", AGENTNAME, est_version);
276     wp += sprintf(wp, "\r\n");
277     est_sock_send_all(clsock, iobuf, wp - iobuf);
278     while((size = recv(clsock, iobuf, IOBUFSIZ, 0)) > 0){
279     if(pb) fwrite(iobuf, 1, size, stdout);
280     }
281     est_sock_down(clsock);
282     } else {
283     printferror("%d(%d/%d): connection failed", id, i + 1, cblistnum(targets));
284     }
285     if(ims > 0) est_usleep(ims * 1000);
286     }
287     etime = est_gettimeofday() - etime;
288     printfinfo("%d: finished: elapsed time: %.3f sec. (average: %.3f)",
289     id, etime / 1000, etime / cblistnum(targets) / 1000);
290     return NULL;
291     }
292    
293    
294    
295     /* END OF FILE */

  ViewVC Help
Powered by ViewVC 1.1.26