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