RECEIVING COOKIE INFORMATION
============================
-struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
- const char *file, struct CookieInfo *inc, bool newsession);
+struct CookieInfo *cookie_init(char *file);
Inits a cookie struct to store data in a local file. This is always
called before any cookies are set.
-struct Cookie *Curl_cookie_add(struct SessionHandle *data,
- struct CookieInfo *c, bool httpheader, char *lineptr,
- const char *domain, const char *path);
+int cookies_set(struct CookieInfo *cookie, char *cookie_line);
- The 'lineptr' parameter is a full "Set-cookie:" line as
+ The 'cookie_line' parameter is a full "Set-cookie:" line as
received from a server.
The function need to replace previously stored lines that this new
SENDING COOKIE INFORMATION
==========================
-struct Cookies *Curl_cookie_getlist(struct CookieInfo *cookie,
- char *host, char *path, bool secure);
+struct Cookies *cookie_getlist(struct CookieInfo *cookie,
+ char *host, char *path, bool secure);
For a given host and path, return a linked list of cookies that
the client should send to the server if used now. The secure
#include "strtoofft.h"
#include "rawstr.h"
#include "curl_memrchr.h"
-#include "inet_pton.h"
/* The last #include file should be: */
#include "memdebug.h"
return NULL;
/* some stupid site sends path attribute with '"'. */
- len = strlen(new_path);
if(new_path[0] == '\"') {
- memmove((void *)new_path, (const void *)(new_path + 1), len);
- len--;
+ memmove((void *)new_path, (const void *)(new_path + 1), strlen(new_path));
}
- if(len && (new_path[len - 1] == '\"')) {
- new_path[len - 1] = 0x0;
- len--;
+ if(new_path[strlen(new_path) - 1] == '\"') {
+ new_path[strlen(new_path) - 1] = 0x0;
}
/* RFC6265 5.2.4 The Path Attribute */
}
/* convert /hoge/ to /hoge */
- if(len && new_path[len - 1] == '/') {
+ len = strlen(new_path);
+ if(1 < len && new_path[len - 1] == '/') {
new_path[len - 1] = 0x0;
}
/*
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
- *
- * NOTE: OOM or cookie parsing failures are ignored.
*/
void Curl_cookie_loadfiles(struct SessionHandle *data)
{
if(list) {
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
while(list) {
- struct CookieInfo *newcookies = Curl_cookie_init(data,
- list->data,
- data->cookies,
- data->set.cookiesession);
- if(!newcookies)
- /* Failure may be due to OOM or a bad cookie; both are ignored
- * but only the first should be
- */
- infof(data, "ignoring failed cookie_init for %s\n", list->data);
- else
- data->cookies = newcookies;
+ data->cookies = Curl_cookie_init(data,
+ list->data,
+ data->cookies,
+ data->set.cookiesession);
list = list->next;
}
curl_slist_free_all(data->change.cookielist); /* clean up list */
}
}
-/*
- * Return true if the given string is an IP(v4|v6) address.
- */
-static bool isip(const char *domain)
-{
- struct in_addr addr;
-#ifdef ENABLE_IPV6
- struct in6_addr addr6;
-#endif
-
- if(Curl_inet_pton(AF_INET, domain, &addr)
-#ifdef ENABLE_IPV6
- || Curl_inet_pton(AF_INET6, domain, &addr6)
-#endif
- ) {
- /* domain name given as IP address */
- return TRUE;
- }
-
- return FALSE;
-}
-
/****************************************************************************
*
* Curl_cookie_add()
* Be aware that sometimes we get an IP-only host name, and that might also be
* a numerical IPv6 address.
*
- * Returns NULL on out of memory or invalid cookie. This is suboptimal,
- * as they should be treated separately.
***************************************************************************/
struct Cookie *
}
}
else if(Curl_raw_equal("domain", name)) {
- bool is_ip;
- const char *dotp;
-
/* Now, we make sure that our host is within the given domain,
or the given domain is not valid and thus cannot be set. */
if('.' == whatptr[0])
whatptr++; /* ignore preceding dot */
- is_ip = isip(domain ? domain : whatptr);
-
- /* check for more dots */
- dotp = strchr(whatptr, '.');
- if(!dotp)
- domain=":";
-
- if(!domain
- || (is_ip && !strcmp(whatptr, domain))
- || (!is_ip && tailmatch(whatptr, domain))) {
- strstore(&co->domain, whatptr);
+ if(!domain || tailmatch(whatptr, domain)) {
+ const char *tailptr=whatptr;
+ if(tailptr[0] == '.')
+ tailptr++;
+ strstore(&co->domain, tailptr); /* don't prefix w/dots
+ internally */
if(!co->domain) {
badcookie = TRUE;
break;
}
- if(!is_ip)
- co->tailmatch=TRUE; /* we always do that if the domain name was
- given */
+ co->tailmatch=TRUE; /* we always do that if the domain name was
+ given */
}
else {
/* we did not get a tailmatch and then the attempted set domain
*
* If 'newsession' is TRUE, discard all "session cookies" on read from file.
*
- * Returns NULL on out of memory. Invalid cookies are ignored.
****************************************************************************/
struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
const char *file,
bool newsession)
{
struct CookieInfo *c;
- FILE *fp = NULL;
+ FILE *fp;
bool fromfile=TRUE;
- char *line = NULL;
if(NULL == inc) {
/* we didn't get a struct, create one */
if(!c)
return NULL; /* failed to get memory */
c->filename = strdup(file?file:"none"); /* copy the name just in case */
- if(!c->filename)
- goto fail; /* failed to get memory */
}
else {
/* we got an already existing one, use that */
char *lineptr;
bool headerline;
- line = malloc(MAX_COOKIE_LINE);
- if(!line)
- goto fail;
- while(fgets(line, MAX_COOKIE_LINE, fp)) {
- if(checkprefix("Set-Cookie:", line)) {
- /* This is a cookie line, get it! */
- lineptr=&line[11];
- headerline=TRUE;
- }
- else {
- lineptr=line;
- headerline=FALSE;
- }
- while(*lineptr && ISBLANK(*lineptr))
- lineptr++;
+ char *line = malloc(MAX_COOKIE_LINE);
+ if(line) {
+ while(fgets(line, MAX_COOKIE_LINE, fp)) {
+ if(checkprefix("Set-Cookie:", line)) {
+ /* This is a cookie line, get it! */
+ lineptr=&line[11];
+ headerline=TRUE;
+ }
+ else {
+ lineptr=line;
+ headerline=FALSE;
+ }
+ while(*lineptr && ISBLANK(*lineptr))
+ lineptr++;
- Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
+ Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
+ }
+ free(line); /* free the line buffer */
}
- free(line); /* free the line buffer */
-
if(fromfile)
fclose(fp);
}
c->running = TRUE; /* now, we're running */
return c;
-
-fail:
- Curl_safefree(line);
- if(!inc)
- /* Only clean up if we allocated it here, as the original could still be in
- * use by a share handle */
- Curl_cookie_cleanup(c);
- if(fromfile && fp)
- fclose(fp);
- return NULL; /* out of memory */
}
/* sort this so that the longest path gets before the shorter path */
time_t now = time(NULL);
struct Cookie *mainco=NULL;
size_t matches = 0;
- bool is_ip;
if(!c || !c->cookies)
return NULL; /* no cookie struct or no cookies in the struct */
/* at first, remove expired cookies */
remove_expired(c);
- /* check if host is an IP(v4|v6) address */
- is_ip = isip(host);
-
co = c->cookies;
while(co) {
/* now check if the domain is correct */
if(!co->domain ||
- (co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
- ((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
+ (co->tailmatch && tailmatch(co->domain, host)) ||
+ (!co->tailmatch && Curl_raw_equal(host, co->domain)) ) {
/* the right part of the host matches the domain stuff in the
cookie data */
void Curl_cookie_freelist(struct Cookie *co, bool cookiestoo)
{
struct Cookie *next;
- while(co) {
- next = co->next;
- if(cookiestoo)
- freecookie(co);
- else
- free(co); /* we only free the struct since the "members" are all just
- pointed out in the main cookie list! */
- co = next;
+ if(co) {
+ while(co) {
+ next = co->next;
+ if(cookiestoo)
+ freecookie(co);
+ else
+ free(co); /* we only free the struct since the "members" are all just
+ pointed out in the main cookie list! */
+ co = next;
+ }
}
}
*
* Curl_cookie_cleanup()
*
- * Free a "cookie object" previous created with Curl_cookie_init().
+ * Free a "cookie object" previous created with cookie_init().
*
****************************************************************************/
void Curl_cookie_cleanup(struct CookieInfo *c)
{
+ struct Cookie *co;
+ struct Cookie *next;
if(c) {
if(c->filename)
free(c->filename);
- Curl_cookie_freelist(c->cookies, TRUE);
+ co = c->cookies;
+
+ while(co) {
+ next = co->next;
+ freecookie(co);
+ co = next;
+ }
free(c); /* free the base struct as well */
}
}