diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/easy.c | 24 | ||||
-rw-r--r-- | lib/http.c | 2 | ||||
-rw-r--r-- | lib/share.c | 16 | ||||
-rw-r--r-- | lib/share.h | 2 | ||||
-rw-r--r-- | lib/transfer.c | 4 | ||||
-rw-r--r-- | lib/url.c | 60 |
6 files changed, 81 insertions, 27 deletions
diff --git a/lib/easy.c b/lib/easy.c index 02f5b2eb7..73f3d9cca 100644 --- a/lib/easy.c +++ b/lib/easy.c @@ -76,6 +76,7 @@ #include "url.h" #include "getinfo.h" #include "hostip.h" +#include "share.h" #define _MPRINTF_REPLACE /* use our functions only */ #include <curl/mprintf.h> @@ -233,15 +234,18 @@ CURLcode curl_easy_perform(CURL *curl) { struct SessionHandle *data = (struct SessionHandle *)curl; - if (Curl_global_host_cache_use(data) && data->hostcache != Curl_global_host_cache_get()) { - if (data->hostcache) { - Curl_hash_destroy(data->hostcache); + if ( ! (data->share && data->share->hostcache) ) { + + if (Curl_global_host_cache_use(data) && + data->hostcache != Curl_global_host_cache_get()) { + if (data->hostcache) + Curl_hash_destroy(data->hostcache); + data->hostcache = Curl_global_host_cache_get(); } - data->hostcache = Curl_global_host_cache_get(); - } - if (!data->hostcache) { - data->hostcache = Curl_hash_alloc(7, Curl_freednsinfo); + if (!data->hostcache) + data->hostcache = Curl_hash_alloc(7, Curl_freednsinfo); + } return Curl_perform(data); @@ -250,8 +254,10 @@ CURLcode curl_easy_perform(CURL *curl) void curl_easy_cleanup(CURL *curl) { struct SessionHandle *data = (struct SessionHandle *)curl; - if (!Curl_global_host_cache_use(data)) { - Curl_hash_destroy(data->hostcache); + if ( ! (data->share && data->share->hostcache) ) { + if ( !Curl_global_host_cache_use(data)) { + Curl_hash_destroy(data->hostcache); + } } Curl_close(data); } diff --git a/lib/http.c b/lib/http.c index 2418c1bd7..e0c5d73e7 100644 --- a/lib/http.c +++ b/lib/http.c @@ -853,10 +853,12 @@ CURLcode Curl_http(struct connectdata *conn) } if(data->cookies) { + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); co = Curl_cookie_getlist(data->cookies, conn->allocptr.cookiehost? conn->allocptr.cookiehost:host, ppath, (bool)(conn->protocol&PROT_HTTPS?TRUE:FALSE)); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); } if (conn->bits.httpproxy && diff --git a/lib/share.c b/lib/share.c index 798a0a497..9b5f79f9e 100644 --- a/lib/share.c +++ b/lib/share.c @@ -76,6 +76,9 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...) break; case CURL_LOCK_DATA_COOKIE: + if (!share->cookies) { + share->cookies = Curl_cookie_init( NULL, NULL, TRUE ); + } break; case CURL_LOCK_DATA_SSL_SESSION: @@ -103,6 +106,10 @@ curl_share_setopt(CURLSH *sh, CURLSHoption option, ...) break; case CURL_LOCK_DATA_COOKIE: + if (share->cookies) { + Curl_cookie_cleanup(share->cookies); + share->cookies = NULL; + } break; case CURL_LOCK_DATA_SSL_SESSION: @@ -144,6 +151,12 @@ CURLSHcode curl_share_cleanup(CURLSH *sh) if (share->dirty) return CURLSHE_IN_USE; + if(share->hostcache) + Curl_hash_destroy(share->hostcache); + + if(share->cookies) + Curl_cookie_cleanup(share->cookies); + free (share); return CURLSHE_OK; @@ -151,7 +164,8 @@ CURLSHcode curl_share_cleanup(CURLSH *sh) CURLSHcode -Curl_share_lock(struct SessionHandle *data, curl_lock_data type, curl_lock_access access) +Curl_share_lock(struct SessionHandle *data, curl_lock_data type, + curl_lock_access access) { struct Curl_share *share = data->share; diff --git a/lib/share.h b/lib/share.h index 76e6244d7..45844e495 100644 --- a/lib/share.h +++ b/lib/share.h @@ -26,6 +26,7 @@ #include "setup.h" #include <curl/curl.h> +#include "cookie.h" /* this struct is libcurl-private, don't export details */ struct Curl_share { @@ -37,6 +38,7 @@ struct Curl_share { void *clientdata; curl_hash *hostcache; + struct CookieInfo *cookies; }; CURLSHcode Curl_share_lock ( diff --git a/lib/transfer.c b/lib/transfer.c index 4f9ea8c30..445975b0a 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -707,12 +707,14 @@ CURLcode Curl_readwrite(struct connectdata *conn, } else if(data->cookies && checkprefix("Set-Cookie:", k->p)) { + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); Curl_cookie_add(data->cookies, TRUE, k->p+11, /* If there is a custom-set Host: name, use it here, or else use real peer host name. */ conn->allocptr.cookiehost? conn->allocptr.cookiehost:conn->name, conn->ppath); + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); } else if(checkprefix("Last-Modified:", k->p) && (data->set.timecondition || data->set.get_filetime) ) { @@ -1509,12 +1511,14 @@ CURLcode Curl_pretransfer(struct SessionHandle *data) do it now! */ if(data->change.cookielist) { struct curl_slist *list = data->change.cookielist; + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); while(list) { data->cookies = Curl_cookie_init(list->data, data->cookies, data->set.cookiesession); list = list->next; } + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); curl_slist_free_all(data->change.cookielist); /* clean up list */ data->change.cookielist = NULL; /* don't do this again! */ } @@ -191,10 +191,6 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_SSL_Close_All(data); #endif - /* No longer a dirty share, if it exists */ - if (data->share) - data->share->dirty--; - if(data->change.cookielist) /* clean up list if any */ curl_slist_free_all(data->change.cookielist); @@ -213,13 +209,17 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_safefree(data->state.headerbuff); #ifndef CURL_DISABLE_HTTP + Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE); if(data->set.cookiejar) { /* we have a "destination" for all the cookies to get dumped to */ if(Curl_cookie_output(data->cookies, data->set.cookiejar)) infof(data, "WARNING: failed to save cookies in given jar\n"); } - Curl_cookie_cleanup(data->cookies); + if( !data->share || (data->cookies != data->share->cookies) ) { + Curl_cookie_cleanup(data->cookies); + } + Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); #endif /* free the connection cache */ @@ -229,6 +229,10 @@ CURLcode Curl_close(struct SessionHandle *data) Curl_digest_cleanup(data); + /* No longer a dirty share, if it exists */ + if (data->share) + data->share->dirty--; + free(data); return CURLE_OK; } @@ -1148,34 +1152,56 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...) { struct Curl_share *set; set = va_arg(param, struct Curl_share *); - if(data->share) - { + + /* disconnect from old share, if any */ + if(data->share) { Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - /* checking the dns cache stuff */ if(data->share->hostcache == data->hostcache) - { data->hostcache = NULL; - } + + if(data->share->cookies == data->cookies) + data->cookies = NULL; data->share->dirty--; Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + data->share = NULL; } + /* use new share if it set */ data->share = set; + if(data->share) { + + Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); - Curl_share_lock(data, CURL_LOCK_DATA_SHARE, CURL_LOCK_ACCESS_SINGLE); + data->share->dirty++; - data->share->dirty++; + if(data->share->hostcache) { + /* use shared host cache, first free own one if any */ + if(data->hostcache) + Curl_hash_destroy(data->hostcache); - if( data->hostcache ) - { - Curl_hash_destroy(data->hostcache); - data->hostcache = data->share->hostcache; + data->hostcache = data->share->hostcache; + } + + if(data->share->cookies) { + /* use shared cookie list, first free own one if any */ + if (data->cookies) + Curl_cookie_cleanup(data->cookies); + data->cookies = data->share->cookies; + } + + Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + } - Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); + /* check cookie list is set */ + if(!data->cookies) + data->cookies = Curl_cookie_init( NULL, NULL, TRUE ); + + /* check for host cache not needed, + * it will be done by curl_easy_perform */ } break; |