1 #include <stdlib.h>
2 #include <string.h>
3
4 #include "types.h"
5 #include "http_util.h"
6
7 /* ------------------------------------------------------- */
8
9 /* split URL into parts */
10
11 static int
parse_url(struct global * registry,char * p,int i)12 parse_url(struct global * registry, char *p, int i) {
13 char *url = (char *) malloc((strlen(p)+1) * sizeof(char));
14 char *port, *tok, *tok2;
15
16 /* first, get a copy of url */
17 strcpy(url, p);
18
19 /* remove http:// prefix if it exists */
20 if (strlen(url) > 7 && strncmp(url, "http://", 7) == 0)
21 url += 7;
22
23 #ifdef AB_DEBUG
24 printf("AB_DEBUG: parse_url() - stage 1\n");
25 #endif
26
27 /* first, extract the hostname and port */
28 tok = strtok(url, "/");
29
30 #ifdef AB_DEBUG
31 printf("AB_DEBUG: parse_url() - stage 2\n");
32 #endif
33
34 /* the remaining part of url is just the uri */
35 tok2 = strtok(NULL, "");
36
37 #ifdef AB_DEBUG
38 printf("AB_DEBUG: parse_url() - stage 3\n");
39 #endif
40
41 registry->hostname[i] = (char *) malloc((strlen(tok)+1) * sizeof(char));
42 strcpy(registry->hostname[i], strtok(tok, ":"));
43 if ((port = strtok(NULL, "")) != NULL)
44 registry->port[i] = atoi(port);
45
46 #ifdef AB_DEBUG
47 printf("AB_DEBUG: parse_url() - stage 4\n");
48 #endif
49
50 /* if there is no uri, url was of the form http://host.name - assume / */
51 if (tok2 == NULL) {
52 registry->path[i] = "/";
53 return 0;
54 }
55
56 #ifdef AB_DEBUG
57 printf("AB_DEBUG: parse_url() - stage 5\n");
58 #endif
59
60 /* need to allocate memory for uri */
61 registry->path[i] = (char *) malloc((strlen(tok2)+2) * sizeof(char));
62
63 /* only add leading / if not proxy request */
64 if (strncmp(tok2, "http://", 7) != 0) {
65 strcpy(registry->path[i], "/");
66 strcat(registry->path[i], tok2);
67 } else
68 strcpy(registry->path[i], tok2);
69
70 return 0;
71 }
72
73
74 /* --------------------------------------------------------- */
75
76 /* extract cookies from response_data (Set-Cookie: headers) and save to auto_cookies */
77
78 static void
allocate_auto_cookie_memory(struct global * registry,struct connection * c)79 allocate_auto_cookie_memory(struct global * registry, struct connection * c) {
80 #ifdef AB_DEBUG
81 printf("AB_DEBUG: start of allocate_auto_cookie_memory(): run %d, thread %d\n", c->run, c->thread);
82 #endif
83
84 if (registry->auto_cookies[c->run] == NULL) {
85 registry->auto_cookies[c->run] = (char **) calloc(registry->repeats[c->run], sizeof(char *));
86 #ifdef AB_DEBUG
87 printf("AB_DEBUG: allocate_auto_cookie_memory() - stage 1: run %d, thread %d\n", c->run, c->thread);
88 #endif
89 }
90
91 if (registry->auto_cookies[c->run][c->thread] == NULL) {
92 registry->auto_cookies[c->run][c->thread] = (char *) calloc(CBUFFSIZE, sizeof(char));
93 #ifdef AB_DEBUG
94 printf("AB_DEBUG: allocate_auto_cookie_memory() - stage 2: run %d, thread %d\n", c->run, c->thread);
95 #endif
96 }
97 }
98
99 static void
extract_cookies_from_response(struct global * registry,struct connection * c)100 extract_cookies_from_response(struct global * registry, struct connection * c) {
101 char * set_cookie_hdr, * eoh;
102
103 #ifdef AB_DEBUG
104 printf("AB_DEBUG: start of extract_cookies_from_response()\n");
105 #endif
106 if (registry->failed[c->url] > 0)
107 return;
108
109 allocate_auto_cookie_memory(registry, c);
110
111 #ifdef AB_DEBUG
112 printf("AB_DEBUG: extract_cookies_from_response() - stage 1; run %d, thread %d\n", c->run, c->thread);
113 #endif
114
115 if (! c->response_headers) return;
116
117 set_cookie_hdr = strstr(c->response_headers, "\r\nSet-Cookie: ");
118 while (set_cookie_hdr) {
119 remove_existing_cookie_from_auto_cookies(registry, c, set_cookie_hdr);
120
121 #ifdef AB_DEBUG
122 printf("AB_DEBUG: extract_cookies_from_response() - stage 2.1; run %d, thread %d, postdata[%d] = %s\n", c->run, c->thread, c->url, registry->postdata[c->url]);
123 #endif
124
125 eoh = strstr(set_cookie_hdr+2, "\r\n");
126 if (! strnstr(set_cookie_hdr, "=; Expires=", eoh - set_cookie_hdr)) // hack: do not set expired headers
127 // drop the "Set-" from beginning to just append "Cookie: ....\r\n"
128 strncat(registry->auto_cookies[c->run][c->thread], set_cookie_hdr + 6, eoh - set_cookie_hdr - 4);
129
130 #ifdef AB_DEBUG
131 printf("AB_DEBUG: extract_cookies_from_response() - stage 2.2; run %d, thread %d, auto_cookies[%d][%d] = %s\n", c->run, c->thread, c->run, c->url, registry->auto_cookies[c->run][c->thread]);
132 #endif
133
134 set_cookie_hdr = strstr(set_cookie_hdr+1, "\r\nSet-Cookie: ");
135 }
136 }
137
138 /* remove existing cookies from registry->auto_cookies[..][..] which will be set again by extract_cookies_from_response() */
139
140 static void
remove_existing_cookie_from_auto_cookies(struct global * registry,struct connection * c,char * set_cookie_hdr)141 remove_existing_cookie_from_auto_cookies(struct global * registry, struct connection * c, char * set_cookie_hdr) {
142 char *existing_cookie, *end_of_existing_cookie, *cookie_name, *new_auto_cookies, *eoh;
143
144 #ifdef AB_DEBUG
145 printf("AB_DEBUG: start of remove_existing_cookie_from_auto_cookies(), postdata[%d] = %s\n", c->url, registry->postdata[c->url]);
146 #endif
147 // first need to find the name of cookie on current "Set-Cookie: " header line
148 cookie_name = (char *) calloc(CBUFFSIZE, sizeof(char));
149 strcat(cookie_name, "Cookie: ");
150 eoh = strstr(set_cookie_hdr+14, "\r\n");
151 strncat(cookie_name, set_cookie_hdr+14, strnstr(set_cookie_hdr+14, "=", eoh-(set_cookie_hdr+14)) - (set_cookie_hdr+14));
152
153 #ifdef AB_DEBUG
154 printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 1\n");
155 #endif
156
157 existing_cookie = strstr(registry->auto_cookies[c->run][c->thread], cookie_name);
158
159 #ifdef AB_DEBUG
160 printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 1.1\n");
161 #endif
162 if (existing_cookie) {
163 new_auto_cookies = (char *) calloc(CBUFFSIZE, sizeof(char));
164
165 #ifdef AB_DEBUG
166 printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 2.1\n");
167 #endif
168
169 strncpy(new_auto_cookies, registry->auto_cookies[c->run][c->thread], existing_cookie - registry->auto_cookies[c->run][c->thread]);
170 end_of_existing_cookie = strstr(existing_cookie, "\r\n");
171 strcat(new_auto_cookies, end_of_existing_cookie+2);
172
173 #ifdef AB_DEBUG
174 printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 2.2\n");
175 #endif
176
177 // overwrite auto_cookies with new version with existing_cookie removed
178 strcpy(registry->auto_cookies[c->run][c->thread], new_auto_cookies);
179 free(new_auto_cookies);
180
181 #ifdef AB_DEBUG
182 printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 2.3, auto_cookies[%d][%d] = %s\n", c->url, c->thread, registry->auto_cookies[c->url][c->thread]);
183 #endif
184 }
185 #ifdef AB_DEBUG
186 printf("AB_DEBUG: remove_existing_cookie_from_auto_cookies() - stage 3, cookie_name = %s\n", cookie_name);
187 #endif
188
189 free(cookie_name);
190
191 #ifdef AB_DEBUG
192 printf("AB_DEBUG: end of remove_existing_cookie_from_auto_cookies(), postdata[%d] = %s\n", c->url, registry->postdata[c->url]);
193 #endif
194 }
195