|
|
c260e0 |
From 4ce37d79704623778fbe266397c85ed2b735e4dd Mon Sep 17 00:00:00 2001
|
|
|
c260e0 |
From: Daniel Stenberg <daniel@haxx.se>
|
|
|
c260e0 |
Date: Fri, 15 Mar 2013 14:18:16 +0100
|
|
|
c260e0 |
Subject: [PATCH 1/7] HTTP proxy: insert slash in URL if missing
|
|
|
c260e0 |
|
|
|
c260e0 |
curl has been accepting URLs using slightly wrong syntax for a long
|
|
|
c260e0 |
time, such as when completely missing as slash "http://example.org" or
|
|
|
c260e0 |
missing a slash when a query part is given
|
|
|
c260e0 |
"http://example.org?q=foobar".
|
|
|
c260e0 |
|
|
|
c260e0 |
curl would translate these into a legitimate HTTP request to servers,
|
|
|
c260e0 |
although as was shown in bug #1206 it was not adjusted properly in the
|
|
|
c260e0 |
cases where a HTTP proxy was used.
|
|
|
c260e0 |
|
|
|
c260e0 |
Test 1213 and 1214 were added to the test suite to verify this fix.
|
|
|
c260e0 |
|
|
|
c260e0 |
The test HTTP server was adjusted to allow us to specify test number in
|
|
|
c260e0 |
the host name only without using any slashes in a given URL.
|
|
|
c260e0 |
|
|
|
c260e0 |
Bug: http://curl.haxx.se/bug/view.cgi?id=1206
|
|
|
c260e0 |
Reported by: ScottJi
|
|
|
c260e0 |
|
|
|
c260e0 |
Upstream-commit: e4b733e3f1a771bd1017cdcfb355fcb9caffe646
|
|
|
c260e0 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
c260e0 |
---
|
|
|
c260e0 |
lib/url.c | 38 ++++++++++++++++++++++++++++++++++
|
|
|
c260e0 |
tests/FILEFORMAT | 4 ++++
|
|
|
c260e0 |
tests/data/Makefile.am | 2 +-
|
|
|
c260e0 |
tests/data/Makefile.in | 2 +-
|
|
|
c260e0 |
tests/data/test1213 | 53 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
c260e0 |
tests/data/test1214 | 53 +++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
c260e0 |
tests/server/sws.c | 56 ++++++++++++++++++++++++++++++++++++++++++--------
|
|
|
c260e0 |
7 files changed, 198 insertions(+), 10 deletions(-)
|
|
|
c260e0 |
create mode 100644 tests/data/test1213
|
|
|
c260e0 |
create mode 100644 tests/data/test1214
|
|
|
c260e0 |
|
|
|
c260e0 |
diff --git a/lib/url.c b/lib/url.c
|
|
|
c260e0 |
index 181f0a4..77549ba 100644
|
|
|
c260e0 |
--- a/lib/url.c
|
|
|
c260e0 |
+++ b/lib/url.c
|
|
|
c260e0 |
@@ -3584,6 +3584,7 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
|
|
|
c260e0 |
char protobuf[16];
|
|
|
c260e0 |
const char *protop;
|
|
|
c260e0 |
CURLcode result;
|
|
|
c260e0 |
+ bool fix_slash = FALSE;
|
|
|
c260e0 |
|
|
|
c260e0 |
*prot_missing = FALSE;
|
|
|
c260e0 |
|
|
|
c260e0 |
@@ -3730,12 +3731,14 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
|
|
|
c260e0 |
memcpy(path+1, query, hostlen);
|
|
|
c260e0 |
|
|
|
c260e0 |
path[0]='/'; /* prepend the missing slash */
|
|
|
c260e0 |
+ fix_slash = TRUE;
|
|
|
c260e0 |
|
|
|
c260e0 |
*query=0; /* now cut off the hostname at the ? */
|
|
|
c260e0 |
}
|
|
|
c260e0 |
else if(!path[0]) {
|
|
|
c260e0 |
/* if there's no path set, use a single slash */
|
|
|
c260e0 |
strcpy(path, "/");
|
|
|
c260e0 |
+ fix_slash = TRUE;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
|
|
|
c260e0 |
/* If the URL is malformatted (missing a '/' after hostname before path) we
|
|
|
c260e0 |
@@ -3748,6 +3751,41 @@ static CURLcode parseurlandfillconn(struct SessionHandle *data,
|
|
|
c260e0 |
is bigger than the path. Use +1 to move the zero byte too. */
|
|
|
c260e0 |
memmove(&path[1], path, strlen(path)+1);
|
|
|
c260e0 |
path[0] = '/';
|
|
|
c260e0 |
+ fix_slash = TRUE;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /*
|
|
|
c260e0 |
+ * "fix_slash" means that the URL was malformatted so we need to generate an
|
|
|
c260e0 |
+ * updated version with the new slash inserted at the right place! We need
|
|
|
c260e0 |
+ * the corrected URL when communicating over HTTP proxy and we don't know at
|
|
|
c260e0 |
+ * this point if we're using a proxy or not.
|
|
|
c260e0 |
+ */
|
|
|
c260e0 |
+ if(fix_slash) {
|
|
|
c260e0 |
+ char *reurl;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ size_t plen = strlen(path); /* new path, should be 1 byte longer than
|
|
|
c260e0 |
+ the original */
|
|
|
c260e0 |
+ size_t urllen = strlen(data->change.url); /* original URL length */
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */
|
|
|
c260e0 |
+ if(!reurl)
|
|
|
c260e0 |
+ return CURLE_OUT_OF_MEMORY;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* copy the prefix */
|
|
|
c260e0 |
+ memcpy(reurl, data->change.url, urllen - (plen-1));
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* append the trailing piece + zerobyte */
|
|
|
c260e0 |
+ memcpy(&reurl[urllen - (plen-1)], path, plen + 1);
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* possible free the old one */
|
|
|
c260e0 |
+ if(data->change.url_alloc) {
|
|
|
c260e0 |
+ Curl_safefree(data->change.url);
|
|
|
c260e0 |
+ data->change.url_alloc = FALSE;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ data->change.url = reurl;
|
|
|
c260e0 |
+ data->change.url_alloc = TRUE; /* free this later */
|
|
|
c260e0 |
}
|
|
|
c260e0 |
|
|
|
c260e0 |
/*************************************************************
|
|
|
c260e0 |
diff --git a/tests/FILEFORMAT b/tests/FILEFORMAT
|
|
|
c260e0 |
index d79cbf7..96cd5c8 100644
|
|
|
c260e0 |
--- a/tests/FILEFORMAT
|
|
|
c260e0 |
+++ b/tests/FILEFORMAT
|
|
|
c260e0 |
@@ -250,6 +250,10 @@ If a CONNECT is used to the server (to emulate HTTPS etc over proxy), the port
|
|
|
c260e0 |
number given in the CONNECT request will be used to identify which test that
|
|
|
c260e0 |
is being run, if the proxy host name is said to start with 'test'.
|
|
|
c260e0 |
|
|
|
c260e0 |
+If there's no non-zero test number found in the above to places, the HTTP test
|
|
|
c260e0 |
+server will use the number following the last dot in the given url so that
|
|
|
c260e0 |
+"foo.bar.123" gets treated as test case 123.
|
|
|
c260e0 |
+
|
|
|
c260e0 |
Set type="perl" to write the test case as a perl script. It implies that
|
|
|
c260e0 |
there's no memory debugging and valgrind gets shut off for this test.
|
|
|
c260e0 |
|
|
|
c260e0 |
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
|
|
|
c260e0 |
index 4e37ed9..5e12f62 100644
|
|
|
c260e0 |
--- a/tests/data/Makefile.am
|
|
|
c260e0 |
+++ b/tests/data/Makefile.am
|
|
|
c260e0 |
@@ -77,7 +77,7 @@ test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 \
|
|
|
c260e0 |
test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125 \
|
|
|
c260e0 |
test1126 test1127 test1128 test1129 test1130 test1131 test1132 test1133 \
|
|
|
c260e0 |
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
|
|
|
c260e0 |
-test1208 test1209 test1210 test1211 test1216 test1218 \
|
|
|
c260e0 |
+test1208 test1209 test1210 test1211 test1213 test1214 test1216 test1218 \
|
|
|
c260e0 |
test1220 test1221 test1222 test1223 test1233 \
|
|
|
c260e0 |
test1300 test1301 test1302 test1303 test1304 test1305 \
|
|
|
c260e0 |
test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
|
|
|
c260e0 |
diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in
|
|
|
c260e0 |
index d7f9ac2..597c1fb 100644
|
|
|
c260e0 |
--- a/tests/data/Makefile.in
|
|
|
c260e0 |
+++ b/tests/data/Makefile.in
|
|
|
c260e0 |
@@ -341,7 +341,7 @@ test1110 test1111 test1112 test1113 test1114 test1115 test1116 test1117 \
|
|
|
c260e0 |
test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125 \
|
|
|
c260e0 |
test1126 test1127 test1128 test1129 test1130 test1131 test1132 test1133 \
|
|
|
c260e0 |
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
|
|
|
c260e0 |
-test1208 test1209 test1210 test1211 test1216 test1218 \
|
|
|
c260e0 |
+test1208 test1209 test1210 test1211 test1213 test1214 test1216 test1218 \
|
|
|
c260e0 |
test1220 test1221 test1222 test1223 \
|
|
|
c260e0 |
test1300 test1301 test1302 test1303 test1304 test1305 \
|
|
|
c260e0 |
test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
|
|
|
c260e0 |
diff --git a/tests/data/test1213 b/tests/data/test1213
|
|
|
c260e0 |
new file mode 100644
|
|
|
c260e0 |
index 0000000..d0d12b4
|
|
|
c260e0 |
--- /dev/null
|
|
|
c260e0 |
+++ b/tests/data/test1213
|
|
|
c260e0 |
@@ -0,0 +1,53 @@
|
|
|
c260e0 |
+<testcase>
|
|
|
c260e0 |
+<info>
|
|
|
c260e0 |
+<keywords>
|
|
|
c260e0 |
+HTTP
|
|
|
c260e0 |
+HTTP GET
|
|
|
c260e0 |
+HTTP proxy
|
|
|
c260e0 |
+</keywords>
|
|
|
c260e0 |
+</info>
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+# Server-side
|
|
|
c260e0 |
+<reply>
|
|
|
c260e0 |
+<data>
|
|
|
c260e0 |
+HTTP/1.1 200 OK
|
|
|
c260e0 |
+Date: Thu, 09 Nov 2010 14:49:00 GMT
|
|
|
c260e0 |
+Server: test-server/fake
|
|
|
c260e0 |
+Content-Type: text/html
|
|
|
c260e0 |
+Funny-head: yesyes
|
|
|
c260e0 |
+Content-Length: 22
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+the content goes here
|
|
|
c260e0 |
+</data>
|
|
|
c260e0 |
+</reply>
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+# Client-side
|
|
|
c260e0 |
+<client>
|
|
|
c260e0 |
+<server>
|
|
|
c260e0 |
+http
|
|
|
c260e0 |
+</server>
|
|
|
c260e0 |
+ <name>
|
|
|
c260e0 |
+HTTP with proxy and host-only URL
|
|
|
c260e0 |
+ </name>
|
|
|
c260e0 |
+# the thing here is that this sloppy form is accepted and we convert it
|
|
|
c260e0 |
+# for normal server use, and we need to make sure it gets converted to
|
|
|
c260e0 |
+# RFC style even for proxies
|
|
|
c260e0 |
+ <command>
|
|
|
c260e0 |
+-x %HOSTIP:%HTTPPORT we.want.that.site.com.1213
|
|
|
c260e0 |
+</command>
|
|
|
c260e0 |
+</client>
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+# Verify data after the test has been "shot"
|
|
|
c260e0 |
+<verify>
|
|
|
c260e0 |
+<strip>
|
|
|
c260e0 |
+^User-Agent:.*
|
|
|
c260e0 |
+</strip>
|
|
|
c260e0 |
+<protocol>
|
|
|
c260e0 |
+GET HTTP://we.want.that.site.com.1213/ HTTP/1.1
|
|
|
c260e0 |
+Host: we.want.that.site.com.1213
|
|
|
c260e0 |
+Accept: */*
|
|
|
c260e0 |
+Proxy-Connection: Keep-Alive
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+</protocol>
|
|
|
c260e0 |
+</verify>
|
|
|
c260e0 |
+</testcase>
|
|
|
c260e0 |
diff --git a/tests/data/test1214 b/tests/data/test1214
|
|
|
c260e0 |
new file mode 100644
|
|
|
c260e0 |
index 0000000..8c36ade
|
|
|
c260e0 |
--- /dev/null
|
|
|
c260e0 |
+++ b/tests/data/test1214
|
|
|
c260e0 |
@@ -0,0 +1,53 @@
|
|
|
c260e0 |
+<testcase>
|
|
|
c260e0 |
+<info>
|
|
|
c260e0 |
+<keywords>
|
|
|
c260e0 |
+HTTP
|
|
|
c260e0 |
+HTTP GET
|
|
|
c260e0 |
+HTTP proxy
|
|
|
c260e0 |
+</keywords>
|
|
|
c260e0 |
+</info>
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+# Server-side
|
|
|
c260e0 |
+<reply>
|
|
|
c260e0 |
+<data>
|
|
|
c260e0 |
+HTTP/1.1 200 OK
|
|
|
c260e0 |
+Date: Thu, 09 Nov 2010 14:49:00 GMT
|
|
|
c260e0 |
+Server: test-server/fake
|
|
|
c260e0 |
+Content-Type: text/html
|
|
|
c260e0 |
+Funny-head: yesyes
|
|
|
c260e0 |
+Content-Length: 22
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+the content goes here
|
|
|
c260e0 |
+</data>
|
|
|
c260e0 |
+</reply>
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+# Client-side
|
|
|
c260e0 |
+<client>
|
|
|
c260e0 |
+<server>
|
|
|
c260e0 |
+http
|
|
|
c260e0 |
+</server>
|
|
|
c260e0 |
+ <name>
|
|
|
c260e0 |
+HTTP with proxy and URL with ? and no slash separator
|
|
|
c260e0 |
+ </name>
|
|
|
c260e0 |
+# the thing here is that this sloppy form is accepted and we convert it
|
|
|
c260e0 |
+# for normal server use, and we need to make sure it gets converted to
|
|
|
c260e0 |
+# RFC style even for proxies
|
|
|
c260e0 |
+ <command>
|
|
|
c260e0 |
+-x %HOSTIP:%HTTPPORT http://we.want.that.site.com.1214?moo=foo
|
|
|
c260e0 |
+</command>
|
|
|
c260e0 |
+</client>
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+# Verify data after the test has been "shot"
|
|
|
c260e0 |
+<verify>
|
|
|
c260e0 |
+<strip>
|
|
|
c260e0 |
+^User-Agent:.*
|
|
|
c260e0 |
+</strip>
|
|
|
c260e0 |
+<protocol>
|
|
|
c260e0 |
+GET http://we.want.that.site.com.1214/?moo=foo HTTP/1.1
|
|
|
c260e0 |
+Host: we.want.that.site.com.1214
|
|
|
c260e0 |
+Accept: */*
|
|
|
c260e0 |
+Proxy-Connection: Keep-Alive
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+</protocol>
|
|
|
c260e0 |
+</verify>
|
|
|
c260e0 |
+</testcase>
|
|
|
c260e0 |
diff --git a/tests/server/sws.c b/tests/server/sws.c
|
|
|
c260e0 |
index a7de09f..aef55ea 100644
|
|
|
c260e0 |
--- a/tests/server/sws.c
|
|
|
c260e0 |
+++ b/tests/server/sws.c
|
|
|
c260e0 |
@@ -507,15 +507,24 @@ static int ProcessRequest(struct httprequest *req)
|
|
|
c260e0 |
else
|
|
|
c260e0 |
req->partno = 0;
|
|
|
c260e0 |
|
|
|
c260e0 |
- sprintf(logbuf, "Requested test number %ld part %ld",
|
|
|
c260e0 |
- req->testno, req->partno);
|
|
|
c260e0 |
- logmsg("%s", logbuf);
|
|
|
c260e0 |
+ if(req->testno) {
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ sprintf(logbuf, "Requested test number %ld part %ld",
|
|
|
c260e0 |
+ req->testno, req->partno);
|
|
|
c260e0 |
+ logmsg("%s", logbuf);
|
|
|
c260e0 |
|
|
|
c260e0 |
- /* find and parse <servercmd> for this test */
|
|
|
c260e0 |
- parse_servercmd(req);
|
|
|
c260e0 |
+ /* find and parse <servercmd> for this test */
|
|
|
c260e0 |
+ parse_servercmd(req);
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+ else
|
|
|
c260e0 |
+ req->testno = DOCNUMBER_NOTHING;
|
|
|
c260e0 |
|
|
|
c260e0 |
}
|
|
|
c260e0 |
- else {
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ if(req->testno == DOCNUMBER_NOTHING) {
|
|
|
c260e0 |
+ /* didn't find any in the first scan, try alternative test case
|
|
|
c260e0 |
+ number placements */
|
|
|
c260e0 |
+
|
|
|
c260e0 |
if(sscanf(req->reqbuf, "CONNECT %" MAXDOCNAMELEN_TXT "s HTTP/%d.%d",
|
|
|
c260e0 |
doc, &prot_major, &prot_minor) == 3) {
|
|
|
c260e0 |
char *portp = NULL;
|
|
|
c260e0 |
@@ -563,8 +572,39 @@ static int ProcessRequest(struct httprequest *req)
|
|
|
c260e0 |
parse_servercmd(req);
|
|
|
c260e0 |
}
|
|
|
c260e0 |
else {
|
|
|
c260e0 |
- logmsg("Did not find test number in PATH");
|
|
|
c260e0 |
- req->testno = DOCNUMBER_404;
|
|
|
c260e0 |
+ /* there was no trailing slash and it wasn't CONNECT, then we get the
|
|
|
c260e0 |
+ the number off the last dot instead, IE we consider the TLD to be
|
|
|
c260e0 |
+ the test number. Test 123 can then be written as
|
|
|
c260e0 |
+ "example.com.123". */
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* find the last dot */
|
|
|
c260e0 |
+ ptr = strrchr(doc, '.');
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* get the number after it */
|
|
|
c260e0 |
+ if(ptr) {
|
|
|
c260e0 |
+ ptr++; /* skip the dot */
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ req->testno = strtol(ptr, &ptr, 10);
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ if(req->testno > 10000) {
|
|
|
c260e0 |
+ req->partno = req->testno % 10000;
|
|
|
c260e0 |
+ req->testno /= 10000;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+ else
|
|
|
c260e0 |
+ req->partno = 0;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ sprintf(logbuf, "Requested test number %ld part %ld (from host name)",
|
|
|
c260e0 |
+ req->testno, req->partno);
|
|
|
c260e0 |
+ logmsg("%s", logbuf);
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ if(!req->testno) {
|
|
|
c260e0 |
+ logmsg("Did not find test number in PATH");
|
|
|
c260e0 |
+ req->testno = DOCNUMBER_404;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+ else
|
|
|
c260e0 |
+ parse_servercmd(req);
|
|
|
c260e0 |
}
|
|
|
c260e0 |
}
|
|
|
c260e0 |
}
|
|
|
c260e0 |
--
|
|
|
c260e0 |
2.1.0
|
|
|
c260e0 |
|
|
|
c260e0 |
|
|
|
c260e0 |
From 052143a4aaac9ce91ffdb6ae88eb5888c54d66aa Mon Sep 17 00:00:00 2001
|
|
|
c260e0 |
From: YAMADA Yasuharu <yasuharu.yamada@access-company.com>
|
|
|
c260e0 |
Date: Sat, 18 May 2013 22:51:31 +0200
|
|
|
c260e0 |
Subject: [PATCH 2/7] cookies: only consider full path matches
|
|
|
c260e0 |
|
|
|
c260e0 |
I found a bug which cURL sends cookies to the path not to aim at.
|
|
|
c260e0 |
For example:
|
|
|
c260e0 |
- cURL sends a request to http://example.fake/hoge/
|
|
|
c260e0 |
- server returns cookie which with path=/hoge;
|
|
|
c260e0 |
the point is there is NOT the '/' end of path string.
|
|
|
c260e0 |
- cURL sends a request to http://example.fake/hogege/ with the cookie.
|
|
|
c260e0 |
|
|
|
c260e0 |
The reason for this old "feature" is because that behavior is what is
|
|
|
c260e0 |
described in the original netscape cookie spec:
|
|
|
c260e0 |
http://curl.haxx.se/rfc/cookie_spec.html
|
|
|
c260e0 |
|
|
|
c260e0 |
The current cookie spec (RFC6265) clarifies the situation:
|
|
|
c260e0 |
http://tools.ietf.org/html/rfc6265#section-5.2.4
|
|
|
c260e0 |
Upstream-commit: 04f52e9b4db01bcbf672c9c69303a4e4ad0d0fb9
|
|
|
c260e0 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
c260e0 |
---
|
|
|
c260e0 |
lib/cookie.c | 33 ++++++++++++++++++++++++++----
|
|
|
c260e0 |
tests/data/Makefile.am | 2 +-
|
|
|
c260e0 |
tests/data/Makefile.in | 2 +-
|
|
|
c260e0 |
tests/data/test1228 | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
c260e0 |
tests/data/test46 | 8 ++++----
|
|
|
c260e0 |
tests/data/test8 | 2 +-
|
|
|
c260e0 |
6 files changed, 90 insertions(+), 11 deletions(-)
|
|
|
c260e0 |
create mode 100644 tests/data/test1228
|
|
|
c260e0 |
|
|
|
c260e0 |
diff --git a/lib/cookie.c b/lib/cookie.c
|
|
|
c260e0 |
index ac4d89c..a4480c0 100644
|
|
|
c260e0 |
--- a/lib/cookie.c
|
|
|
c260e0 |
+++ b/lib/cookie.c
|
|
|
c260e0 |
@@ -143,6 +143,34 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
|
|
|
c260e0 |
return FALSE;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
|
|
|
c260e0 |
+static bool pathmatch(const char* cookie_path, const char* url_path)
|
|
|
c260e0 |
+{
|
|
|
c260e0 |
+ size_t cookie_path_len = strlen(cookie_path);
|
|
|
c260e0 |
+ size_t url_path_len = strlen(url_path);
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ if(url_path_len < cookie_path_len)
|
|
|
c260e0 |
+ return FALSE;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* not using checkprefix() because matching should be case-sensitive */
|
|
|
c260e0 |
+ if(strncmp(cookie_path, url_path, cookie_path_len))
|
|
|
c260e0 |
+ return FALSE;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* it is true if cookie_path and url_path are the same */
|
|
|
c260e0 |
+ if(cookie_path_len == url_path_len)
|
|
|
c260e0 |
+ return TRUE;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* here, cookie_path_len < url_path_len */
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* it is false if cookie path is /example and url path is /examples */
|
|
|
c260e0 |
+ if(cookie_path[cookie_path_len - 1] != '/') {
|
|
|
c260e0 |
+ if(url_path[cookie_path_len] != '/') {
|
|
|
c260e0 |
+ return FALSE;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+ /* matching! */
|
|
|
c260e0 |
+ return TRUE;
|
|
|
c260e0 |
+}
|
|
|
c260e0 |
+
|
|
|
c260e0 |
/*
|
|
|
c260e0 |
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
|
|
|
c260e0 |
*/
|
|
|
c260e0 |
@@ -841,10 +869,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
|
|
c260e0 |
|
|
|
c260e0 |
/* now check the left part of the path with the cookies path
|
|
|
c260e0 |
requirement */
|
|
|
c260e0 |
- if(!co->path ||
|
|
|
c260e0 |
- /* not using checkprefix() because matching should be
|
|
|
c260e0 |
- case-sensitive */
|
|
|
c260e0 |
- !strncmp(co->path, path, strlen(co->path)) ) {
|
|
|
c260e0 |
+ if(!co->path || pathmatch(co->path, path) ) {
|
|
|
c260e0 |
|
|
|
c260e0 |
/* and now, we know this is a match and we should create an
|
|
|
c260e0 |
entry for the return-linked-list */
|
|
|
c260e0 |
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
|
|
|
c260e0 |
index 4e37ed9..64662c6 100644
|
|
|
c260e0 |
--- a/tests/data/Makefile.am
|
|
|
c260e0 |
+++ b/tests/data/Makefile.am
|
|
|
c260e0 |
@@ -78,7 +78,7 @@ test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125 \
|
|
|
c260e0 |
test1126 test1127 test1128 test1129 test1130 test1131 test1132 test1133 \
|
|
|
c260e0 |
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
|
|
|
c260e0 |
test1208 test1209 test1210 test1211 test1213 test1214 test1216 test1218 \
|
|
|
c260e0 |
-test1220 test1221 test1222 test1223 test1233 \
|
|
|
c260e0 |
+test1220 test1221 test1222 test1223 test1233 test1236 \
|
|
|
c260e0 |
test1300 test1301 test1302 test1303 test1304 test1305 \
|
|
|
c260e0 |
test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
|
|
|
c260e0 |
test1314 test1315 test1316 test1317 test1318 test1319 test1320 test1321 \
|
|
|
c260e0 |
diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in
|
|
|
c260e0 |
index 1e6d679..5296c09 100644
|
|
|
c260e0 |
--- a/tests/data/Makefile.in
|
|
|
c260e0 |
+++ b/tests/data/Makefile.in
|
|
|
c260e0 |
@@ -342,7 +342,7 @@ test1118 test1119 test1120 test1121 test1122 test1123 test1124 test1125 \
|
|
|
c260e0 |
test1126 test1127 test1128 test1129 test1130 test1131 test1132 test1133 \
|
|
|
c260e0 |
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
|
|
|
c260e0 |
test1208 test1209 test1210 test1211 test1213 test1214 test1216 test1218 \
|
|
|
c260e0 |
-test1220 test1221 test1222 test1223 \
|
|
|
c260e0 |
+test1220 test1221 test1222 test1223 test1233 test1236 \
|
|
|
c260e0 |
test1300 test1301 test1302 test1303 test1304 test1305 \
|
|
|
c260e0 |
test1306 test1307 test1308 test1309 test1310 test1311 test1312 test1313 \
|
|
|
c260e0 |
test1314 test1315 test1316 test1317 test1318 test1319 test1320 test1321 \
|
|
|
c260e0 |
diff --git a/tests/data/test1228 b/tests/data/test1228
|
|
|
c260e0 |
new file mode 100644
|
|
|
c260e0 |
index 0000000..0a76b87
|
|
|
c260e0 |
--- /dev/null
|
|
|
c260e0 |
+++ b/tests/data/test1228
|
|
|
c260e0 |
@@ -0,0 +1,54 @@
|
|
|
c260e0 |
+<testcase>
|
|
|
c260e0 |
+<info>
|
|
|
c260e0 |
+<keywords>
|
|
|
c260e0 |
+HTTP
|
|
|
c260e0 |
+HTTP GET
|
|
|
c260e0 |
+cookies
|
|
|
c260e0 |
+cookie path
|
|
|
c260e0 |
+</keywords>
|
|
|
c260e0 |
+</info>
|
|
|
c260e0 |
+<reply>
|
|
|
c260e0 |
+<data>
|
|
|
c260e0 |
+HTTP/1.1 200 OK
|
|
|
c260e0 |
+Date: Tue, 25 Sep 2001 19:37:44 GMT
|
|
|
c260e0 |
+Set-Cookie: path1=root; domain=.example.fake; path=/;
|
|
|
c260e0 |
+Set-Cookie: path2=depth1; domain=.example.fake; path=/hoge;
|
|
|
c260e0 |
+Content-Length: 34
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+This server says cookie path test
|
|
|
c260e0 |
+</data>
|
|
|
c260e0 |
+</reply>
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+# Client-side
|
|
|
c260e0 |
+<client>
|
|
|
c260e0 |
+<server>
|
|
|
c260e0 |
+http
|
|
|
c260e0 |
+</server>
|
|
|
c260e0 |
+ <name>
|
|
|
c260e0 |
+HTTP cookie path match
|
|
|
c260e0 |
+ </name>
|
|
|
c260e0 |
+ <command>
|
|
|
c260e0 |
+http://example.fake/hoge/1228 http://example.fake/hogege/ -b nonexisting -x %HOSTIP:%HTTPPORT
|
|
|
c260e0 |
+</command>
|
|
|
c260e0 |
+</client>
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+# Verify data after the test has been "shot"
|
|
|
c260e0 |
+<verify>
|
|
|
c260e0 |
+<strip>
|
|
|
c260e0 |
+^User-Agent:.*
|
|
|
c260e0 |
+</strip>
|
|
|
c260e0 |
+<protocol>
|
|
|
c260e0 |
+GET http://example.fake/hoge/1228 HTTP/1.1
|
|
|
c260e0 |
+Host: example.fake
|
|
|
c260e0 |
+Accept: */*
|
|
|
c260e0 |
+Proxy-Connection: Keep-Alive
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+GET http://example.fake/hogege/ HTTP/1.1
|
|
|
c260e0 |
+Host: example.fake
|
|
|
c260e0 |
+Accept: */*
|
|
|
c260e0 |
+Proxy-Connection: Keep-Alive
|
|
|
c260e0 |
+Cookie: path1=root
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+</protocol>
|
|
|
c260e0 |
+</verify>
|
|
|
c260e0 |
+</testcase>
|
|
|
c260e0 |
diff --git a/tests/data/test46 b/tests/data/test46
|
|
|
c260e0 |
index f73acde..b6f8f83 100644
|
|
|
c260e0 |
--- a/tests/data/test46
|
|
|
c260e0 |
+++ b/tests/data/test46
|
|
|
c260e0 |
@@ -52,8 +52,8 @@ TZ=GMT
|
|
|
c260e0 |
www.fake.come FALSE / FALSE 1022144953 cookiecliente si
|
|
|
c260e0 |
www.loser.com FALSE / FALSE 1139150993 UID 99
|
|
|
c260e0 |
%HOSTIP FALSE / FALSE 1439150993 mooo indeed
|
|
|
c260e0 |
-#HttpOnly_%HOSTIP FALSE /w FALSE 1439150993 mooo2 indeed2
|
|
|
c260e0 |
-%HOSTIP FALSE /wa FALSE 0 empty
|
|
|
c260e0 |
+#HttpOnly_%HOSTIP FALSE /want FALSE 1439150993 mooo2 indeed2
|
|
|
c260e0 |
+%HOSTIP FALSE /want FALSE 0 empty
|
|
|
c260e0 |
</file>
|
|
|
c260e0 |
</client>
|
|
|
c260e0 |
|
|
|
c260e0 |
@@ -77,8 +77,8 @@ Cookie: empty=; mooo2=indeed2; mooo=indeed
|
|
|
c260e0 |
www.fake.come FALSE / FALSE 1022144953 cookiecliente si
|
|
|
c260e0 |
www.loser.com FALSE / FALSE 1139150993 UID 99
|
|
|
c260e0 |
%HOSTIP FALSE / FALSE 1439150993 mooo indeed
|
|
|
c260e0 |
-#HttpOnly_%HOSTIP FALSE /w FALSE 1439150993 mooo2 indeed2
|
|
|
c260e0 |
-%HOSTIP FALSE /wa FALSE 0 empty
|
|
|
c260e0 |
+#HttpOnly_%HOSTIP FALSE /want FALSE 1439150993 mooo2 indeed2
|
|
|
c260e0 |
+%HOSTIP FALSE /want FALSE 0 empty
|
|
|
c260e0 |
%HOSTIP FALSE / FALSE 2054030187 ckyPersistent permanent
|
|
|
c260e0 |
%HOSTIP FALSE / FALSE 0 ckySession temporary
|
|
|
c260e0 |
%HOSTIP FALSE / FALSE 0 ASPSESSIONIDQGGQQSJJ GKNBDIFAAOFDPDAIEAKDIBKE
|
|
|
c260e0 |
diff --git a/tests/data/test8 b/tests/data/test8
|
|
|
c260e0 |
index c36408a..4d54541 100644
|
|
|
c260e0 |
--- a/tests/data/test8
|
|
|
c260e0 |
+++ b/tests/data/test8
|
|
|
c260e0 |
@@ -59,7 +59,7 @@ perl -e 'if ("%HOSTIP" !~ /\.0\.0\.1$/) {print "Test only works for HOSTIPs endi
|
|
|
c260e0 |
GET /we/want/8 HTTP/1.1
|
|
|
c260e0 |
Host: %HOSTIP:%HTTPPORT
|
|
|
c260e0 |
Accept: */*
|
|
|
c260e0 |
-Cookie: cookie=perhaps; cookie=yes; partmatch=present; foobar=name; blexp=yesyes
|
|
|
c260e0 |
+Cookie: cookie=perhaps; cookie=yes; foobar=name; blexp=yesyes
|
|
|
c260e0 |
|
|
|
c260e0 |
</protocol>
|
|
|
c260e0 |
</verify>
|
|
|
c260e0 |
--
|
|
|
c260e0 |
2.1.0
|
|
|
c260e0 |
|
|
|
c260e0 |
|
|
|
c260e0 |
From 847085920706380e75f8cb23f2a161cdcdfcb384 Mon Sep 17 00:00:00 2001
|
|
|
c260e0 |
From: YAMADA Yasuharu <yasuharu.yamada@access-company.com>
|
|
|
c260e0 |
Date: Wed, 12 Jun 2013 11:19:56 +0200
|
|
|
c260e0 |
Subject: [PATCH 3/7] cookies: follow-up fix for path checking
|
|
|
c260e0 |
|
|
|
c260e0 |
The initial fix to only compare full path names were done in commit
|
|
|
c260e0 |
04f52e9b4db0 but found out to be incomplete. This takes should make the
|
|
|
c260e0 |
change more complete and there's now two additional tests to verify
|
|
|
c260e0 |
(test 31 and 62).
|
|
|
c260e0 |
Upstream-commit: f24dc09d209a2f91ca38d854f0c15ad93f3d7e2d
|
|
|
c260e0 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
c260e0 |
---
|
|
|
c260e0 |
lib/cookie.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++--------
|
|
|
c260e0 |
lib/cookie.h | 3 +-
|
|
|
c260e0 |
tests/data/test31 | 3 ++
|
|
|
c260e0 |
3 files changed, 128 insertions(+), 21 deletions(-)
|
|
|
c260e0 |
|
|
|
c260e0 |
diff --git a/lib/cookie.c b/lib/cookie.c
|
|
|
c260e0 |
index a4480c0..1d226cf 100644
|
|
|
c260e0 |
--- a/lib/cookie.c
|
|
|
c260e0 |
+++ b/lib/cookie.c
|
|
|
c260e0 |
@@ -106,6 +106,8 @@ static void freecookie(struct Cookie *co)
|
|
|
c260e0 |
free(co->domain);
|
|
|
c260e0 |
if(co->path)
|
|
|
c260e0 |
free(co->path);
|
|
|
c260e0 |
+ if(co->spath)
|
|
|
c260e0 |
+ free(co->spath);
|
|
|
c260e0 |
if(co->name)
|
|
|
c260e0 |
free(co->name);
|
|
|
c260e0 |
if(co->value)
|
|
|
c260e0 |
@@ -143,32 +145,114 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
|
|
|
c260e0 |
return FALSE;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
|
|
|
c260e0 |
-static bool pathmatch(const char* cookie_path, const char* url_path)
|
|
|
c260e0 |
+/*
|
|
|
c260e0 |
+ * matching cookie path and url path
|
|
|
c260e0 |
+ * RFC6265 5.1.4 Paths and Path-Match
|
|
|
c260e0 |
+ */
|
|
|
c260e0 |
+static bool pathmatch(const char* cookie_path, const char* request_uri)
|
|
|
c260e0 |
{
|
|
|
c260e0 |
- size_t cookie_path_len = strlen(cookie_path);
|
|
|
c260e0 |
- size_t url_path_len = strlen(url_path);
|
|
|
c260e0 |
+ size_t cookie_path_len;
|
|
|
c260e0 |
+ size_t uri_path_len;
|
|
|
c260e0 |
+ char* uri_path = NULL;
|
|
|
c260e0 |
+ char* pos;
|
|
|
c260e0 |
+ bool ret = FALSE;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* cookie_path must not have last '/' separator. ex: /sample */
|
|
|
c260e0 |
+ cookie_path_len = strlen(cookie_path);
|
|
|
c260e0 |
+ if(1 == cookie_path_len) {
|
|
|
c260e0 |
+ /* cookie_path must be '/' */
|
|
|
c260e0 |
+ return TRUE;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
|
|
|
c260e0 |
- if(url_path_len < cookie_path_len)
|
|
|
c260e0 |
+ uri_path = strdup(request_uri);
|
|
|
c260e0 |
+ if(!uri_path)
|
|
|
c260e0 |
return FALSE;
|
|
|
c260e0 |
+ pos = strchr(uri_path, '?');
|
|
|
c260e0 |
+ if(pos)
|
|
|
c260e0 |
+ *pos = 0x0;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* #-fragments are already cut off! */
|
|
|
c260e0 |
+ if(0 == strlen(uri_path) || uri_path[0] != '/') {
|
|
|
c260e0 |
+ free(uri_path);
|
|
|
c260e0 |
+ uri_path = strdup("/");
|
|
|
c260e0 |
+ if(!uri_path)
|
|
|
c260e0 |
+ return FALSE;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* here, RFC6265 5.1.4 says
|
|
|
c260e0 |
+ 4. Output the characters of the uri-path from the first character up
|
|
|
c260e0 |
+ to, but not including, the right-most %x2F ("/").
|
|
|
c260e0 |
+ but URL path /hoge?fuga=xxx means /hoge/index.cgi?fuga=xxx in some site
|
|
|
c260e0 |
+ without redirect.
|
|
|
c260e0 |
+ Ignore this algorithm because /hoge is uri path for this case
|
|
|
c260e0 |
+ (uri path is not /).
|
|
|
c260e0 |
+ */
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ uri_path_len = strlen(uri_path);
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ if(uri_path_len < cookie_path_len) {
|
|
|
c260e0 |
+ ret = FALSE;
|
|
|
c260e0 |
+ goto pathmatched;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
|
|
|
c260e0 |
/* not using checkprefix() because matching should be case-sensitive */
|
|
|
c260e0 |
- if(strncmp(cookie_path, url_path, cookie_path_len))
|
|
|
c260e0 |
- return FALSE;
|
|
|
c260e0 |
+ if(strncmp(cookie_path, uri_path, cookie_path_len)) {
|
|
|
c260e0 |
+ ret = FALSE;
|
|
|
c260e0 |
+ goto pathmatched;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
|
|
|
c260e0 |
- /* it is true if cookie_path and url_path are the same */
|
|
|
c260e0 |
- if(cookie_path_len == url_path_len)
|
|
|
c260e0 |
- return TRUE;
|
|
|
c260e0 |
+ /* The cookie-path and the uri-path are identical. */
|
|
|
c260e0 |
+ if(cookie_path_len == uri_path_len) {
|
|
|
c260e0 |
+ ret = TRUE;
|
|
|
c260e0 |
+ goto pathmatched;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
|
|
|
c260e0 |
/* here, cookie_path_len < url_path_len */
|
|
|
c260e0 |
+ if(uri_path[cookie_path_len] == '/') {
|
|
|
c260e0 |
+ ret = TRUE;
|
|
|
c260e0 |
+ goto pathmatched;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
|
|
|
c260e0 |
- /* it is false if cookie path is /example and url path is /examples */
|
|
|
c260e0 |
- if(cookie_path[cookie_path_len - 1] != '/') {
|
|
|
c260e0 |
- if(url_path[cookie_path_len] != '/') {
|
|
|
c260e0 |
- return FALSE;
|
|
|
c260e0 |
- }
|
|
|
c260e0 |
+ ret = FALSE;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+pathmatched:
|
|
|
c260e0 |
+ free(uri_path);
|
|
|
c260e0 |
+ return ret;
|
|
|
c260e0 |
+}
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+/*
|
|
|
c260e0 |
+ * cookie path sanitize
|
|
|
c260e0 |
+ */
|
|
|
c260e0 |
+static char *sanitize_cookie_path(const char *cookie_path)
|
|
|
c260e0 |
+{
|
|
|
c260e0 |
+ size_t len;
|
|
|
c260e0 |
+ char *new_path = strdup(cookie_path);
|
|
|
c260e0 |
+ if(!new_path)
|
|
|
c260e0 |
+ return NULL;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* some stupid site sends path attribute with '"'. */
|
|
|
c260e0 |
+ if(new_path[0] == '\"') {
|
|
|
c260e0 |
+ memmove((void *)new_path, (const void *)(new_path + 1), strlen(new_path));
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+ if(new_path[strlen(new_path) - 1] == '\"') {
|
|
|
c260e0 |
+ new_path[strlen(new_path) - 1] = 0x0;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* RFC6265 5.2.4 The Path Attribute */
|
|
|
c260e0 |
+ if(new_path[0] != '/') {
|
|
|
c260e0 |
+ /* Let cookie-path be the default-path. */
|
|
|
c260e0 |
+ free(new_path);
|
|
|
c260e0 |
+ new_path = strdup("/");
|
|
|
c260e0 |
+ return new_path;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* convert /hoge/ to /hoge */
|
|
|
c260e0 |
+ len = strlen(new_path);
|
|
|
c260e0 |
+ if(1 < len && new_path[len - 1] == '/') {
|
|
|
c260e0 |
+ new_path[len - 1] = 0x0;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
- /* matching! */
|
|
|
c260e0 |
- return TRUE;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ return new_path;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
|
|
|
c260e0 |
/*
|
|
|
c260e0 |
@@ -316,6 +400,11 @@ Curl_cookie_add(struct SessionHandle *data,
|
|
|
c260e0 |
badcookie = TRUE; /* out of memory bad */
|
|
|
c260e0 |
break;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
+ co->spath = sanitize_cookie_path(co->path);
|
|
|
c260e0 |
+ if(!co->spath) {
|
|
|
c260e0 |
+ badcookie = TRUE; /* out of memory bad */
|
|
|
c260e0 |
+ break;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
}
|
|
|
c260e0 |
else if(Curl_raw_equal("domain", name)) {
|
|
|
c260e0 |
/* note that this name may or may not have a preceding dot, but
|
|
|
c260e0 |
@@ -489,6 +578,9 @@ Curl_cookie_add(struct SessionHandle *data,
|
|
|
c260e0 |
if(co->path) {
|
|
|
c260e0 |
memcpy(co->path, path, pathlen);
|
|
|
c260e0 |
co->path[pathlen]=0; /* zero terminate */
|
|
|
c260e0 |
+ co->spath = sanitize_cookie_path(co->path);
|
|
|
c260e0 |
+ if(!co->spath)
|
|
|
c260e0 |
+ badcookie = TRUE; /* out of memory bad */
|
|
|
c260e0 |
}
|
|
|
c260e0 |
else
|
|
|
c260e0 |
badcookie = TRUE;
|
|
|
c260e0 |
@@ -580,12 +672,21 @@ Curl_cookie_add(struct SessionHandle *data,
|
|
|
c260e0 |
co->path = strdup(ptr);
|
|
|
c260e0 |
if(!co->path)
|
|
|
c260e0 |
badcookie = TRUE;
|
|
|
c260e0 |
+ else {
|
|
|
c260e0 |
+ co->spath = sanitize_cookie_path(co->path);
|
|
|
c260e0 |
+ if(!co->spath) {
|
|
|
c260e0 |
+ badcookie = TRUE; /* out of memory bad */
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
break;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
/* this doesn't look like a path, make one up! */
|
|
|
c260e0 |
co->path = strdup("/");
|
|
|
c260e0 |
if(!co->path)
|
|
|
c260e0 |
badcookie = TRUE;
|
|
|
c260e0 |
+ co->spath = strdup("/");
|
|
|
c260e0 |
+ if(!co->spath)
|
|
|
c260e0 |
+ badcookie = TRUE;
|
|
|
c260e0 |
fields++; /* add a field and fall down to secure */
|
|
|
c260e0 |
/* FALLTHROUGH */
|
|
|
c260e0 |
case 3:
|
|
|
c260e0 |
@@ -656,14 +757,14 @@ Curl_cookie_add(struct SessionHandle *data,
|
|
|
c260e0 |
if(replace_old) {
|
|
|
c260e0 |
/* the domains were identical */
|
|
|
c260e0 |
|
|
|
c260e0 |
- if(clist->path && co->path) {
|
|
|
c260e0 |
- if(Curl_raw_equal(clist->path, co->path)) {
|
|
|
c260e0 |
+ if(clist->spath && co->spath) {
|
|
|
c260e0 |
+ if(Curl_raw_equal(clist->spath, co->spath)) {
|
|
|
c260e0 |
replace_old = TRUE;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
else
|
|
|
c260e0 |
replace_old = FALSE;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
- else if(!clist->path && !co->path)
|
|
|
c260e0 |
+ else if(!clist->spath && !co->spath)
|
|
|
c260e0 |
replace_old = TRUE;
|
|
|
c260e0 |
else
|
|
|
c260e0 |
replace_old = FALSE;
|
|
|
c260e0 |
@@ -692,6 +793,8 @@ Curl_cookie_add(struct SessionHandle *data,
|
|
|
c260e0 |
free(clist->domain);
|
|
|
c260e0 |
if(clist->path)
|
|
|
c260e0 |
free(clist->path);
|
|
|
c260e0 |
+ if(clist->spath)
|
|
|
c260e0 |
+ free(clist->spath);
|
|
|
c260e0 |
if(clist->expirestr)
|
|
|
c260e0 |
free(clist->expirestr);
|
|
|
c260e0 |
|
|
|
c260e0 |
@@ -869,7 +972,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
|
|
c260e0 |
|
|
|
c260e0 |
/* now check the left part of the path with the cookies path
|
|
|
c260e0 |
requirement */
|
|
|
c260e0 |
- if(!co->path || pathmatch(co->path, path) ) {
|
|
|
c260e0 |
+ if(!co->spath || pathmatch(co->spath, path) ) {
|
|
|
c260e0 |
|
|
|
c260e0 |
/* and now, we know this is a match and we should create an
|
|
|
c260e0 |
entry for the return-linked-list */
|
|
|
c260e0 |
diff --git a/lib/cookie.h b/lib/cookie.h
|
|
|
c260e0 |
index d3b63f7..bd89082 100644
|
|
|
c260e0 |
--- a/lib/cookie.h
|
|
|
c260e0 |
+++ b/lib/cookie.h
|
|
|
c260e0 |
@@ -29,7 +29,8 @@ struct Cookie {
|
|
|
c260e0 |
struct Cookie *next; /* next in the chain */
|
|
|
c260e0 |
char *name; /* <this> = value */
|
|
|
c260e0 |
char *value; /* name = <this> */
|
|
|
c260e0 |
- char *path; /* path = <this> */
|
|
|
c260e0 |
+ char *path; /* path = <this> which is in Set-Cookie: */
|
|
|
c260e0 |
+ char *spath; /* sanitized cookie path */
|
|
|
c260e0 |
char *domain; /* domain = <this> */
|
|
|
c260e0 |
curl_off_t expires; /* expires = <this> */
|
|
|
c260e0 |
char *expirestr; /* the plain text version */
|
|
|
c260e0 |
diff --git a/tests/data/test31 b/tests/data/test31
|
|
|
c260e0 |
index b1171d8..38af83b 100644
|
|
|
c260e0 |
--- a/tests/data/test31
|
|
|
c260e0 |
+++ b/tests/data/test31
|
|
|
c260e0 |
@@ -18,6 +18,8 @@ Content-Type: text/html
|
|
|
c260e0 |
Funny-head: yesyes
|
|
|
c260e0 |
Set-Cookie: foobar=name; domain=anything.com; path=/ ; secure
|
|
|
c260e0 |
Set-Cookie:ismatch=this ; domain=127.0.0.1; path=/silly/
|
|
|
c260e0 |
+Set-Cookie: overwrite=this ; domain=127.0.0.1; path=/overwrite/
|
|
|
c260e0 |
+Set-Cookie: overwrite=this2 ; domain=127.0.0.1; path=/overwrite
|
|
|
c260e0 |
Set-Cookie: sec1value=secure1 ; domain=127.0.0.1; path=/secure1/ ; secure
|
|
|
c260e0 |
Set-Cookie: sec2value=secure2 ; domain=127.0.0.1; path=/secure2/ ; secure=
|
|
|
c260e0 |
Set-Cookie: sec3value=secure3 ; domain=127.0.0.1; path=/secure3/ ; secure=
|
|
|
c260e0 |
@@ -94,6 +96,7 @@ Accept: */*
|
|
|
c260e0 |
# This file was generated by libcurl! Edit at your own risk.
|
|
|
c260e0 |
|
|
|
c260e0 |
.127.0.0.1 TRUE /silly/ FALSE 0 ismatch this
|
|
|
c260e0 |
+.127.0.0.1 TRUE /overwrite FALSE 0 overwrite this2
|
|
|
c260e0 |
.127.0.0.1 TRUE /secure1/ TRUE 0 sec1value secure1
|
|
|
c260e0 |
.127.0.0.1 TRUE /secure2/ TRUE 0 sec2value secure2
|
|
|
c260e0 |
.127.0.0.1 TRUE /secure3/ TRUE 0 sec3value secure3
|
|
|
c260e0 |
--
|
|
|
c260e0 |
2.1.0
|
|
|
c260e0 |
|
|
|
c260e0 |
|
|
|
c260e0 |
From ffe02d8f3950b5fcf0470890a112125327606f35 Mon Sep 17 00:00:00 2001
|
|
|
c260e0 |
From: YAMADA Yasuharu <yasuharu.yamada@access-company.com>
|
|
|
c260e0 |
Date: Tue, 17 Sep 2013 15:51:22 +0900
|
|
|
c260e0 |
Subject: [PATCH 4/7] cookies: add expiration
|
|
|
c260e0 |
|
|
|
c260e0 |
Implement: Expired Cookies These following situation, curl removes
|
|
|
c260e0 |
cookie(s) from struct CookieInfo if the cookie expired.
|
|
|
c260e0 |
- Curl_cookie_add()
|
|
|
c260e0 |
- Curl_cookie_getlist()
|
|
|
c260e0 |
- cookie_output()
|
|
|
c260e0 |
|
|
|
c260e0 |
Upstream-commit: 4cfbb201c4f823ba31ba4b895044088fba6ae535
|
|
|
c260e0 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
c260e0 |
---
|
|
|
c260e0 |
lib/cookie.c | 37 ++++++++++++++++++++++++++
|
|
|
c260e0 |
tests/data/Makefile.am | 2 +-
|
|
|
c260e0 |
tests/data/Makefile.in | 2 +-
|
|
|
c260e0 |
tests/data/test1415 | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
c260e0 |
4 files changed, 111 insertions(+), 2 deletions(-)
|
|
|
c260e0 |
create mode 100644 tests/data/test1415
|
|
|
c260e0 |
|
|
|
c260e0 |
diff --git a/lib/cookie.c b/lib/cookie.c
|
|
|
c260e0 |
index 1d226cf..0ca0829 100644
|
|
|
c260e0 |
--- a/lib/cookie.c
|
|
|
c260e0 |
+++ b/lib/cookie.c
|
|
|
c260e0 |
@@ -289,6 +289,34 @@ static void strstore(char **str, const char *newstr)
|
|
|
c260e0 |
*str = strdup(newstr);
|
|
|
c260e0 |
}
|
|
|
c260e0 |
|
|
|
c260e0 |
+/*
|
|
|
c260e0 |
+ * remove_expired() removes expired cookies.
|
|
|
c260e0 |
+ */
|
|
|
c260e0 |
+static void remove_expired(struct CookieInfo *cookies)
|
|
|
c260e0 |
+{
|
|
|
c260e0 |
+ struct Cookie *co, *nx, *pv;
|
|
|
c260e0 |
+ curl_off_t now = (curl_off_t)time(NULL);
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ co = cookies->cookies;
|
|
|
c260e0 |
+ pv = NULL;
|
|
|
c260e0 |
+ while(co) {
|
|
|
c260e0 |
+ nx = co->next;
|
|
|
c260e0 |
+ if((co->expirestr || co->maxage) && co->expires < now) {
|
|
|
c260e0 |
+ if(co == cookies->cookies) {
|
|
|
c260e0 |
+ cookies->cookies = co->next;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+ else {
|
|
|
c260e0 |
+ pv->next = co->next;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+ cookies->numcookies--;
|
|
|
c260e0 |
+ freecookie(co);
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+ else {
|
|
|
c260e0 |
+ pv = co;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+ co = nx;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+}
|
|
|
c260e0 |
|
|
|
c260e0 |
/****************************************************************************
|
|
|
c260e0 |
*
|
|
|
c260e0 |
@@ -740,6 +768,9 @@ Curl_cookie_add(struct SessionHandle *data,
|
|
|
c260e0 |
superceeds an already existing cookie, which it may if the previous have
|
|
|
c260e0 |
the same domain and path as this */
|
|
|
c260e0 |
|
|
|
c260e0 |
+ /* at first, remove expired cookies */
|
|
|
c260e0 |
+ remove_expired(c);
|
|
|
c260e0 |
+
|
|
|
c260e0 |
clist = c->cookies;
|
|
|
c260e0 |
replace_old = FALSE;
|
|
|
c260e0 |
while(clist) {
|
|
|
c260e0 |
@@ -954,6 +985,9 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
|
|
c260e0 |
if(!c || !c->cookies)
|
|
|
c260e0 |
return NULL; /* no cookie struct or no cookies in the struct */
|
|
|
c260e0 |
|
|
|
c260e0 |
+ /* at first, remove expired cookies */
|
|
|
c260e0 |
+ remove_expired(c);
|
|
|
c260e0 |
+
|
|
|
c260e0 |
co = c->cookies;
|
|
|
c260e0 |
|
|
|
c260e0 |
while(co) {
|
|
|
c260e0 |
@@ -1196,6 +1230,9 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
|
|
|
c260e0 |
destination file */
|
|
|
c260e0 |
return 0;
|
|
|
c260e0 |
|
|
|
c260e0 |
+ /* at first, remove expired cookies */
|
|
|
c260e0 |
+ remove_expired(c);
|
|
|
c260e0 |
+
|
|
|
c260e0 |
if(strequal("-", dumphere)) {
|
|
|
c260e0 |
/* use stdout */
|
|
|
c260e0 |
out = stdout;
|
|
|
c260e0 |
diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am
|
|
|
c260e0 |
index 64662c6..f34268c 100644
|
|
|
c260e0 |
--- a/tests/data/Makefile.am
|
|
|
c260e0 |
+++ b/tests/data/Makefile.am
|
|
|
c260e0 |
@@ -92,7 +92,7 @@ test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 \
|
|
|
c260e0 |
test1379 test1380 test1381 test1382 test1383 test1384 test1385 test1386 \
|
|
|
c260e0 |
test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
|
|
|
c260e0 |
test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
|
|
|
c260e0 |
-test1408 test1409 test1410 test1411 test1412 test1413 \
|
|
|
c260e0 |
+test1408 test1409 test1410 test1411 test1412 test1413 test1415 \
|
|
|
c260e0 |
test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
|
|
|
c260e0 |
test1508 \
|
|
|
c260e0 |
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
|
|
|
c260e0 |
diff --git a/tests/data/Makefile.in b/tests/data/Makefile.in
|
|
|
c260e0 |
index 791fa1e..cd2c322 100644
|
|
|
c260e0 |
--- a/tests/data/Makefile.in
|
|
|
c260e0 |
+++ b/tests/data/Makefile.in
|
|
|
c260e0 |
@@ -356,7 +356,7 @@ test1371 test1372 test1373 test1374 test1375 test1376 test1377 test1378 \
|
|
|
c260e0 |
test1379 test1380 test1381 test1382 test1383 test1384 test1385 test1386 \
|
|
|
c260e0 |
test1387 test1388 test1389 test1390 test1391 test1392 test1393 \
|
|
|
c260e0 |
test1400 test1401 test1402 test1403 test1404 test1405 test1406 test1407 \
|
|
|
c260e0 |
-test1408 test1409 test1410 test1411 test1412 test1413 \
|
|
|
c260e0 |
+test1408 test1409 test1410 test1411 test1412 test1413 test1415 \
|
|
|
c260e0 |
test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \
|
|
|
c260e0 |
test1508 \
|
|
|
c260e0 |
test2000 test2001 test2002 test2003 test2004 test2005 test2006 test2007 \
|
|
|
c260e0 |
diff --git a/tests/data/test1415 b/tests/data/test1415
|
|
|
c260e0 |
new file mode 100644
|
|
|
c260e0 |
index 0000000..cc6bd70
|
|
|
c260e0 |
--- /dev/null
|
|
|
c260e0 |
+++ b/tests/data/test1415
|
|
|
c260e0 |
@@ -0,0 +1,72 @@
|
|
|
c260e0 |
+<testcase>
|
|
|
c260e0 |
+<info>
|
|
|
c260e0 |
+<keywords>
|
|
|
c260e0 |
+HTTP
|
|
|
c260e0 |
+HTTP GET
|
|
|
c260e0 |
+cookies
|
|
|
c260e0 |
+cookiejar
|
|
|
c260e0 |
+delete expired cookie
|
|
|
c260e0 |
+</keywords>
|
|
|
c260e0 |
+</info>
|
|
|
c260e0 |
+# Server-side
|
|
|
c260e0 |
+<reply>
|
|
|
c260e0 |
+<data>
|
|
|
c260e0 |
+HTTP/1.1 200 OK
|
|
|
c260e0 |
+Date: Thu, 09 Nov 2010 14:49:00 GMT
|
|
|
c260e0 |
+Server: test-server/fake
|
|
|
c260e0 |
+Content-Length: 4
|
|
|
c260e0 |
+Content-Type: text/html
|
|
|
c260e0 |
+Funny-head: yesyes
|
|
|
c260e0 |
+Set-Cookie: test1value=test1; domain=example.com; path=/;
|
|
|
c260e0 |
+Set-Cookie: test2value=test2; expires=Friday, 01-Jan-2038 00:00:00 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
+Set-Cookie: test3value=test3; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
+Set-Cookie: test4value=test4; expires=Friday, 01-Jan-2038 00:00:00 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
+Set-Cookie: test5value=test5; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
+Set-Cookie: test6value=test6; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
+Set-Cookie: test7value=test7; expires=Friday, 01-Jan-2038 00:00:00 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
+Set-Cookie: test8value=test8; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+boo
|
|
|
c260e0 |
+</data>
|
|
|
c260e0 |
+</reply>
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+# Client-side
|
|
|
c260e0 |
+<client>
|
|
|
c260e0 |
+<server>
|
|
|
c260e0 |
+http
|
|
|
c260e0 |
+</server>
|
|
|
c260e0 |
+<name>
|
|
|
c260e0 |
+Delete expired cookies
|
|
|
c260e0 |
+</name>
|
|
|
c260e0 |
+<setenv>
|
|
|
c260e0 |
+TZ=GMT
|
|
|
c260e0 |
+</setenv>
|
|
|
c260e0 |
+<command>
|
|
|
c260e0 |
+http://example.com/we/want/1415 -b none -c log/jar1415.txt -x %HOSTIP:%HTTPPORT
|
|
|
c260e0 |
+</command>
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+# Verify data after the test has been "shot"
|
|
|
c260e0 |
+<verify>
|
|
|
c260e0 |
+<strip>
|
|
|
c260e0 |
+^User-Agent:.*
|
|
|
c260e0 |
+</strip>
|
|
|
c260e0 |
+<protocol>
|
|
|
c260e0 |
+GET http://example.com/we/want/1415 HTTP/1.1
|
|
|
c260e0 |
+Host: example.com
|
|
|
c260e0 |
+Accept: */*
|
|
|
c260e0 |
+Proxy-Connection: Keep-Alive
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+</protocol>
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+<file name="log/jar1415.txt" mode="text">
|
|
|
c260e0 |
+# Netscape HTTP Cookie File
|
|
|
c260e0 |
+# http://curl.haxx.se/docs/http-cookies.html
|
|
|
c260e0 |
+# This file was generated by libcurl! Edit at your own risk.
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+.example.com TRUE / FALSE 0 test1value test1
|
|
|
c260e0 |
+.example.com TRUE / FALSE 2145916800 test2value test2
|
|
|
c260e0 |
+.example.com TRUE / FALSE 2145916800 test4value test4
|
|
|
c260e0 |
+.example.com TRUE / FALSE 2145916800 test7value test7
|
|
|
c260e0 |
+</file>
|
|
|
c260e0 |
+</verify>
|
|
|
c260e0 |
+</testcase>
|
|
|
c260e0 |
--
|
|
|
c260e0 |
2.1.0
|
|
|
c260e0 |
|
|
|
c260e0 |
|
|
|
c260e0 |
From f866a6369316df97b777289a34db03444f7dedbe Mon Sep 17 00:00:00 2001
|
|
|
c260e0 |
From: Daniel Stenberg <daniel@haxx.se>
|
|
|
c260e0 |
Date: Sat, 21 Sep 2013 13:43:39 -0500
|
|
|
c260e0 |
Subject: [PATCH 5/7] test1415: adjusted to work for 32bit time_t
|
|
|
c260e0 |
|
|
|
c260e0 |
The libcurl date parser returns INT_MAX for all dates > 2037 so this
|
|
|
c260e0 |
test is now made to use 2037 instead of 2038 to work the same for both
|
|
|
c260e0 |
32bit and 64bit time_t systems.
|
|
|
c260e0 |
|
|
|
c260e0 |
Upstream-commit: 34df869f99477edda61d639151b1edf75998abd9
|
|
|
c260e0 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
c260e0 |
---
|
|
|
c260e0 |
tests/data/test1415 | 12 ++++++------
|
|
|
c260e0 |
1 file changed, 6 insertions(+), 6 deletions(-)
|
|
|
c260e0 |
|
|
|
c260e0 |
diff --git a/tests/data/test1415 b/tests/data/test1415
|
|
|
c260e0 |
index cc6bd70..51eed3e 100644
|
|
|
c260e0 |
--- a/tests/data/test1415
|
|
|
c260e0 |
+++ b/tests/data/test1415
|
|
|
c260e0 |
@@ -18,12 +18,12 @@ Content-Length: 4
|
|
|
c260e0 |
Content-Type: text/html
|
|
|
c260e0 |
Funny-head: yesyes
|
|
|
c260e0 |
Set-Cookie: test1value=test1; domain=example.com; path=/;
|
|
|
c260e0 |
-Set-Cookie: test2value=test2; expires=Friday, 01-Jan-2038 00:00:00 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
+Set-Cookie: test2value=test2; expires=Friday, 01-Jan-2037 00:00:00 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
Set-Cookie: test3value=test3; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
-Set-Cookie: test4value=test4; expires=Friday, 01-Jan-2038 00:00:00 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
+Set-Cookie: test4value=test4; expires=Friday, 01-Jan-2037 00:00:00 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
Set-Cookie: test5value=test5; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
Set-Cookie: test6value=test6; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
-Set-Cookie: test7value=test7; expires=Friday, 01-Jan-2038 00:00:00 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
+Set-Cookie: test7value=test7; expires=Friday, 01-Jan-2037 00:00:00 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
Set-Cookie: test8value=test8; expires=Monday, 13-Jun-1988 03:04:55 GMT; domain=example.com; path=/;
|
|
|
c260e0 |
|
|
|
c260e0 |
boo
|
|
|
c260e0 |
@@ -64,9 +64,9 @@ Proxy-Connection: Keep-Alive
|
|
|
c260e0 |
# This file was generated by libcurl! Edit at your own risk.
|
|
|
c260e0 |
|
|
|
c260e0 |
.example.com TRUE / FALSE 0 test1value test1
|
|
|
c260e0 |
-.example.com TRUE / FALSE 2145916800 test2value test2
|
|
|
c260e0 |
-.example.com TRUE / FALSE 2145916800 test4value test4
|
|
|
c260e0 |
-.example.com TRUE / FALSE 2145916800 test7value test7
|
|
|
c260e0 |
+.example.com TRUE / FALSE 2114380800 test2value test2
|
|
|
c260e0 |
+.example.com TRUE / FALSE 2114380800 test4value test4
|
|
|
c260e0 |
+.example.com TRUE / FALSE 2114380800 test7value test7
|
|
|
c260e0 |
</file>
|
|
|
c260e0 |
</verify>
|
|
|
c260e0 |
</testcase>
|
|
|
c260e0 |
--
|
|
|
c260e0 |
2.1.0
|
|
|
c260e0 |
|
|
|
c260e0 |
|
|
|
c260e0 |
From 8471ac93e881f7f17fe598086b6b548289716279 Mon Sep 17 00:00:00 2001
|
|
|
c260e0 |
From: Daniel Stenberg <daniel@haxx.se>
|
|
|
c260e0 |
Date: Thu, 16 Jan 2014 08:51:30 +0100
|
|
|
c260e0 |
Subject: [PATCH 6/7] cookie: max-age fixes
|
|
|
c260e0 |
|
|
|
c260e0 |
1 - allow >31 bit max-age values
|
|
|
c260e0 |
|
|
|
c260e0 |
2 - don't overflow on extremely large max-age values when we add the
|
|
|
c260e0 |
value to the current time
|
|
|
c260e0 |
|
|
|
c260e0 |
3 - make sure max-age takes precedence over expires as dictated by
|
|
|
c260e0 |
RFC6265
|
|
|
c260e0 |
|
|
|
c260e0 |
Bug: http://curl.haxx.se/mail/lib-2014-01/0130.html
|
|
|
c260e0 |
Reported-by: Chen Prog
|
|
|
c260e0 |
Upstream-commit: ecaf2f02f1df70f0bbcbbbf48914bfc83c8f2a56
|
|
|
c260e0 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
c260e0 |
---
|
|
|
c260e0 |
lib/cookie.c | 38 ++++++++++++++++++++++++--------------
|
|
|
c260e0 |
1 file changed, 24 insertions(+), 14 deletions(-)
|
|
|
c260e0 |
|
|
|
c260e0 |
diff --git a/lib/cookie.c b/lib/cookie.c
|
|
|
c260e0 |
index 0ca0829..d4fe9a3 100644
|
|
|
c260e0 |
--- a/lib/cookie.c
|
|
|
c260e0 |
+++ b/lib/cookie.c
|
|
|
c260e0 |
@@ -523,9 +523,6 @@ Curl_cookie_add(struct SessionHandle *data,
|
|
|
c260e0 |
badcookie = TRUE;
|
|
|
c260e0 |
break;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
- co->expires =
|
|
|
c260e0 |
- strtol((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0],NULL,10)
|
|
|
c260e0 |
- + (long)now;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
else if(Curl_raw_equal("expires", name)) {
|
|
|
c260e0 |
strstore(&co->expirestr, whatptr);
|
|
|
c260e0 |
@@ -533,17 +530,6 @@ Curl_cookie_add(struct SessionHandle *data,
|
|
|
c260e0 |
badcookie = TRUE;
|
|
|
c260e0 |
break;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
- /* Note that if the date couldn't get parsed for whatever reason,
|
|
|
c260e0 |
- the cookie will be treated as a session cookie */
|
|
|
c260e0 |
- co->expires = curl_getdate(what, &now;;
|
|
|
c260e0 |
-
|
|
|
c260e0 |
- /* Session cookies have expires set to 0 so if we get that back
|
|
|
c260e0 |
- from the date parser let's add a second to make it a
|
|
|
c260e0 |
- non-session cookie */
|
|
|
c260e0 |
- if(co->expires == 0)
|
|
|
c260e0 |
- co->expires = 1;
|
|
|
c260e0 |
- else if(co->expires < 0)
|
|
|
c260e0 |
- co->expires = 0;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
else if(!co->name) {
|
|
|
c260e0 |
co->name = strdup(name);
|
|
|
c260e0 |
@@ -578,6 +564,30 @@ Curl_cookie_add(struct SessionHandle *data,
|
|
|
c260e0 |
semiptr=strchr(ptr, '\0');
|
|
|
c260e0 |
} while(semiptr);
|
|
|
c260e0 |
|
|
|
c260e0 |
+ if(co->maxage) {
|
|
|
c260e0 |
+ co->expires =
|
|
|
c260e0 |
+ curlx_strtoofft((*co->maxage=='\"')?
|
|
|
c260e0 |
+ &co->maxage[1]:&co->maxage[0], NULL, 10);
|
|
|
c260e0 |
+ if(CURL_OFF_T_MAX - now < co->expires)
|
|
|
c260e0 |
+ /* avoid overflow */
|
|
|
c260e0 |
+ co->expires = CURL_OFF_T_MAX;
|
|
|
c260e0 |
+ else
|
|
|
c260e0 |
+ co->expires += now;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+ else if(co->expirestr) {
|
|
|
c260e0 |
+ /* Note that if the date couldn't get parsed for whatever reason,
|
|
|
c260e0 |
+ the cookie will be treated as a session cookie */
|
|
|
c260e0 |
+ co->expires = curl_getdate(co->expirestr, NULL);
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ /* Session cookies have expires set to 0 so if we get that back
|
|
|
c260e0 |
+ from the date parser let's add a second to make it a
|
|
|
c260e0 |
+ non-session cookie */
|
|
|
c260e0 |
+ if(co->expires == 0)
|
|
|
c260e0 |
+ co->expires = 1;
|
|
|
c260e0 |
+ else if(co->expires < 0)
|
|
|
c260e0 |
+ co->expires = 0;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+
|
|
|
c260e0 |
if(!badcookie && !co->domain) {
|
|
|
c260e0 |
if(domain) {
|
|
|
c260e0 |
/* no domain was given in the header line, set the default */
|
|
|
c260e0 |
--
|
|
|
c260e0 |
2.1.0
|
|
|
c260e0 |
|
|
|
c260e0 |
|
|
|
c260e0 |
From ee52a81c23b918895b363b904ebb5fc9908b55cc Mon Sep 17 00:00:00 2001
|
|
|
c260e0 |
From: Tim Ruehsen <tim.ruehsen@gmx.de>
|
|
|
c260e0 |
Date: Tue, 19 Aug 2014 21:01:28 +0200
|
|
|
c260e0 |
Subject: [PATCH 7/7] cookies: only use full host matches for hosts used as IP
|
|
|
c260e0 |
address
|
|
|
c260e0 |
|
|
|
c260e0 |
By not detecting and rejecting domain names for partial literal IP
|
|
|
c260e0 |
addresses properly when parsing received HTTP cookies, libcurl can be
|
|
|
c260e0 |
fooled to both send cookies to wrong sites and to allow arbitrary sites
|
|
|
c260e0 |
to set cookies for others.
|
|
|
c260e0 |
|
|
|
c260e0 |
CVE-2014-3613
|
|
|
c260e0 |
|
|
|
c260e0 |
Bug: http://curl.haxx.se/docs/adv_20140910A.html
|
|
|
c260e0 |
Upstream-commit: 8a75dbeb2305297640453029b7905ef51b87e8dd
|
|
|
c260e0 |
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
|
|
|
c260e0 |
---
|
|
|
c260e0 |
lib/cookie.c | 50 ++++++++++++++++++++++++++++++++++++++----------
|
|
|
c260e0 |
tests/data/test1105 | 3 +--
|
|
|
c260e0 |
tests/data/test31 | 55 +++++++++++++++++++++++++++--------------------------
|
|
|
c260e0 |
tests/data/test8 | 3 ++-
|
|
|
c260e0 |
4 files changed, 71 insertions(+), 40 deletions(-)
|
|
|
c260e0 |
|
|
|
c260e0 |
diff --git a/lib/cookie.c b/lib/cookie.c
|
|
|
c260e0 |
index d4fe9a3..956efd4 100644
|
|
|
c260e0 |
--- a/lib/cookie.c
|
|
|
c260e0 |
+++ b/lib/cookie.c
|
|
|
c260e0 |
@@ -94,6 +94,7 @@ Example set of cookies:
|
|
|
c260e0 |
#include "strtoofft.h"
|
|
|
c260e0 |
#include "rawstr.h"
|
|
|
c260e0 |
#include "curl_memrchr.h"
|
|
|
c260e0 |
+#include "inet_pton.h"
|
|
|
c260e0 |
|
|
|
c260e0 |
/* The last #include file should be: */
|
|
|
c260e0 |
#include "memdebug.h"
|
|
|
c260e0 |
@@ -318,6 +319,28 @@ static void remove_expired(struct CookieInfo *cookies)
|
|
|
c260e0 |
}
|
|
|
c260e0 |
}
|
|
|
c260e0 |
|
|
|
c260e0 |
+/*
|
|
|
c260e0 |
+ * Return true if the given string is an IP(v4|v6) address.
|
|
|
c260e0 |
+ */
|
|
|
c260e0 |
+static bool isip(const char *domain)
|
|
|
c260e0 |
+{
|
|
|
c260e0 |
+ struct in_addr addr;
|
|
|
c260e0 |
+#ifdef ENABLE_IPV6
|
|
|
c260e0 |
+ struct in6_addr addr6;
|
|
|
c260e0 |
+#endif
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ if(Curl_inet_pton(AF_INET, domain, &addr)
|
|
|
c260e0 |
+#ifdef ENABLE_IPV6
|
|
|
c260e0 |
+ || Curl_inet_pton(AF_INET6, domain, &addr6)
|
|
|
c260e0 |
+#endif
|
|
|
c260e0 |
+ ) {
|
|
|
c260e0 |
+ /* domain name given as IP address */
|
|
|
c260e0 |
+ return TRUE;
|
|
|
c260e0 |
+ }
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ return FALSE;
|
|
|
c260e0 |
+}
|
|
|
c260e0 |
+
|
|
|
c260e0 |
/****************************************************************************
|
|
|
c260e0 |
*
|
|
|
c260e0 |
* Curl_cookie_add()
|
|
|
c260e0 |
@@ -472,24 +495,27 @@ Curl_cookie_add(struct SessionHandle *data,
|
|
|
c260e0 |
whatptr);
|
|
|
c260e0 |
}
|
|
|
c260e0 |
else {
|
|
|
c260e0 |
+ bool is_ip;
|
|
|
c260e0 |
+
|
|
|
c260e0 |
/* Now, we make sure that our host is within the given domain,
|
|
|
c260e0 |
or the given domain is not valid and thus cannot be set. */
|
|
|
c260e0 |
|
|
|
c260e0 |
if('.' == whatptr[0])
|
|
|
c260e0 |
whatptr++; /* ignore preceding dot */
|
|
|
c260e0 |
|
|
|
c260e0 |
- if(!domain || tailmatch(whatptr, domain)) {
|
|
|
c260e0 |
- const char *tailptr=whatptr;
|
|
|
c260e0 |
- if(tailptr[0] == '.')
|
|
|
c260e0 |
- tailptr++;
|
|
|
c260e0 |
- strstore(&co->domain, tailptr); /* don't prefix w/dots
|
|
|
c260e0 |
- internally */
|
|
|
c260e0 |
+ is_ip = isip(domain ? domain : whatptr);
|
|
|
c260e0 |
+
|
|
|
c260e0 |
+ if(!domain
|
|
|
c260e0 |
+ || (is_ip && !strcmp(whatptr, domain))
|
|
|
c260e0 |
+ || (!is_ip && tailmatch(whatptr, domain))) {
|
|
|
c260e0 |
+ strstore(&co->domain, whatptr);
|
|
|
c260e0 |
if(!co->domain) {
|
|
|
c260e0 |
badcookie = TRUE;
|
|
|
c260e0 |
break;
|
|
|
c260e0 |
}
|
|
|
c260e0 |
- co->tailmatch=TRUE; /* we always do that if the domain name was
|
|
|
c260e0 |
- given */
|
|
|
c260e0 |
+ if(!is_ip)
|
|
|
c260e0 |
+ co->tailmatch=TRUE; /* we always do that if the domain name was
|
|
|
c260e0 |
+ given */
|
|
|
c260e0 |
}
|
|
|
c260e0 |
else {
|
|
|
c260e0 |
/* we did not get a tailmatch and then the attempted set domain
|
|
|
c260e0 |
@@ -991,6 +1017,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
|
|
c260e0 |
time_t now = time(NULL);
|
|
|
c260e0 |
struct Cookie *mainco=NULL;
|
|
|
c260e0 |
size_t matches = 0;
|
|
|
c260e0 |
+ bool is_ip;
|
|
|
c260e0 |
|
|
|
c260e0 |
if(!c || !c->cookies)
|
|
|
c260e0 |
return NULL; /* no cookie struct or no cookies in the struct */
|
|
|
c260e0 |
@@ -998,6 +1025,9 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
|
|
c260e0 |
/* at first, remove expired cookies */
|
|
|
c260e0 |
remove_expired(c);
|
|
|
c260e0 |
|
|
|
c260e0 |
+ /* check if host is an IP(v4|v6) address */
|
|
|
c260e0 |
+ is_ip = isip(host);
|
|
|
c260e0 |
+
|
|
|
c260e0 |
co = c->cookies;
|
|
|
c260e0 |
|
|
|
c260e0 |
while(co) {
|
|
|
c260e0 |
@@ -1009,8 +1039,8 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
|
|
|
c260e0 |
|
|
|
c260e0 |
/* now check if the domain is correct */
|
|
|
c260e0 |
if(!co->domain ||
|
|
|
c260e0 |
- (co->tailmatch && tailmatch(co->domain, host)) ||
|
|
|
c260e0 |
- (!co->tailmatch && Curl_raw_equal(host, co->domain)) ) {
|
|
|
c260e0 |
+ (co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
|
|
|
c260e0 |
+ ((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
|
|
|
c260e0 |
/* the right part of the host matches the domain stuff in the
|
|
|
c260e0 |
cookie data */
|
|
|
c260e0 |
|
|
|
c260e0 |
diff --git a/tests/data/test1105 b/tests/data/test1105
|
|
|
c260e0 |
index 922346f..ea7b198 100644
|
|
|
c260e0 |
--- a/tests/data/test1105
|
|
|
c260e0 |
+++ b/tests/data/test1105
|
|
|
c260e0 |
@@ -59,8 +59,7 @@ userid=myname&password=mypassword
|
|
|
c260e0 |
# This file was generated by libcurl! Edit at your own risk.
|
|
|
c260e0 |
|
|
|
c260e0 |
127.0.0.1 FALSE /we/want/ FALSE 0 foobar name
|
|
|
c260e0 |
-.127.0.0.1 TRUE "/silly/" FALSE 0 mismatch this
|
|
|
c260e0 |
-.0.0.1 TRUE / FALSE 0 partmatch present
|
|
|
c260e0 |
+127.0.0.1 FALSE "/silly/" FALSE 0 mismatch this
|
|
|
c260e0 |
</file>
|
|
|
c260e0 |
</verify>
|
|
|
c260e0 |
</testcase>
|
|
|
c260e0 |
diff --git a/tests/data/test31 b/tests/data/test31
|
|
|
c260e0 |
index 38af83b..dfcac04 100644
|
|
|
c260e0 |
--- a/tests/data/test31
|
|
|
c260e0 |
+++ b/tests/data/test31
|
|
|
c260e0 |
@@ -51,7 +51,8 @@ Set-Cookie: novalue; domain=reallysilly
|
|
|
c260e0 |
Set-Cookie: test=yes; domain=foo.com; expires=Sat Feb 2 11:56:27 GMT 2030
|
|
|
c260e0 |
Set-Cookie: test2=yes; domain=se; expires=Sat Feb 2 11:56:27 GMT 2030
|
|
|
c260e0 |
Set-Cookie: magic=yessir; path=/silly/; HttpOnly
|
|
|
c260e0 |
-Set-Cookie: blexp=yesyes; domain=.0.0.1; domain=.0.0.1; expiry=totally bad;
|
|
|
c260e0 |
+Set-Cookie: blexp=yesyes; domain=127.0.0.1; domain=127.0.0.1; expiry=totally bad;
|
|
|
c260e0 |
+Set-Cookie: partialip=nono; domain=.0.0.1;
|
|
|
c260e0 |
|
|
|
c260e0 |
boo
|
|
|
c260e0 |
</data>
|
|
|
c260e0 |
@@ -95,34 +96,34 @@ Accept: */*
|
|
|
c260e0 |
# http://curl.haxx.se/docs/http-cookies.html
|
|
|
c260e0 |
# This file was generated by libcurl! Edit at your own risk.
|
|
|
c260e0 |
|
|
|
c260e0 |
-.127.0.0.1 TRUE /silly/ FALSE 0 ismatch this
|
|
|
c260e0 |
-.127.0.0.1 TRUE /overwrite FALSE 0 overwrite this2
|
|
|
c260e0 |
-.127.0.0.1 TRUE /secure1/ TRUE 0 sec1value secure1
|
|
|
c260e0 |
-.127.0.0.1 TRUE /secure2/ TRUE 0 sec2value secure2
|
|
|
c260e0 |
-.127.0.0.1 TRUE /secure3/ TRUE 0 sec3value secure3
|
|
|
c260e0 |
-.127.0.0.1 TRUE /secure4/ TRUE 0 sec4value secure4
|
|
|
c260e0 |
-.127.0.0.1 TRUE /secure5/ TRUE 0 sec5value secure5
|
|
|
c260e0 |
-.127.0.0.1 TRUE /secure6/ TRUE 0 sec6value secure6
|
|
|
c260e0 |
-.127.0.0.1 TRUE /secure7/ TRUE 0 sec7value secure7
|
|
|
c260e0 |
-.127.0.0.1 TRUE /secure8/ TRUE 0 sec8value secure8
|
|
|
c260e0 |
-.127.0.0.1 TRUE /secure9/ TRUE 0 secure very1
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p1/ FALSE 0 httpo1 value1
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p2/ FALSE 0 httpo2 value2
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p3/ FALSE 0 httpo3 value3
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p4/ FALSE 0 httpo4 value4
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p4/ FALSE 0 httponly myvalue1
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec myvalue2
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec2 myvalue3
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec3 myvalue4
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec4 myvalue5
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec5 myvalue6
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec6 myvalue7
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec7 myvalue8
|
|
|
c260e0 |
-#HttpOnly_.127.0.0.1 TRUE /p4/ TRUE 0 httpandsec8 myvalue9
|
|
|
c260e0 |
-.127.0.0.1 TRUE / FALSE 0 partmatch present
|
|
|
c260e0 |
+127.0.0.1 FALSE /silly/ FALSE 0 ismatch this
|
|
|
c260e0 |
+127.0.0.1 FALSE /overwrite FALSE 0 overwrite this2
|
|
|
c260e0 |
+127.0.0.1 FALSE /secure1/ TRUE 0 sec1value secure1
|
|
|
c260e0 |
+127.0.0.1 FALSE /secure2/ TRUE 0 sec2value secure2
|
|
|
c260e0 |
+127.0.0.1 FALSE /secure3/ TRUE 0 sec3value secure3
|
|
|
c260e0 |
+127.0.0.1 FALSE /secure4/ TRUE 0 sec4value secure4
|
|
|
c260e0 |
+127.0.0.1 FALSE /secure5/ TRUE 0 sec5value secure5
|
|
|
c260e0 |
+127.0.0.1 FALSE /secure6/ TRUE 0 sec6value secure6
|
|
|
c260e0 |
+127.0.0.1 FALSE /secure7/ TRUE 0 sec7value secure7
|
|
|
c260e0 |
+127.0.0.1 FALSE /secure8/ TRUE 0 sec8value secure8
|
|
|
c260e0 |
+127.0.0.1 FALSE /secure9/ TRUE 0 secure very1
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p1/ FALSE 0 httpo1 value1
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p2/ FALSE 0 httpo2 value2
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p3/ FALSE 0 httpo3 value3
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p4/ FALSE 0 httpo4 value4
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p4/ FALSE 0 httponly myvalue1
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec myvalue2
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec2 myvalue3
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec3 myvalue4
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec4 myvalue5
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec5 myvalue6
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec6 myvalue7
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec7 myvalue8
|
|
|
c260e0 |
+#HttpOnly_127.0.0.1 FALSE /p4/ TRUE 0 httpandsec8 myvalue9
|
|
|
c260e0 |
+127.0.0.1 FALSE / FALSE 0 partmatch present
|
|
|
c260e0 |
127.0.0.1 FALSE /we/want/ FALSE 2054030187 nodomain value
|
|
|
c260e0 |
#HttpOnly_127.0.0.1 FALSE /silly/ FALSE 0 magic yessir
|
|
|
c260e0 |
-.0.0.1 TRUE /we/want/ FALSE 0 blexp yesyes
|
|
|
c260e0 |
+127.0.0.1 FALSE /we/want/ FALSE 0 blexp yesyes
|
|
|
c260e0 |
</file>
|
|
|
c260e0 |
</verify>
|
|
|
c260e0 |
</testcase>
|
|
|
c260e0 |
diff --git a/tests/data/test8 b/tests/data/test8
|
|
|
c260e0 |
index 4d54541..030fd55 100644
|
|
|
c260e0 |
--- a/tests/data/test8
|
|
|
c260e0 |
+++ b/tests/data/test8
|
|
|
c260e0 |
@@ -42,7 +42,8 @@ Set-Cookie: duplicate=test; domain=.0.0.1; domain=.0.0.1; path=/donkey;
|
|
|
c260e0 |
Set-Cookie: cookie=yes; path=/we;
|
|
|
c260e0 |
Set-Cookie: cookie=perhaps; path=/we/want;
|
|
|
c260e0 |
Set-Cookie: nocookie=yes; path=/WE;
|
|
|
c260e0 |
-Set-Cookie: blexp=yesyes; domain=.0.0.1; domain=.0.0.1; expiry=totally bad;
|
|
|
c260e0 |
+Set-Cookie: blexp=yesyes; domain=%HOSTIP; domain=%HOSTIP; expiry=totally bad;
|
|
|
c260e0 |
+Set-Cookie: partialip=nono; domain=.0.0.1;
|
|
|
c260e0 |
|
|
|
c260e0 |
</file>
|
|
|
c260e0 |
<precheck>
|
|
|
c260e0 |
--
|
|
|
c260e0 |
2.1.0
|
|
|
c260e0 |
|