unsigned short dstport = srcport; /* the same by default */
size_t entries = 0;
struct Curl_str alpn;
- const char *sp;
- time_t maxage = 24 * 3600; /* default is 24 hours */
- bool persist = FALSE;
#ifdef CURL_DISABLE_VERBOSE_STRINGS
(void)data;
#endif
curlx_str_trimblanks(&alpn);
- /* Handle the optional 'ma' and 'persist' flags once first, as they need to
- be known for each alternative service. Unknown flags are skipped. */
- sp = strchr(p, ';');
- if(sp) {
- sp++; /* pass the semicolon */
- for(;;) {
- struct Curl_str name;
- struct Curl_str val;
- const char *vp;
- curl_off_t num;
- bool quoted;
- /* allow some extra whitespaces around name and value */
- if(curlx_str_until(&sp, &name, 20, '=') ||
- curlx_str_single(&sp, '=') ||
- curlx_str_until(&sp, &val, 80, ';'))
- break;
- curlx_str_trimblanks(&name);
- curlx_str_trimblanks(&val);
- /* the value might be quoted */
- vp = curlx_str(&val);
- quoted = (*vp == '\"');
- if(quoted)
- vp++;
- if(!curlx_str_number(&vp, &num, TIME_T_MAX)) {
- if(curlx_str_casecompare(&name, "ma"))
- maxage = (time_t)num;
- else if(curlx_str_casecompare(&name, "persist") && (num == 1))
- persist = TRUE;
- }
- if(quoted && curlx_str_single(&sp, '\"'))
- break;
- if(curlx_str_single(&sp, ';'))
- break;
- }
- }
-
do {
if(!curlx_str_single(&p, '=')) {
+ time_t maxage = 24 * 3600; /* default is 24 hours */
+ bool persist = FALSE;
/* [protocol]="[host][:port], [protocol]="[host][:port]" */
enum alpnid dstalpnid = Curl_str2alpnid(&alpn);
if(!curlx_str_single(&p, '\"')) {
if(curlx_str_single(&p, '\"'))
break;
+ /* Handle the optional 'ma' and 'persist' flags. Unknown flags are
+ skipped. */
+ curlx_str_passblanks(&p);
+ if(!curlx_str_single(&p, ';')) {
+ for(;;) {
+ struct Curl_str name;
+ struct Curl_str val;
+ const char *vp;
+ curl_off_t num;
+ bool quoted;
+ /* allow some extra whitespaces around name and value */
+ if(curlx_str_until(&p, &name, 20, '=') ||
+ curlx_str_single(&p, '=') ||
+ curlx_str_cspn(&p, &val, ",;"))
+ break;
+ curlx_str_trimblanks(&name);
+ curlx_str_trimblanks(&val);
+ /* the value might be quoted */
+ vp = curlx_str(&val);
+ quoted = (*vp == '\"');
+ if(quoted)
+ vp++;
+ if(!curlx_str_number(&vp, &num, TIME_T_MAX)) {
+ if(curlx_str_casecompare(&name, "ma"))
+ maxage = (time_t)num;
+ else if(curlx_str_casecompare(&name, "persist") && (num == 1))
+ persist = TRUE;
+ }
+ else
+ break;
+ p = vp; /* point to the byte ending the value */
+ curlx_str_passblanks(&p);
+ if(quoted && curlx_str_single(&p, '\"'))
+ break;
+ curlx_str_passblanks(&p);
+ if(curlx_str_single(&p, ';'))
+ break;
+ }
+ }
if(dstalpnid) {
if(!entries++)
/* Flush cached alternatives for this source origin, if any - when
fail_unless(Curl_llist_count(&asi->list) == 10, "wrong number of entries");
res = Curl_altsvc_parse(curl, asi,
- "h2=\":443\", h3=\":443\"; "
+ "h2=\":443\"; ma=180, h3=\":443\"; "
"persist = \"1\"; ma = 120;\r\n",
ALPN_h1, "curl.se", 80);
fail_if(res, "Curl_altsvc_parse(6) failed!");
ALPN_h2, "8.example.net", 80);
fail_if(res, "Curl_altsvc_parse(11) failed!");
+ res = Curl_altsvc_parse(curl, asi,
+ "h2=\"test2.se:443\"; ma=\"180 \" ; unknown=2, "
+ "h2=\"test3.se:443\"; ma = 120;\r\n",
+ ALPN_h2, "test.se", 443);
+ fail_if(res, "Curl_altsvc_parse(12) failed!");
+
Curl_altsvc_save(curl, asi, outname);
curl_easy_cleanup(curl);