summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Gustafsson <daniel@yesql.se>2021-02-25 18:12:28 +0100
committerDaniel Gustafsson <daniel@yesql.se>2021-02-25 18:12:28 +0100
commit82c583dcf009f038a9ceccc695f942f24015f9ab (patch)
tree8bf04adb2ee16faa8406b5b3cabd516f6b223dc5
parent1b2098c3c9580c431cc9c4b110249abfd94792ed (diff)
downloadcurl-82c583dcf009f038a9ceccc695f942f24015f9ab.tar.gz
cookies: Support multiple -b parameters
Previously only a single -b cookie parameter was supported with the last one winning. This adds support for supplying multiple -b params to have them serialized semicolon separated. Both cookiefiles and cookies can be entered multiple times. Closes #6649 Reviewed-by: Daniel Stenberg <daniel@haxx.se>
-rw-r--r--docs/cmdline-opts/cookie.d2
-rw-r--r--src/tool_cfgable.c4
-rw-r--r--src/tool_cfgable.h4
-rw-r--r--src/tool_getparam.c8
-rw-r--r--src/tool_operate.c33
-rw-r--r--tests/data/test3298
-rw-r--r--tests/data/test64
7 files changed, 48 insertions, 15 deletions
diff --git a/docs/cmdline-opts/cookie.d b/docs/cmdline-opts/cookie.d
index 5d2c9d783..d5e63e427 100644
--- a/docs/cmdline-opts/cookie.d
+++ b/docs/cmdline-opts/cookie.d
@@ -31,7 +31,7 @@ name then both will be sent on a future transfer to that server, likely not
what you intended. To address these issues set a domain in Set-Cookie (doing
that will include sub domains) or use the Netscape format.
-If this option is used several times, the last one will be used.
+This option can be used multiple times.
Users very often want to both read cookies from a file and write updated
cookies back to a file, so using both --cookie and --cookie-jar in the same
diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c
index ea186a7c3..c3f7cecb1 100644
--- a/src/tool_cfgable.c
+++ b/src/tool_cfgable.c
@@ -56,9 +56,9 @@ static void free_config_fields(struct OperationConfig *config)
Curl_safefree(config->useragent);
Curl_safefree(config->altsvc);
Curl_safefree(config->hsts);
- Curl_safefree(config->cookie);
+ curl_slist_free_all(config->cookies);
Curl_safefree(config->cookiejar);
- Curl_safefree(config->cookiefile);
+ curl_slist_free_all(config->cookiefiles);
Curl_safefree(config->postfields);
Curl_safefree(config->referer);
diff --git a/src/tool_cfgable.h b/src/tool_cfgable.h
index bd84315f5..95c66d081 100644
--- a/src/tool_cfgable.h
+++ b/src/tool_cfgable.h
@@ -54,9 +54,9 @@ struct OperationConfig {
char *random_file;
char *egd_file;
char *useragent;
- char *cookie; /* single line with specified cookies */
+ struct curl_slist *cookies; /* cookies to serialize into a single line */
char *cookiejar; /* write to this file */
- char *cookiefile; /* read from this file */
+ struct curl_slist *cookiefiles; /* file(s) to load cookies from */
char *altsvc; /* alt-svc cache file name */
char *hsts; /* HSTS cache file name */
bool cookiesession; /* new session? */
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index 5b155cf00..f1393c373 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -1320,11 +1320,15 @@ ParameterError getparameter(const char *flag, /* f or -long-flag */
}
else if(strchr(nextarg, '=')) {
/* A cookie string must have a =-letter */
- GetStr(&config->cookie, nextarg);
+ err = add2list(&config->cookies, nextarg);
+ if(err)
+ return err;
break;
}
/* We have a cookie file to read from! */
- GetStr(&config->cookiefile, nextarg);
+ err = add2list(&config->cookiefiles, nextarg);
+ if(err)
+ return err;
}
break;
case 'B':
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 2605a4cdf..e2b287269 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -82,6 +82,7 @@
#include "tool_help.h"
#include "tool_hugehelp.h"
#include "tool_progress.h"
+#include "dynbuf.h"
#include "memdebug.h" /* keep this as LAST include */
@@ -1765,11 +1766,35 @@ static CURLcode single_transfer(struct GlobalConfig *global,
my_setopt_slist(curl, CURLOPT_POSTQUOTE, config->postquote);
my_setopt_slist(curl, CURLOPT_PREQUOTE, config->prequote);
- if(config->cookie)
- my_setopt_str(curl, CURLOPT_COOKIE, config->cookie);
+ if(config->cookies) {
+ struct curlx_dynbuf cookies;
+ struct curl_slist *cl;
+ CURLcode ret;
- if(config->cookiefile)
- my_setopt_str(curl, CURLOPT_COOKIEFILE, config->cookiefile);
+ /* The maximum size needs to match MAX_NAME in cookie.h */
+ curlx_dyn_init(&cookies, 4096);
+ for(cl = config->cookies; cl; cl = cl->next) {
+ if(cl == config->cookies)
+ ret = curlx_dyn_addf(&cookies, "%s", cl->data);
+ else
+ ret = curlx_dyn_addf(&cookies, ";%s", cl->data);
+
+ if(ret) {
+ result = CURLE_OUT_OF_MEMORY;
+ break;
+ }
+ }
+
+ my_setopt_str(curl, CURLOPT_COOKIE, curlx_dyn_ptr(&cookies));
+ curlx_dyn_free(&cookies);
+ }
+
+ if(config->cookiefiles) {
+ struct curl_slist *cfl;
+
+ for(cfl = config->cookiefiles; cfl; cfl = cfl->next)
+ my_setopt_str(curl, CURLOPT_COOKIEFILE, cfl->data);
+ }
/* new in libcurl 7.9 */
if(config->cookiejar)
diff --git a/tests/data/test329 b/tests/data/test329
index 81b8383c1..67aac4baa 100644
--- a/tests/data/test329
+++ b/tests/data/test329
@@ -33,6 +33,9 @@ moo
<file name="log/jar329.txt" mode="text">
.host.foo.com TRUE /we/want/ FALSE 2147483647 test no
</file>
+<file name="log/jar329-2.txt" mode="text">
+.host.foo.com TRUE /we/want/ FALSE 2147483647 tester yes
+</file>
<server>
http
</server>
@@ -46,7 +49,7 @@ HTTP cookie with Max-Age=0
TZ=GMT
</setenv>
<command>
-http://%HOSTIP:%HTTPPORT/we/want/329 -b log/jar329.txt -H "Host: host.foo.com" http://%HOSTIP:%HTTPPORT/we/want/3290002
+http://%HOSTIP:%HTTPPORT/we/want/329 -b log/jar329.txt -b log/jar329-2.txt -H "Host: host.foo.com" http://%HOSTIP:%HTTPPORT/we/want/3290002
</command>
</client>
@@ -57,12 +60,13 @@ GET /we/want/329 HTTP/1.1
Host: host.foo.com
User-Agent: curl/%VERSION
Accept: */*
-Cookie: test=no
+Cookie: tester=yes; test=no
GET /we/want/3290002 HTTP/1.1
Host: host.foo.com
User-Agent: curl/%VERSION
Accept: */*
+Cookie: tester=yes
</protocol>
</verify>
diff --git a/tests/data/test6 b/tests/data/test6
index efd15a901..bbd67cbf8 100644
--- a/tests/data/test6
+++ b/tests/data/test6
@@ -29,7 +29,7 @@ http
HTTP with simple cookie send
</name>
<command>
-http://%HOSTIP:%HTTPPORT/we/want/that/page/6 -b "name=contents;name2=content2"
+http://%HOSTIP:%HTTPPORT/we/want/that/page/6 -b "name=contents;name2=content2" -b name3=content3
</command>
</client>
@@ -40,7 +40,7 @@ GET /we/want/that/page/6 HTTP/1.1
Host: %HOSTIP:%HTTPPORT
User-Agent: curl/%VERSION
Accept: */*
-Cookie: name=contents;name2=content2
+Cookie: name=contents;name2=content2;name3=content3
</protocol>
</verify>