diff options
-rw-r--r-- | include/curl/curl.h | 12 | ||||
-rw-r--r-- | lib/cookie.c | 44 | ||||
-rw-r--r-- | lib/cookie.h | 7 | ||||
-rw-r--r-- | lib/easy.c | 3 | ||||
-rw-r--r-- | lib/url.c | 25 | ||||
-rw-r--r-- | lib/urldata.h | 1 | ||||
-rw-r--r-- | src/main.c | 25 |
7 files changed, 92 insertions, 25 deletions
diff --git a/include/curl/curl.h b/include/curl/curl.h index 2d52fb1eb..df4f093b1 100644 --- a/include/curl/curl.h +++ b/include/curl/curl.h @@ -537,10 +537,18 @@ typedef enum { /* set the data for the debug function */ CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), CURLOPT_LASTENTRY /* the last unusued */ } CURLoption; + /* two convenient "aliases" that follow the name scheme better */ +#define CURLOPT_WRITEDATA CURLOPT_FILE +#define CURLOPT_READDATA CURLOPT_INFILE + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ enum { CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd @@ -676,8 +684,8 @@ CURLcode curl_global_init(long flags); void curl_global_cleanup(void); /* This is the version number */ -#define LIBCURL_VERSION "7.9.6" -#define LIBCURL_VERSION_NUM 0x070906 +#define LIBCURL_VERSION "7.9.7-pre1" +#define LIBCURL_VERSION_NUM 0x070907 /* linked-list structure for the CURLOPT_QUOTE option (and other) */ struct curl_slist { diff --git a/lib/cookie.c b/lib/cookie.c index 51155786b..2a90d0b8b 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -93,6 +93,21 @@ Example set of cookies: #include "memdebug.h" #endif +static void +free_cookiemess(struct Cookie *co) +{ + if(co->domain) + free(co->domain); + if(co->path) + free(co->path); + if(co->name) + free(co->name); + if(co->value) + free(co->value); + + free(co); +} + /**************************************************************************** * * Curl_cookie_add() @@ -326,22 +341,19 @@ Curl_cookie_add(struct CookieInfo *c, if(7 != fields) { /* we did not find the sufficient number of fields to recognize this as a valid line, abort and go home */ - - if(co->domain) - free(co->domain); - if(co->path) - free(co->path); - if(co->name) - free(co->name); - if(co->value) - free(co->value); - - free(co); + free_cookiemess(co); return NULL; } } + if(!c->running && /* read from a file */ + c->newsession && /* clean session cookies */ + !co->expires) { /* this is a session cookie since it doesn't expire! */ + free_cookiemess(co); + return NULL; + } + co->livecookie = c->running; /* now, we have parsed the incoming line, we must now check if this @@ -462,8 +474,12 @@ Curl_cookie_add(struct CookieInfo *c, * Inits a cookie struct to read data from a local file. This is always * called before any cookies are set. File may be NULL. * + * If 'newsession' is TRUE, discard all "session cookies" on read from file. + * ****************************************************************************/ -struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc) +struct CookieInfo *Curl_cookie_init(char *file, + struct CookieInfo *inc, + bool newsession) { char line[MAX_COOKIE_LINE]; struct CookieInfo *c; @@ -491,6 +507,8 @@ struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc) else fp = file?fopen(file, "r"):NULL; + c->newsession = newsession; /* new session? */ + if(fp) { char *lineptr; bool headerline; @@ -513,7 +531,7 @@ struct CookieInfo *Curl_cookie_init(char *file, struct CookieInfo *inc) fclose(fp); } - c->running = TRUE; /* now, we're running */ + c->running = TRUE; /* now, we're running */ return c; } diff --git a/lib/cookie.h b/lib/cookie.h index 7bdbf0c34..d9e1a0fe9 100644 --- a/lib/cookie.h +++ b/lib/cookie.h @@ -55,9 +55,10 @@ struct CookieInfo { /* linked list of cookies we know of */ struct Cookie *cookies; - char *filename; /* file we read from/write to */ - bool running; /* state info, for cookie adding information */ + char *filename; /* file we read from/write to */ + bool running; /* state info, for cookie adding information */ long numcookies; /* number of cookies in the "jar" */ + bool newsession; /* new session, discard session cookies on load */ }; /* This is the maximum line length we accept for a cookie line */ @@ -75,7 +76,7 @@ struct CookieInfo { struct Cookie *Curl_cookie_add(struct CookieInfo *, bool header, char *line, char *domain); -struct CookieInfo *Curl_cookie_init(char *, struct CookieInfo *); +struct CookieInfo *Curl_cookie_init(char *, struct CookieInfo *, bool); struct Cookie *Curl_cookie_getlist(struct CookieInfo *, char *, char *, bool); void Curl_cookie_freelist(struct Cookie *); void Curl_cookie_cleanup(struct CookieInfo *); diff --git a/lib/easy.c b/lib/easy.c index 401eeeddf..4ae607a8a 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -312,7 +312,8 @@ CURL *curl_easy_duphandle(CURL *incurl) /* If cookies are enabled in the parent handle, we enable them in the clone as well! */ outcurl->cookies = Curl_cookie_init(data->cookies->filename, - outcurl->cookies); + outcurl->cookies, + data->set.cookiesession); /* duplicate all values in 'change' */ if(data->change.url) { @@ -495,13 +495,33 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) data->set.ssl.version = va_arg(param, long); break; + case CURLOPT_COOKIESESSION: + /* + * Set this option to TRUE to start a new "cookie session". It will + * prevent the forthcoming read-cookies-from-file actions to accept + * cookies that are marked as being session cookies, as they belong to a + * previous session. + * + * In the original Netscape cookie spec, "session cookies" are cookies + * with no expire date set. RFC2109 describes the same action if no + * 'Max-Age' is set and RFC2965 includes the RFC2109 description and adds + * a 'Discard' action that can enforce the discard even for cookies that + * have a Max-Age. + * + * We run mostly with the original cookie spec, as hardly anyone implements + * anything else. + */ + data->set.cookiesession = (bool)va_arg(param, long); + break; + case CURLOPT_COOKIEFILE: /* * Set cookie file to read and parse. Can be used multiple times. */ cookiefile = (char *)va_arg(param, void *); if(cookiefile) - data->cookies = Curl_cookie_init(cookiefile, data->cookies); + data->cookies = Curl_cookie_init(cookiefile, data->cookies, + data->set.cookiesession); break; case CURLOPT_COOKIEJAR: @@ -514,7 +534,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) * Activate the cookie parser. This may or may not already * have been made. */ - data->cookies = Curl_cookie_init(NULL, data->cookies); + data->cookies = Curl_cookie_init(NULL, data->cookies, + data->set.cookiesession); break; case CURLOPT_WRITEHEADER: /* diff --git a/lib/urldata.h b/lib/urldata.h index 571ab3015..ff2a997a0 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -607,6 +607,7 @@ struct UserDefined { char *key_passwd; /* plain text private key password */ char *crypto_engine; /* name of the crypto engine to use */ char *cookiejar; /* dump all cookies to this file */ + bool cookiesession; /* new cookie session? */ bool crlf; /* convert crlf on ftp upload(?) */ struct curl_slist *quote; /* after connection is established */ struct curl_slist *postquote; /* after the transfer */ diff --git a/src/main.c b/src/main.c index 2217fef83..6b4236355 100644 --- a/src/main.c +++ b/src/main.c @@ -351,7 +351,8 @@ static void help(void) puts(" -h/--help This help text\n" " -H/--header <line> Custom header to pass to server. (H)\n" " -i/--include Include the HTTP-header in the output (H)\n" - " -I/--head Fetch document info only (HTTP HEAD/FTP SIZE)\n" + " -I/--head Fetch document info only (HTTP HEAD/FTP SIZE)"); + puts(" -j/--junk-session-cookies Ignore session cookies read from file (H)\n" " --interface <interface> Specify the interface to be used\n" " --krb4 <level> Enable krb4 with specified security level (F)\n" " -K/--config Specify which config file to read\n" @@ -410,6 +411,7 @@ struct Configurable { char *cookie; /* single line with specified cookies */ char *cookiejar; /* write to this file */ char *cookiefile; /* read from this file */ + bool cookiesession; /* new session? */ bool use_resume; bool resume_from_current; bool disable_epsv; @@ -455,6 +457,8 @@ struct Configurable { char *krb4level; char *trace_dump; /* file to dump the network trace to, or NULL */ FILE *trace_stream; + bool trace_fopened; + long httpversion; bool progressmode; bool nobuffer; @@ -995,6 +999,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ {"H", "header", TRUE}, {"i", "include", FALSE}, {"I", "head", FALSE}, + {"j", "junk-session-cookies", FALSE}, {"K", "config", TRUE}, {"l", "list-only", FALSE}, {"L", "location", FALSE}, @@ -1380,6 +1385,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */ case 'i': config->conf ^= CONF_HEADER; /* include the HTTP header as well */ break; + case 'j': + config->cookiesession ^= TRUE; + break; case 'I': /* * This is a bit tricky. We either SET both bits, or we clear both @@ -1963,9 +1971,15 @@ int my_trace(CURL *handle, curl_infotype type, (void)handle; /* prevent compiler warning */ - if(!config->trace_stream) + if(!config->trace_stream) { /* open for append */ - config->trace_stream = fopen(config->trace_dump, "w"); + if(strequal("-", config->trace_dump)) + config->trace_stream = stdout; + else { + config->trace_stream = fopen(config->trace_dump, "w"); + config->trace_fopened = TRUE; + } + } if(config->trace_stream) output = config->trace_stream; @@ -2523,6 +2537,9 @@ operate(struct Configurable *config, int argc, char *argv[]) curl_easy_setopt(curl, CURLOPT_COOKIEFILE, config->cookiefile); /* cookie jar was added in 7.9 */ curl_easy_setopt(curl, CURLOPT_COOKIEJAR, config->cookiejar); + /* cookie session added in 7.9.7 */ + curl_easy_setopt(curl, CURLOPT_COOKIESESSION, config->cookiesession); + curl_easy_setopt(curl, CURLOPT_SSLVERSION, config->ssl_version); curl_easy_setopt(curl, CURLOPT_TIMECONDITION, config->timecond); curl_easy_setopt(curl, CURLOPT_TIMEVALUE, config->condtime); @@ -2650,7 +2667,7 @@ operate(struct Configurable *config, int argc, char *argv[]) if(config->headerfile && !headerfilep && heads.stream) fclose(heads.stream); - if(config->trace_stream) + if(config->trace_fopened) fclose(config->trace_stream); if(allocuseragent) |