23
count_tabs(const char *the_string)
25
int str_index = 0, num_tabs = 0;
26
for(str_index = 0; the_string[str_index] != '\0'; str_index++)
27
if(the_string[str_index] == '\t')
32
#define FIELDS_PER_COOKIE_LINE 7
34
static struct cookie *
35
cookie_from_netscape_line(char *cookie_line)
37
struct cookie *new_cookie = NULL;
38
if(cookie_line && cookie_line[0]) {
39
/* Only parse the line if it is not a comment and it has the requisite number
40
* of tabs. Comment lines begin with a leading # symbol.
41
* Syntax checking is rudimentary, because these lines are
42
* machine-generated. */
43
if(cookie_line[0] != '#' &&
44
count_tabs(cookie_line) == FIELDS_PER_COOKIE_LINE - 1) {
45
new_cookie = allocZeroMem(sizeof (struct cookie));
46
char *start = cookie_line;
47
char *end = strchr(cookie_line, '\t');
48
new_cookie->domain = pullString1(start, end);
50
/* Ignore the second field of the line. */
53
start++; /* skip tab */
54
end = strchr(start, '\t');
55
new_cookie->path = pullString1(start, end);
57
if(*start == 'T' || *start == 't')
58
new_cookie->secure = true;
60
new_cookie->secure = false;
61
start = strchr(start, '\t') + 1;
62
new_cookie->expires = strtol(start, &end, 10);
63
/* Now end points to the tab following the expiration time. */
65
end = strchr(start, '\t');
66
new_cookie->name = pullString1(start, end);
68
/* strcspn gives count of non-newline characters in string, which is the
69
* length of the final field. Either CR or LF is considered a newline. */
70
new_cookie->value = pullString(start, strcspn(start, "\r\n"));
75
} /* cookie_from_netscape_line */
22
78
freeCookie(struct cookie *c)
49
105
addToListBack(&cookies, c);
50
106
} /* acceptCookie */
53
cookieIntoJar(const struct cookie *c)
109
/* Tell libcurl about a new cookie. Called when setting cookies from
111
* The function is pretty simple. Construct a line of the form used by
112
* the Netscape cookie file format, and pass that to libcurl. */
114
cookieForLibcurl(const struct cookie *c)
57
static bool warn = false;
64
if(c->expires <= time(0))
65
return; /* not persistent, or out of date */
66
f = fopen(cookieFile, "a");
69
116
/* Netscape format */
70
117
/* I have no clue what the second argument is suppose to be, */
71
118
/* I'm always calling it false. */
72
fprintf(f, "%s\tFALSE\t%s\t%s\t%u\t%s\t%s\n",
120
allocMem(strlen(c->path) + strlen(c->domain) + strlen(c->name) +
121
strlen(c->value) + 48);
122
sprintf(cookLine, "%s\tFALSE\t%s\t%s\t%u\t%s\t%s\n", c->domain, c->path,
74
123
c->secure ? "TRUE" : "FALSE", (unsigned)c->expires, c->name, c->value);
76
debugPrint(3, "into jar");
124
debugPrint(3, "cookie for libcurl");
125
curl_easy_setopt(curl_handle, CURLOPT_COOKIELIST, cookLine);
126
} /* cookieForLibcurl */
79
128
/* Should this server really specify this domain in a cookie? */
80
129
/* Domain must be the trailing substring of server. */
202
253
if(!fileIntoMemory(cookieFile, &cbuf, &n))
203
254
showErrorAbort();
207
259
cnt = expired = displaced = 0;
211
c = allocZeroMem(sizeof (struct cookie));
214
c->domain = cloneString(s);
220
c->path = cloneString(s);
223
c->secure = (*s == 'T');
227
c->expires = (time_t) atol(s);
231
c->name = cloneString(s);
235
c->value = cloneString(s);
238
if(c->expires < now) {
244
displaced += displacedCookie;
262
while(s < cbuf_end) {
263
t = s + strcspn(s, "\r\n");
264
/* t points to the first newline past s. If there is no newline in s,
265
* then it points to the NUL byte at end of s. */
267
c = cookie_from_netscape_line(s);
269
if(c) { /* Got a valid cookie line. */
271
if(c->expires < now) {
277
displaced += displacedCookie;
281
s = t + 1; /* Get ready to read more lines. */
282
/* Skip over blank lines, if necessary. */
283
while(s < cbuf_end && (*s == '\r' || *s == '\n'))
248
287
debugPrint(3, "%d persistent cookies, %d expired, %d displaced",
287
326
return !memcmp(d, s, dl);
288
327
} /* isPathPrefix */
291
332
sendCookies(char **s, int *l, const char *url, bool issecure)
293
334
const char *server = getHostURL(url);
294
335
const char *data = getDataURL(url);
295
336
int nc = 0; /* new cookie */
296
struct cookie *c, *d;
337
struct cookie *c = NULL;
339
struct curl_slist *known_cookies = NULL;
340
struct curl_slist *cursor = NULL;
341
curl_easy_getinfo(curl_handle, CURLINFO_COOKIELIST, &known_cookies);
299
343
if(!url || !server || !data)
308
foreach(c, cookies) {
352
/* Can't use foreach here, since known_cookies is just a pointer. */
353
cursor = known_cookies;
355
/* The code at the top of the loop guards against a memory leak.
356
* Otherwise, structs could become inaccessible after continue statements. */
357
while(cursor != NULL) {
358
if(c != NULL) { /* discard un-freed cookie structs */
362
c = cookie_from_netscape_line(cursor->data);
363
cursor = cursor->next;
364
if(c == NULL) /* didn't read a cookie line. */
309
366
if(!isInDomain(c->domain, server))
311
368
if(!isPathPrefix(c->path, data))
313
if(c->expires && c->expires < now) {
370
if(c->expires && c->expires < now)
321
372
if(c->secure && !issecure)
323
374
/* We're good to go. */
331
382
debugPrint(3, "send cookie %s=%s", c->name, c->value);
390
if(known_cookies != NULL)
391
curl_slist_free_all(known_cookies);
335
393
stringAndString(s, l, eol);
336
394
} /* sendCookies */