'delay' attribute is intended for specific test cases, and normally not
needed.
-### `<file name="%LOGDIR/filename" [nonewline="yes"][crlf="yes"]>`
+### `<file name="%LOGDIR/filename" [options]>`
This creates the named file with this content before the test case is run,
which is useful if the test case needs a file to act on.
`crlf=yes` forces the newlines to become CRLF even if not written so in the
test.
+`mode="text"` normalizes the line endings to make them compare as text on all
+platforms.
+
### `<file1>`
1 to 4 can be appended to 'file' to create more files.
out->len = len;
}
+/* remove bytes from the end of the string, never remove more bytes than what
+ the string holds! */
+void curlx_str_trim(struct Curl_str *out, size_t len)
+{
+ DEBUGASSERT(out);
+ DEBUGASSERT(out->len >= len);
+ out->len -= len;
+}
+
/* Get a word until the first DELIM or end of string. At least one byte long.
return non-zero on error */
int curlx_str_until(const char **linep, struct Curl_str *out,
void curlx_str_init(struct Curl_str *out);
void curlx_str_assign(struct Curl_str *out, const char *str, size_t len);
+void curlx_str_trim(struct Curl_str *out, size_t len);
#define curlx_str(x) ((x)->str)
#define curlx_strlen(x) ((x)->len)
char dbuf[MAX_HSTS_DATELEN + 1];
time_t expires = 0;
const char *hp = curlx_str(&host);
+ size_t hlen;
/* The date parser works on a null-terminated string. The maximum length
is upheld by curlx_str_quotedword(). */
if(hp[0] == '.') {
curlx_str_nudge(&host, 1);
+ hp = curlx_str(&host);
subdomain = TRUE;
}
+ hlen = curlx_strlen(&host);
+ if(hlen && (hp[hlen - 1] == '.'))
+ /* strip off any trailing dot */
+ curlx_str_trim(&host, 1);
+
/* only add it if not already present */
e = Curl_hsts(h, curlx_str(&host), curlx_strlen(&host), subdomain);
if(!e)
result = hsts_create(h, curlx_str(&host), curlx_strlen(&host),
subdomain, expires);
else if(curlx_str_casecompare(&host, e->host)) {
- /* the same hostname, use the largest expire time */
+ /* the same hostname, use the largest expire time and keep the
+ strictest subdomain policy */
if(expires > e->expires)
e->expires = expires;
+ if(subdomain)
+ e->includeSubDomains = TRUE;
}
if(result)
return result;
test1620 test1621 test1622 test1623 test1624 test1625 test1626 test1627 \
\
test1630 test1631 test1632 test1633 test1634 test1635 test1636 test1637 \
-\
+test1638 \
test1640 test1641 test1642 test1643 \
\
test1650 test1651 test1652 test1653 test1654 test1655 test1656 test1657 \
--- /dev/null
+<?xml version="1.0" encoding="US-ASCII"?>
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP proxy
+HSTS
+</keywords>
+</info>
+
+<reply>
+
+# we use this as response to a CONNECT
+<connect crlf="headers" nocheck="yes">
+HTTP/1.1 200 not OK at all
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Connection: close
+Funny-head: yesyes
+
+</connect>
+
+<data crlf="headers" nocheck="yes">
+HTTP/1.1 200 not OK at all
+Date: Tue, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 6
+Connection: close
+Funny-head: yesyes
+
+-foo-
+</data>
+</reply>
+
+<client>
+<server>
+http
+</server>
+<features>
+HSTS
+proxy
+https
+large-time
+</features>
+
+<file name="%LOGDIR/hsts%TESTNUMBER">
+# comment in input file
+foo.example. "20391001 04:47:41"
+.foo.example. "20291001 04:47:41"
+</file>
+
+<name>
+HSTS duplicate domains where the update adds subdomains
+</name>
+<command>
+-x http://%HOSTIP:%HTTPPORT http://this.hsts.example/%TESTNUMBER --hsts %LOGDIR/hsts%TESTNUMBER
+</command>
+<disable>
+test-duphandle
+</disable>
+</client>
+
+<verify>
+<protocol crlf="headers">
+GET http://this.hsts.example/%TESTNUMBER HTTP/1.1
+Host: this.hsts.example
+User-Agent: curl/%VERSION
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+</protocol>
+<file name="%LOGDIR/hsts%TESTNUMBER" mode="text">
+# Your HSTS cache. https://curl.se/docs/hsts.html
+# This file was generated by libcurl! Edit at your own risk.
+.foo.example "20391001 04:47:41"
+</file>
+
+</verify>
+</testcase>