From 606562aa7ea28ee0fdd5bf2cd6febada9594ad19 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 24 May 2006 22:46:38 +0000 Subject: Michael Wallner provided a patch that allows "SESS" to be set with CURLOPT_COOKIELIST, which then makes all session cookies get cleared. (slightly edited by me, and the re-indent in cookie.c was also done by me) --- lib/cookie.c | 254 +++++++++++++++++++++++++++++++++++------------------------ lib/cookie.h | 4 +- lib/url.c | 15 ++-- 3 files changed, 164 insertions(+), 109 deletions(-) (limited to 'lib') diff --git a/lib/cookie.c b/lib/cookie.c index a8519c4e3..d934868ca 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -733,68 +733,81 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data, struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, char *host, char *path, bool secure) { - struct Cookie *newco; - struct Cookie *co; - time_t now = time(NULL); - struct Cookie *mainco=NULL; - - if(!c || !c->cookies) - return NULL; /* no cookie struct or no cookies in the struct */ - - co = c->cookies; - - while(co) { - /* only process this cookie if it is not expired or had no expire - date AND that if the cookie requires we're secure we must only - continue if we are! */ - if( (co->expires<=0 || (co->expires> now)) && - (co->secure?secure:TRUE) ) { - - /* now check if the domain is correct */ - if(!co->domain || - (co->tailmatch && tailmatch(co->domain, host)) || - (!co->tailmatch && strequal(host, co->domain)) ) { - /* the right part of the host matches the domain stuff in the - cookie data */ - - /* now check the left part of the path with the cookies path - requirement */ - if(!co->path || - checkprefix(co->path, path) ) { - - /* and now, we know this is a match and we should create an - entry for the return-linked-list */ - - newco = (struct Cookie *)malloc(sizeof(struct Cookie)); - if(newco) { - /* first, copy the whole source cookie: */ - memcpy(newco, co, sizeof(struct Cookie)); - - /* then modify our next */ - newco->next = mainco; - - /* point the main to us */ - mainco = newco; - } - else { - /* failure, clear up the allocated chain and return NULL */ - while(mainco) { - co = mainco->next; - free(mainco); - mainco = co; - } - - return NULL; - } - } - } - } - co = co->next; - } - - return mainco; /* return the new list */ + struct Cookie *newco; + struct Cookie *co; + time_t now = time(NULL); + struct Cookie *mainco=NULL; + + if(!c || !c->cookies) + return NULL; /* no cookie struct or no cookies in the struct */ + + co = c->cookies; + + while(co) { + /* only process this cookie if it is not expired or had no expire + date AND that if the cookie requires we're secure we must only + continue if we are! */ + if( (co->expires<=0 || (co->expires> now)) && + (co->secure?secure:TRUE) ) { + + /* now check if the domain is correct */ + if(!co->domain || + (co->tailmatch && tailmatch(co->domain, host)) || + (!co->tailmatch && strequal(host, co->domain)) ) { + /* the right part of the host matches the domain stuff in the + cookie data */ + + /* now check the left part of the path with the cookies path + requirement */ + if(!co->path || + checkprefix(co->path, path) ) { + + /* and now, we know this is a match and we should create an + entry for the return-linked-list */ + + newco = (struct Cookie *)malloc(sizeof(struct Cookie)); + if(newco) { + /* first, copy the whole source cookie: */ + memcpy(newco, co, sizeof(struct Cookie)); + + /* then modify our next */ + newco->next = mainco; + + /* point the main to us */ + mainco = newco; + } + else { + /* failure, clear up the allocated chain and return NULL */ + while(mainco) { + co = mainco->next; + free(mainco); + mainco = co; + } + + return NULL; + } + } + } + } + co = co->next; + } + + return mainco; /* return the new list */ } +/***************************************************************************** + * + * Curl_cookie_clearall() + * + * Clear all existing cookies and reset the counter. + * + ****************************************************************************/ +void Curl_cookie_clearall(struct CookieInfo *cookies) +{ + Curl_cookie_freelist(cookies->cookies); + cookies->cookies = NULL; + cookies->numcookies = 0; +} /***************************************************************************** * @@ -806,17 +819,56 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, void Curl_cookie_freelist(struct Cookie *co) { - struct Cookie *next; - if(co) { - while(co) { - next = co->next; - free(co); /* we only free the struct since the "members" are all + struct Cookie *next; + if(co) { + while(co) { + next = co->next; + free(co); /* we only free the struct since the "members" are all just copied! */ - co = next; - } - } + co = next; + } + } +} + + +/***************************************************************************** + * + * Curl_cookie_clearsess() + * + * Free all session cookies in the cookies list. + * + ****************************************************************************/ +void Curl_cookie_clearsess(struct CookieInfo *cookies) +{ + struct Cookie *first, *curr, *next, *prev = NULL; + + if(!cookies->cookies) + return; + + first = curr = prev = cookies->cookies; + + for(; curr; curr = next) { + next = curr->next; + if(!curr->expires) { + if(first == curr) + first = next; + + if(prev == curr) + prev = next; + else + prev->next = next; + + free(curr); + cookies->numcookies--; + } + else + prev = curr; + } + + cookies->cookies = first; } + /***************************************************************************** * * Curl_cookie_cleanup() @@ -826,20 +878,20 @@ void Curl_cookie_freelist(struct Cookie *co) ****************************************************************************/ void Curl_cookie_cleanup(struct CookieInfo *c) { - struct Cookie *co; - struct Cookie *next; - if(c) { - if(c->filename) - free(c->filename); - co = c->cookies; - - while(co) { - next = co->next; - freecookie(co); - co = next; - } - free(c); /* free the base struct as well */ - } + struct Cookie *co; + struct Cookie *next; + if(c) { + if(c->filename) + free(c->filename); + co = c->cookies; + + while(co) { + next = co->next; + freecookie(co); + co = next; + } + free(c); /* free the base struct as well */ + } } /* get_netscape_format() @@ -850,24 +902,24 @@ void Curl_cookie_cleanup(struct CookieInfo *c) */ static char *get_netscape_format(const struct Cookie *co) { - return aprintf( - "%s%s\t" /* domain */ - "%s\t" /* tailmatch */ - "%s\t" /* path */ - "%s\t" /* secure */ - "%" FORMAT_OFF_T "\t" /* expires */ - "%s\t" /* name */ - "%s", /* value */ - /* Make sure all domains are prefixed with a dot if they allow - tailmatching. This is Mozilla-style. */ - (co->tailmatch && co->domain && co->domain[0] != '.')? ".":"", - co->domain?co->domain:"unknown", - co->tailmatch?"TRUE":"FALSE", - co->path?co->path:"/", - co->secure?"TRUE":"FALSE", - co->expires, - co->name, - co->value?co->value:""); + return aprintf( + "%s%s\t" /* domain */ + "%s\t" /* tailmatch */ + "%s\t" /* path */ + "%s\t" /* secure */ + "%" FORMAT_OFF_T "\t" /* expires */ + "%s\t" /* name */ + "%s", /* value */ + /* Make sure all domains are prefixed with a dot if they allow + tailmatching. This is Mozilla-style. */ + (co->tailmatch && co->domain && co->domain[0] != '.')? ".":"", + co->domain?co->domain:"unknown", + co->tailmatch?"TRUE":"FALSE", + co->path?co->path:"/", + co->secure?"TRUE":"FALSE", + co->expires, + co->name, + co->value?co->value:""); } /* diff --git a/lib/cookie.h b/lib/cookie.h index 0dd863074..bdd222b9c 100644 --- a/lib/cookie.h +++ b/lib/cookie.h @@ -7,7 +7,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2005, Daniel Stenberg, , et al. + * Copyright (C) 1998 - 2006, Daniel Stenberg, , et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -89,6 +89,8 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data, char *, struct CookieInfo *, bool); struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool); void Curl_cookie_freelist(struct Cookie *); +void Curl_cookie_clearall(struct CookieInfo *cookies); +void Curl_cookie_clearsess(struct CookieInfo *cookies); void Curl_cookie_cleanup(struct CookieInfo *); int Curl_cookie_output(struct CookieInfo *, char *); diff --git a/lib/url.c b/lib/url.c index 690b3f302..e9fa81168 100644 --- a/lib/url.c +++ b/lib/url.c @@ -829,12 +829,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, break; if(strequal(argptr, "ALL")) { - if(data->cookies) { - /* clear all cookies */ - Curl_cookie_freelist(data->cookies->cookies); - data->cookies->cookies = NULL; - data->cookies->numcookies = 0; - } + /* clear all cookies */ + Curl_cookie_clearall(data->cookies); + break; + } + else if(strequal(argptr, "SESS")) { + /* clear session cookies */ + Curl_cookie_clearsess(data->cookies); break; } @@ -2299,7 +2300,7 @@ static CURLcode ConnectPlease(struct connectdata *conn, break; case CURLPROXY_SOCKS4: return handleSock4Proxy(conn->proxyuser, conn) ? - CURLE_COULDNT_CONNECT : CURLE_OK; + CURLE_COULDNT_CONNECT : CURLE_OK; default: failf(conn->data, "unknown proxytype option given"); return CURLE_COULDNT_CONNECT; -- cgit v1.2.3