3
A brief file description
5
@section license License
7
Licensed to the Apache Software Foundation (ASF) under one
8
or more contributor license agreements. See the NOTICE file
9
distributed with this work for additional information
10
regarding copyright ownership. The ASF licenses this file
11
to you under the Apache License, Version 2.0 (the
12
"License"); you may not use this file except in compliance
13
with the License. You may obtain a copy of the License at
15
http://www.apache.org/licenses/LICENSE-2.0
17
Unless required by applicable law or agreed to in writing, software
18
distributed under the License is distributed on an "AS IS" BASIS,
19
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
See the License for the specific language governing permissions and
21
limitations under the License.
28
* - Generate requests to the web servers listed in the files specified
29
* in the request lists, specified in the configuration file.
30
* Also use the ratio specified with the request lists to generate the
31
* right distribution of requests.
34
* Added Options in SDKtest_client.config -
35
* request_lists : full path of the file[s] that contain the
36
* request lists. Also need to specify the
37
* request ratio. Example :
38
* request_lists=/home/bob/list1:20,/home/bob/list2:80
39
* Note: comma is the seperator. do not leave space or tabs inbetween
40
* This will cause 20 % of requests to go from list1 and
42
* Note : the ratios MUST add upto 100.
45
#include "ClientAPI.h"
53
#define MAX_URL_SIZE 256
55
#define MAX_FILE_NAME_SIZE 512
56
#define MAX_SMALL_NAME 10
64
/* helper functions */
65
void read_host(FILE * url, char *buffer, int buf_size);
66
int select_url_catagory();
75
/* for determining if we submit request to TS or not */
80
/* for request lists */
81
FILE *list_fp[MAX_LISTS];
82
char *list_str[MAX_LISTS];
83
double list_ratio[MAX_LISTS];
84
int list_requests[MAX_LISTS];
87
/* for reporting data */
90
long successful_documents;
91
long unfinished_documents;
92
long other_failed_documents;
93
long total_bytes_received;
97
RequestListPlugin my_plugin;
100
TSPluginInit(int client_id)
102
my_plugin.requests = 0;
103
my_plugin.successful_documents = 0;
104
my_plugin.unfinished_documents = 0;
105
my_plugin.other_failed_documents = 0;
106
my_plugin.total_bytes_received = 0;
108
/* setup the callbacks */
109
TSFuncRegister(TS_FID_OPTIONS_PROCESS);
110
TSFuncRegister(TS_FID_OPTIONS_PROCESS_FINISH);
111
TSFuncRegister(TS_FID_CONNECTION_FINISH);
112
TSFuncRegister(TS_FID_PLUGIN_FINISH);
113
TSFuncRegister(TS_FID_REQUEST_CREATE);
114
TSFuncRegister(TS_FID_HEADER_PROCESS);
115
TSFuncRegister(TS_FID_PARTIAL_BODY_PROCESS);
116
TSFuncRegister(TS_FID_REPORT);
121
TSOptionsProcess(char *option, char *value)
126
if (strcmp(option, "target_host") == 0) {
127
my_plugin.target_host = strdup(value);
128
} else if (strcmp(option, "target_port") == 0) {
129
my_plugin.target_port = strdup(value);
130
} else if (strcmp(option, "request_lists") == 0) {
133
strcpy(my_value, value);
136
my_plugin.list_str[my_plugin.nlist] = strtok(my_value, ",");
138
while (my_plugin.list_str[my_plugin.nlist] != NULL) {
140
my_plugin.list_str[my_plugin.nlist] = strtok(NULL, ",");
144
for (i = 0; i < my_plugin.nlist; i++) {
145
char tmp_s[MAX_FILE_NAME_SIZE];
149
my_plugin.list_requests[i] = 0;
150
strcpy(tmp_s, my_plugin.list_str[i]);
152
fname = strtok(tmp_s, ":");
153
tmp = strtok(NULL, ":");
154
my_plugin.list_ratio[i] = (double) (atoi(tmp));
155
rsum += my_plugin.list_ratio[i];
157
if (!(my_plugin.list_fp[i] = fopen(fname, "r"))) {
158
fprintf(stderr, "Open URL file %s failed\n", fname);
164
fprintf(stderr, "Sum of ratios [%d] != 100", rsum);
173
TSOptionsProcessFinish()
175
if ((strlen(my_plugin.target_host) == 0) || (strlen(my_plugin.target_port) == 0)) {
176
my_plugin.direct = 1;
178
my_plugin.direct = 0;
183
TSConnectionFinish(void *req_id, TSConnectionStatus conn_status)
185
if (conn_status == TS_TIME_EXPIRE) {
186
my_plugin.unfinished_documents++;
195
/* do all cleanup here */
197
free(my_plugin.target_host);
198
free(my_plugin.target_port);
200
for (i = 0; i < my_plugin.nlist; i++) {
201
fclose(my_plugin.list_fp[i]);
207
TSRequestCreate(char *origin_server_host /* return */ , int max_hostname_size,
208
char *origin_server_port /* return */ , int max_portname_size,
209
char *request_buf /* return */ , int max_request_size,
210
void **req_id /* return */ )
212
/* char *portname = "80"; */
214
char *hostname = (char *) malloc(max_hostname_size + 1);
215
char *tail = (char *) malloc(max_hostname_size + 1);
217
int type = select_url_catagory();
219
strcpy(tail, "index.html");
222
char *tmp_h1 = (char *) malloc(max_hostname_size + 1);
223
char *tmp_h2 = (char *) malloc(max_hostname_size + 1);
225
my_plugin.list_requests[type]++;
226
read_host(my_plugin.list_fp[type], hostname, max_hostname_size);
228
strcpy(tmp_h1, hostname);
229
tmp_h2 = strchr(tmp_h1, ':');
231
if (tmp_h2 != NULL) {
233
char *tmp_h3 = (char *) malloc(max_hostname_size + 1);
235
lport = tmp_h2 - tmp_h1;
236
*(hostname + lport) = '\0';
237
portname = hostname + lport + 1;
239
tmp_h3 = strchr(tmp_h1, '/');
241
if (tmp_h3 != NULL) {
242
ltail = tmp_h3 - tmp_h1;
243
*(hostname + ltail) = '\0';
244
tail = hostname + ltail + 1;
248
portname = strdup("80");
251
fprintf(stderr, "ERROR: unable to select url list; select_url_catagory returned -1\n");
255
if (my_plugin.direct) {
256
strcpy(origin_server_host, hostname);
257
strcpy(origin_server_port, portname);
259
"GET /%s HTTP/1.0\r\nAccept: */*\r\nHost: %s:%s\r\n\r\n", tail, origin_server_host, origin_server_port);
261
strcpy(origin_server_host, my_plugin.target_host);
262
strcpy(origin_server_port, my_plugin.target_port);
263
sprintf(request_buf, "GET %s:%s/%s HTTP/1.0\r\nAccept: */*\r\n\r\n", hostname, portname, tail);
265
*req_id = malloc(sizeof(User));
266
my_plugin.requests++;
272
TSHeaderProcess(void *req_id, char *header, int length, char *request_str)
274
((User *) req_id)->header_bytes = length;
276
if (strstr(header, "200 OK")) {
277
return TS_KEEP_GOING;
279
my_plugin.other_failed_documents++;
286
TSPartialBodyProcess(void *req_id, void *partial_content, int partial_length, int accum_length)
288
if (partial_length == 0) {
289
my_plugin.successful_documents++;
290
my_plugin.total_bytes_received += (accum_length + ((User *) req_id)->header_bytes);
292
return TS_KEEP_GOING;
302
TSReportSingleData("Total Requests", "count", TS_SUM, (double) my_plugin.requests);
303
TSReportSingleData("Successful Documents", "count", TS_SUM, (double) my_plugin.successful_documents);
304
TSReportSingleData("Unfinished Documents", "count", TS_SUM, (double) my_plugin.unfinished_documents);
305
TSReportSingleData("Other Failed Documents", "count", TS_SUM, (double) my_plugin.other_failed_documents);
307
for (i = 0; i < my_plugin.nlist; i++) {
308
char s[MAX_FILE_NAME_SIZE + 30];
309
sprintf(s, "Total Requests from file %d", i);
310
TSReportSingleData(s, "count", TS_SUM, (double) my_plugin.list_requests[i]);
313
TSReportSingleData("Total Bytes Received", "count", TS_SUM, (double) my_plugin.total_bytes_received);
317
/******************** ADDED FUNCTIONS ****************************/
319
/* Reads a host from the file pointer, url, and stores the host
320
* it read into the buffer. If no more host is read, it starts
321
* to read the host name from the beginning of the file
324
read_host(FILE * url, char *buffer, int buf_size)
329
while ((c = fgetc(url)) != EOF) {
331
if (c == '\n' && strcmp(buffer, "")) {
338
/* skip those host names that are longer than buf_size */
340
while (((c = fgetc(url)) != EOF) && c != '\n');
341
/* if hits the end, go back to the front */
343
if (fseek(url, 0, SEEK_SET)) {
344
fprintf(stderr, "ERROR in fseek");
349
/* if hits the end, go back to the front */
351
if (fseek(url, 0, SEEK_SET)) {
352
fprintf(stderr, "ERROR in fseek");
359
/* Randomly choose what catagory of url we should generate
360
* based on the ratio for the file specified in SDKtest_client.config
363
select_url_catagory()
373
for (i = 0; i < my_plugin.nlist; i++) {
374
x = x + (double) my_plugin.list_ratio[i] / 100;