From 4449bd9b4dffc67b4c0597414d816a123e9a98e5 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 5 Oct 2007 14:37:33 +0000 Subject: [PATCH] Michael Wallner made the CULROPT_COOKIELIST option support a new magic string: "FLUSH". Using that will cause libcurl to flush its cookies to the CURLOPT_COOKIEJAR file. --- CHANGES | 5 ++- RELEASE-NOTES | 3 +- docs/libcurl/curl_easy_setopt.3 | 4 ++- lib/url.c | 64 ++++++++++++++++++++------------- 4 files changed, 49 insertions(+), 27 deletions(-) diff --git a/CHANGES b/CHANGES index 170dbcfd2..56bb14e98 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,10 @@ Changelog Daniel S (5 October 2007) +- Michael Wallner made the CULROPT_COOKIELIST option support a new magic + string: "FLUSH". Using that will cause libcurl to flush its cookies to the + CURLOPT_COOKIEJAR file. + - The new file docs/libcurl/ABI describes how we view ABI breakages, soname bumps and what the version number's significance to all that is. @@ -25,7 +29,6 @@ Yang Tse (3 October 2007) - Fixed issue related with the use of ares_timeout() result. Daniel S (3 October 2007) - - Alexey Pesternikov introduced CURLOPT_OPENSOCKETFUNCTION and CURLOPT_OPENSOCKETDATA to set a callback that allows an application to replace the socket() call used by libcurl. It basically allows the app to diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 29748f115..50a4db1db 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -19,6 +19,7 @@ This release includes the following changes: o added CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 and --hostpubmd5 o renamed CURLE_SSL_PEER_CERTIFICATE to CURLE_PEER_FAILED_VERIFICATION o added CURLOPT_OPENSOCKETFUNCTION and CURLOPT_OPENSOCKETDATA + o CULROPT_COOKIELIST supports "FLUSH" This release includes the following bugfixes: @@ -53,6 +54,6 @@ advice from friends like these: Dan Fandrich, Michal Marek, Günter Knauf, Rob Crittenden, Immanuel Gregoire, Mark Davies, Max Katsev, Philip Langdale, Alex Fishman, Johnny Luong, - Alexey Pesternikov, Yang Tse, Kim Rinnewitz + Alexey Pesternikov, Yang Tse, Kim Rinnewitz, Michael Wallner Thanks! (and sorry if I forgot to mention someone) diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 index ac460ae09..05895492e 100644 --- a/docs/libcurl/curl_easy_setopt.3 +++ b/docs/libcurl/curl_easy_setopt.3 @@ -810,7 +810,9 @@ format or just regular HTTP-style header (Set-Cookie: ...) format. If cURL cookie engine was not enabled it will enable its cookie engine. Passing a magic string \&"ALL" will erase all cookies known by cURL. (Added in 7.14.1) Passing the special string \&"SESS" will only erase all session cookies known -by cURL. (Added in 7.15.4) +by cURL. (Added in 7.15.4) Passing the special string \&"FLUSH" will write +all cookies known by cURL to the file specified by \fICURLOPT_COOKIEJAR\fP. +(Added in 7.17.1) .IP CURLOPT_HTTPGET Pass a long. If the long is non-zero, this forces the HTTP request to get back to GET. usable if a POST, HEAD, PUT or a custom request have been used diff --git a/lib/url.c b/lib/url.c index 0571fd651..c74a1d858 100644 --- a/lib/url.c +++ b/lib/url.c @@ -165,6 +165,10 @@ static void signalPipeClose(struct curl_llist *pipeline); static struct SessionHandle* gethandleathead(struct curl_llist *pipeline); +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) +static void flush_cookies(struct SessionHandle *data, int cleanup); +#endif + #define MAX_PIPELINE_LENGTH 5 /* @@ -269,6 +273,36 @@ CURLcode Curl_dupset(struct SessionHandle * dst, struct SessionHandle * src) return r; } +#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) +static void flush_cookies(struct SessionHandle *data, int cleanup) +{ + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); + if(data->set.str[STRING_COOKIEJAR]) { + if(data->change.cookielist) { + /* If there is a list of cookie files to read, do it first so that + we have all the told files read before we write the new jar */ + Curl_cookie_loadfiles(data); + } + + /* we have a "destination" for all the cookies to get dumped to */ + if(Curl_cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR])) + infof(data, "WARNING: failed to save cookies in %s\n", + data->set.str[STRING_COOKIEJAR]); + } + else { + if(cleanup && data->change.cookielist) + /* since nothing is written, we can just free the list of cookie file + names */ + curl_slist_free_all(data->change.cookielist); /* clean up list */ + } + + if(cleanup && (!data->share || (data->cookies != data->share->cookies))) { + Curl_cookie_cleanup(data->cookies); + } + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); +} +#endif + /* * This is the internal function curl_easy_cleanup() calls. This should * cleanup and free all resources associated with this sessionhandle. @@ -380,30 +414,7 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_safefree(data->state.headerbuff); #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) - Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); - if(data->set.str[STRING_COOKIEJAR]) { - if(data->change.cookielist) { - /* If there is a list of cookie files to read, do it first so that - we have all the told files read before we write the new jar */ - Curl_cookie_loadfiles(data); - } - - /* we have a "destination" for all the cookies to get dumped to */ - if(Curl_cookie_output(data->cookies, data->set.str[STRING_COOKIEJAR])) - infof(data, "WARNING: failed to save cookies in %s\n", - data->set.str[STRING_COOKIEJAR]); - } - else { - if(data->change.cookielist) - /* since nothing is written, we can just free the list of cookie file - names */ - curl_slist_free_all(data->change.cookielist); /* clean up list */ - } - - if( !data->share || (data->cookies != data->share->cookies) ) { - Curl_cookie_cleanup(data->cookies); - } - Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); + flush_cookies(data, 1); #endif Curl_digest_cleanup(data); @@ -1089,6 +1100,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, Curl_cookie_clearsess(data->cookies); break; } + else if(strequal(argptr, "FLUSH")) { + /* flush cookies to file */ + flush_cookies(data, 0); + break; + } if(!data->cookies) /* if cookie engine was not running, activate it */