"Fossies" - the Fresh Open Source Software Archive 
Member "httperf-0.9.0/src/stat/print_reply.c" (7 Apr 2007, 7324 Bytes) of package /linux/www/old/httperf-0.9.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "print_reply.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 httperf -- a tool for measuring web server performance
3 Copyright 2000-2007 Hewlett-Packard Company and Contributors listed in
4 AUTHORS file. Originally contributed by David Mosberger-Tang
5
6 This file is part of httperf, a web server performance measurment
7 tool.
8
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License as
11 published by the Free Software Foundation; either version 2 of the
12 License, or (at your option) any later version.
13
14 In addition, as a special exception, the copyright holders give
15 permission to link the code of this work with the OpenSSL project's
16 "OpenSSL" library (or with modified versions of it that use the same
17 license as the "OpenSSL" library), and distribute linked combinations
18 including the two. You must obey the GNU General Public License in
19 all respects for all of the code used other than "OpenSSL". If you
20 modify this file, you may extend this exception to your version of the
21 file, but you are not obligated to do so. If you do not wish to do
22 so, delete this exception statement from your version.
23
24 This program is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 General Public License for more details.
28
29 You should have received a copy of the GNU General Public License
30 along with this program; if not, write to the Free Software
31 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
32 02110-1301, USA
33 */
34
35 /* This statistics collector simply prints the replies received from
36 the server. */
37
38 #include <assert.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include <httperf.h>
44 #include <call.h>
45 #include <conn.h>
46 #include <event.h>
47
48 typedef struct Call_Private_Data
49 {
50 int done_with_reply_hdr; /* are we done printing reply header? */
51 size_t size; /* number of bytes allocated for "line" buffer */
52 size_t len; /* current length of line buffer */
53 char *line; /* line buffer */
54 }
55 Call_Private_Data;
56
57 #define CALL_PRIVATE_DATA(c) \
58 ((Call_Private_Data *) ((char *)(c) + call_private_data_offset))
59
60 static size_t call_private_data_offset = -1;
61
62 static void
63 flush_print_buf (Call *call, const char *prefix)
64 {
65 Call_Private_Data *priv = CALL_PRIVATE_DATA (call);
66
67 if (priv->len)
68 printf ("%s%ld:%.*s\n", prefix, call->id, (int) priv->len, priv->line);
69 priv->len = 0;
70 }
71
72 static void
73 print_buf (Call *call, const char *prefix, const char *buf, int len)
74 {
75 Call_Private_Data *priv = CALL_PRIVATE_DATA (call);
76 const char *eol, *end;
77 size_t line_len;
78
79 for (end = buf + len; buf < end; buf += line_len)
80 {
81 line_len = (end - buf);
82 eol = strchr (buf, '\n');
83 if (eol)
84 {
85 /* got a complete line: print it */
86 line_len = eol - buf;
87 printf ("%s%ld:", prefix, call->id);
88
89 if (priv->len)
90 printf ("%.*s", (int) priv->len, priv->line);
91 priv->len = 0;
92
93 if (line_len > 0)
94 printf ("%.*s", (int) line_len, buf);
95 putchar ('\n');
96
97 ++line_len; /* skip over newline */
98 }
99 else
100 {
101 /* got a partial line: buffer it */
102 if (priv->len + line_len > priv->size)
103 {
104 priv->size = priv->len + line_len;
105 if (priv->line)
106 priv->line = realloc (priv->line, priv->size);
107 else
108 priv->line = malloc (priv->size);
109 if (!priv->line)
110 {
111 fprintf (stderr, "%s.print_buf: Out of memory\n", prog_name);
112 exit (1);
113 }
114 }
115 memcpy (priv->line + priv->len, buf, line_len);
116 priv->len += line_len;
117 }
118 }
119 }
120
121 static void
122 print_request (Call *call)
123 {
124 size_t hdr_len, h_len, b_len;
125 int i, first, end;
126 char *hdr;
127
128 first = IE_CONTENT;
129 end = IE_CONTENT;
130
131 if ((param.print_request & PRINT_HEADER) != 0)
132 first = IE_METHOD;
133
134 if ((param.print_request & PRINT_BODY) != 0)
135 end = IE_LEN;
136
137 for (i = first; i < end; ++i)
138 {
139 hdr = call->req.iov[i].iov_base;
140 hdr_len = call->req.iov[i].iov_len;
141
142 if (hdr_len)
143 print_buf (call, (i < IE_CONTENT) ? "SH" : "SB", hdr, hdr_len);
144 }
145
146 for (h_len = 0, i = IE_METHOD; i < IE_CONTENT; ++i)
147 h_len += call->req.iov[i].iov_len;
148
149 for (b_len = 0, i = IE_CONTENT; i < IE_LEN; ++i)
150 b_len += call->req.iov[i].iov_len;
151
152 printf ("SS%ld: header %ld content %ld\n",
153 call->id, (long) h_len, (long) b_len);
154 }
155
156 static void
157 print_reply_hdr (Call *call, const char *buf, int len)
158 {
159 Call_Private_Data *priv = CALL_PRIVATE_DATA (call);
160 const char *eoh;
161
162 if (len <= 0 || priv->done_with_reply_hdr)
163 return;
164
165 eoh = strstr (buf, "\r\n\r\n");
166 if (eoh)
167 {
168 priv->done_with_reply_hdr = 1;
169 eoh += 4;
170 }
171 else
172 {
173 /* no CRLFCRLF: non-conforming server */
174 eoh = strstr (buf, "\n\n");
175 if (eoh)
176 {
177 priv->done_with_reply_hdr = 1;
178 eoh += 2;
179 }
180 else
181 eoh = buf + len;
182 }
183 print_buf (call, "RH", buf, eoh - buf);
184 }
185
186 static void
187 call_destroyed (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
188 {
189 Call_Private_Data *priv;
190 Call *call;
191
192 assert (et == EV_CALL_DESTROYED && object_is_call (obj));
193 call = (Call *) obj;
194 priv = CALL_PRIVATE_DATA (call);
195
196 if (priv->line)
197 free (priv->line);
198 }
199
200 static void
201 send_raw_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
202 {
203 Call *call;
204
205 assert (et == EV_CALL_SEND_RAW_DATA && object_is_call (obj));
206 call = (Call *) obj;
207
208 print_request (call);
209 }
210
211 static void
212 recv_raw_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
213 {
214 struct iovec *iov;
215 Call *call;
216
217 assert (et == EV_CALL_RECV_RAW_DATA && object_is_call (obj));
218 call = (Call *) obj;
219 iov = callarg.vp;
220
221 print_reply_hdr (call, iov->iov_base, iov->iov_len);
222 }
223
224 static void
225 recv_data (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
226 {
227 struct iovec *iov;
228 Call *call;
229
230 assert (et == EV_CALL_RECV_DATA && object_is_call (obj));
231 call = (Call *) obj;
232 iov = callarg.vp;
233
234 print_buf (call, "RB", iov->iov_base, iov->iov_len);
235 }
236
237 static void
238 recv_stop (Event_Type et, Object *obj, Any_Type regarg, Any_Type callarg)
239 {
240 Call *call;
241
242 assert (et == EV_CALL_RECV_STOP && object_is_call (obj));
243 call = (Call *) obj;
244
245 flush_print_buf (call, "RB");
246
247 printf ("RS%ld: header %ld content %ld footer %ld\n",
248 call->id, (long) call->reply.header_bytes,
249 (long) call->reply.content_bytes, (long) call->reply.footer_bytes);
250 }
251
252 static void
253 init (void)
254 {
255 Any_Type arg;
256
257 call_private_data_offset = object_expand (OBJ_CALL,
258 sizeof (Call_Private_Data));
259 arg.l = 0;
260 if ((param.print_request & (PRINT_HEADER | PRINT_BODY)) != 0)
261 event_register_handler (EV_CALL_SEND_RAW_DATA, send_raw_data, arg);
262 if ((param.print_reply & PRINT_HEADER) != 0)
263 event_register_handler (EV_CALL_RECV_RAW_DATA, recv_raw_data, arg);
264 if ((param.print_reply & PRINT_BODY) != 0)
265 event_register_handler (EV_CALL_RECV_DATA, recv_data, arg);
266 if ((param.print_reply & (PRINT_HEADER | PRINT_BODY)) != 0)
267 event_register_handler (EV_CALL_RECV_STOP, recv_stop, arg);
268 event_register_handler (EV_CALL_DESTROYED, call_destroyed, arg);
269 }
270
271 Stat_Collector stats_print_reply =
272 {
273 "Reply printer",
274 init,
275 no_op,
276 no_op,
277 no_op
278 };