cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: duphandle and multi interface

From: Frank Hempel <lists_at_frankoni.net>
Date: Sun, 29 Apr 2007 16:50:36 +0200

Daniel Stenberg schrieb:
> On Sat, 28 Apr 2007, Frank Hempel wrote:
>
>> When I have used an easy handle on a multi stack, I can only duplicate
>> it as long as it belongs to the (living) multi stack. As soon as one
>> removes it from the multi handle (curl_multi_remove_handle) or cleans
>> up the whole multi handle (curl_multi_cleanup), it can be no longer
>> duplicated
>
> Thanks a lot for this and the crash-fix. I've committed both changes now.
>

Pleasure!

I appended another patch which adds functionality to copy/clone the
cookie information between easy handles. You may not find this very
useful because one is already being able to share cookie information
between easy handles with an appropriate share handle. But I have the
situation where I want to start multiple transfers all having the same
"http history" (->same cookies) but allowing those multiple transfers to
have different cookies from then.

Ciao, Frank

diff -U3 -p -r curl-7.16.2/include/curl/easy.h curl-7.16.2-dupcookie/include/curl/easy.h
--- curl-7.16.2/include/curl/easy.h 2004-11-09 15:02:58.000000000 +0100
+++ curl-7.16.2-dupcookie/include/curl/easy.h 2007-04-29 15:00:43.000000000 +0200
@@ -62,6 +62,16 @@ CURL_EXTERN CURLcode curl_easy_getinfo(C
 CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
 
 /*
+ * NAME curl_easy_dupcookies()
+ *
+ * DESCRIPTION
+ *
+ * Copies the cookie information of a given easy handle to another given easy
+ * handle discarding the cookie information of the destination handle.
+ */
+CURL_EXTERN CURLcode curl_easy_dupcookies(CURL *destcurl, CURL *srccurl);
+
+/*
  * NAME curl_easy_reset()
  *
  * DESCRIPTION
diff -U3 -p -r curl-7.16.2/lib/cookie.c curl-7.16.2-dupcookie/lib/cookie.c
--- curl-7.16.2/lib/cookie.c 2007-04-08 22:37:00.000000000 +0200
+++ curl-7.16.2-dupcookie/lib/cookie.c 2007-04-29 16:12:08.000000000 +0200
@@ -1023,4 +1023,110 @@ struct curl_slist *Curl_cookie_list(stru
   return list;
 }
 
+static struct Cookie* clonecookie(struct Cookie* data)
+{
+ bool fail = TRUE;
+ struct Cookie* ret = (struct Cookie*)calloc(1, sizeof(struct Cookie));
+ if (!ret) return NULL;
+
+ ret->expires = data->expires;
+ ret->tailmatch = data->tailmatch;
+ ret->secure = data->secure;
+ ret->livecookie = data->livecookie;
+
+ do {
+ if (data->name) {
+ ret->name = strdup(data->name);
+ if (!ret->name) break;
+ }
+
+ if (data->value) {
+ ret->value = strdup(data->value);
+ if (!ret->value) break;
+ }
+
+ if (data->path) {
+ ret->path = strdup(data->path);
+ if (!ret->path) break;
+ }
+
+ if (data->domain) {
+ ret->domain = strdup(data->domain);
+ if (!ret->domain) break;
+ }
+
+ if (data->expirestr) {
+ ret->expirestr = strdup(data->expirestr);
+ if (!ret->expirestr) break;
+ }
+
+ if (data->version) {
+ ret->version = strdup(data->version);
+ if (!ret->version) break;
+ }
+
+ if (data->maxage) {
+ ret->maxage = strdup(data->maxage);
+ if (!ret->maxage) break;
+ }
+
+ fail = FALSE; /* we reach this point and thus we are OK */
+
+ } while(0);
+
+ if (fail) {
+ freecookie(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+/*
+ * Curl_cookie_clone()
+ *
+ * Clones the whole CookieInfo struct. Will be used in curl_easy_dupcookies().
+ *
+ * The function returns NULL on error.
+ */
+struct CookieInfo* Curl_cookie_clone(struct CookieInfo *data)
+{
+ struct CookieInfo *ret;
+
+ ret = (struct CookieInfo *)calloc(1, sizeof(struct CookieInfo));
+ if (!ret) return NULL;
+
+ ret->running = data->running;
+ ret->numcookies = data->numcookies;
+ ret->newsession = data->newsession;
+
+ if (data->filename) {
+ ret->filename = strdup(data->filename);
+ if (!ret->filename) {
+ free(ret);
+ return NULL;
+ }
+ }
+
+ // clone the cookies
+ struct Cookie* tmpdata = data->cookies;
+ struct Cookie* tmpret = NULL;
+
+ while(tmpdata) {
+ struct Cookie* newcookie = clonecookie(tmpdata);
+ if (!newcookie) {
+ Curl_cookie_cleanup(ret);
+ return NULL;
+ }
+
+ if (!ret->cookies) ret->cookies = newcookie;
+ else tmpret->next = newcookie;
+
+ tmpret = newcookie;
+ tmpdata = tmpdata->next;
+ }
+
+ return ret;
+}
+
 #endif /* CURL_DISABLE_HTTP || CURL_DISABLE_COOKIES */
diff -U3 -p -r curl-7.16.2/lib/cookie.h curl-7.16.2-dupcookie/lib/cookie.h
--- curl-7.16.2/lib/cookie.h 2006-08-31 23:45:44.000000000 +0200
+++ curl-7.16.2-dupcookie/lib/cookie.h 2007-04-29 14:53:03.000000000 +0200
@@ -95,6 +95,7 @@ void Curl_cookie_clearall(struct CookieI
 void Curl_cookie_clearsess(struct CookieInfo *cookies);
 void Curl_cookie_cleanup(struct CookieInfo *);
 int Curl_cookie_output(struct CookieInfo *, char *);
+struct CookieInfo *Curl_cookie_clone(struct CookieInfo *data);
 
 #if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
 #define Curl_cookie_list(x) NULL
diff -U3 -p -r curl-7.16.2/lib/easy.c curl-7.16.2-dupcookie/lib/easy.c
--- curl-7.16.2/lib/easy.c 2007-04-28 18:41:58.000000000 +0200
+++ curl-7.16.2-dupcookie/lib/easy.c 2007-04-29 15:10:36.000000000 +0200
@@ -653,6 +653,32 @@ CURL *curl_easy_duphandle(CURL *incurl)
   return outcurl;
 }
 
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
+
+/*
+ * curl_easy_dupcookies() is an external interface to allow duplication of the
+ * cookieInfo-struct of a given input easy handle to a given destination easy handle.
+ */
+CURLcode curl_easy_dupcookies(CURL *destcurl, CURL *srccurl)
+{
+ struct SessionHandle *src = (struct SessionHandle *)srccurl;
+ struct SessionHandle *dest = (struct SessionHandle *)destcurl;
+
+ struct CookieInfo* clonedCookies = NULL;
+
+ if (src->cookies) {
+ clonedCookies = Curl_cookie_clone(src->cookies);
+ if (!clonedCookies) return CURLE_OUT_OF_MEMORY;
+ }
+
+ Curl_cookie_cleanup(dest->cookies);
+ dest->cookies = clonedCookies;
+
+ return CURLE_OK;
+}
+
+#endif
+
 /*
  * curl_easy_reset() is an external interface that allows an app to re-
  * initialize a session handle to the default values.
Received on 2007-04-29