Skip to content

Commit 7da9f80

Browse files
committed
Structured headers (#197)
Switch reporting to structured headers
1 parent 2c6ce08 commit 7da9f80

File tree

1 file changed

+54
-62
lines changed

1 file changed

+54
-62
lines changed

index.src.html

Lines changed: 54 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ <h1>Reporting API</h1>
115115
text: session; url: dfn-session
116116
text: success; url: dfn-success
117117
text: trying; url: dfn-try
118+
spec: STRUCTURED-HEADERS; urlPrefix: https://httpwg.org/http-extensions/draft-ietf-httpbis-header-structure.html#
119+
type: grammar
120+
text: sh-dictionary; url: rfc.section.3.2
118121
</pre>
119122
<pre class="biblio">
120123
{
@@ -123,6 +126,12 @@ <h1>Reporting API</h1>
123126
"href": "https://w3c.github.io/webappsec-secure-contexts/",
124127
"title": "Secure Contexts",
125128
"publisher": "W3C"
129+
},
130+
"STRUCTURED-HEADERS": {
131+
"authors": [ "Mark Nottingham", "Poul-Henning Kamp" ],
132+
"href": "https://httpwg.org/http-extensions/draft-ietf-httpbis-header-structure.html",
133+
"title": "Structured Headers for HTTP",
134+
"publisher": "IETF"
126135
}
127136
}
128137

@@ -167,8 +176,7 @@ <h3 id="examples">Examples</h3>
167176
define a set of reporting endpoints named "`endpoint-1`":
168177

169178
<pre>
170-
<a>Report-To</a>: { "<a for="ReportTo">name</a>": "endpoint-1",
171-
"<a for="ReportTo">url</a>": "https://example.com/reports" }
179+
<a>Reporting-Endpoints</a>: endpoint-1="https://example.com/reports"
172180
</pre>
173181

174182
And the following headers, which direct CSP and HPKP reports to that
@@ -187,10 +195,8 @@ <h3 id="examples">Examples</h3>
187195
the following header to define two reporting endpoints:
188196

189197
<pre>
190-
<a>Report-To</a>: { "<a for="ReportTo">name</a>": "csp-endpoint",
191-
"<a for="ReportTo">url</a>": "https://example.com/csp-reports" },
192-
{ "<a for="ReportTo">name</a>": "hpkp-endpoint",
193-
"<a for="ReportTo">url</a>": "https://example.com/hpkp-reports" }
198+
<a>Reporting-Endpoints</a>: csp-endpoint="https://example.com/csp-reports",
199+
hpkp-endpoint="https://example.com/hpkp-reports"
194200
</pre>
195201

196202
And the following headers, which direct CSP and HPKP reports to those named
@@ -393,53 +399,41 @@ <h3 id="document-configuration">Document configuration</h3>
393399
attribute>endpoints</dfn> list, which is a list of <a>endpoints</a>, each of
394400
which MUST have a distinct {{endpoint/name}}. (The algorithm in
395401
[[#process-header]] guarantees this by keeping the first entry in a
396-
`Report-To` header with a particular name.)
402+
`Reporting-Endpoints` header with a particular name.)
397403

398404
A server MAY define a set of reporting endpoints for a resource it returns,
399-
via the <a>`Report-To`</a> HTTP response header field. This mechanism
400-
is defined in [[#header]], and its processing in [[#process-header]].
405+
via the <a>`Reporting-Endpoints`</a> HTTP response header field. This
406+
mechanism is defined in [[#header]], and its processing in
407+
[[#process-header]].
401408

402409
Each <a>document</a> has an <dfn for="document" export attribute>reports</dfn>
403410
list, which is a list of <a>reports</a>.
404411

405-
<h3 id="header">The `Report-To` HTTP Response Header Field</h3>
406-
407-
The value of the <dfn export>`Report-To`</dfn> HTTP response header field is
408-
used to construct the reporting configuration for a resource. The header is
409-
represented by the following ABNF grammar [[!RFC5234]]:
410-
411-
<pre class="abnf" link-type="grammar" dfn-type="grammar">
412-
Report-To = <a>json-field-value</a>
413-
; See Section 2 of [[HTTP-JFV]], and Section 2 of [[RFC8259]]
414-
</pre>
412+
<h3 id="header">The `Reporting-Endpoints` HTTP Response Header Field</h3>
415413

416-
The header's value is interpreted as a JSON-formatted array of objects
417-
without the outer `[` and `]`, as described in Section 4 of [[HTTP-JFV]].
414+
The value of the <dfn export>`Reporting-Endpoints`</dfn> HTTP response header
415+
field is used to construct the reporting configuration for a resource.
418416

419-
Each object in the array defines an <a>endpoint</a> to which reports may be
420-
delivered, and will be parsed as defined in [[#process-header]].
417+
<a>`Reporting-Endpoints`</a> is a Dictionary Structured Header
418+
[[STRUCTURED-HEADERS]]. Each entry in the dictionary defines an
419+
<a>endpoint</a> to which reports may be delivered. The entry value MUST be a
420+
string.
421421

422-
The following subsections define the initial set of known members in each
423-
JSON object the header's value defines. Future versions of this document may
424-
define additional such members, and user agents MUST ignore unknown members
425-
when parsing the header.
422+
Each <a>endpoint</a> is defined by a String Item, which is interpreted as a
423+
URI-reference. If its value is not a valid URI-reference, that <a>endpoint</a>
424+
member MUST be ignored.
426425

427-
<h4 id="id-member">The `name` member</h4>
426+
Moreover, the URL that the member's value represents MUST be <a>potentially
427+
trustworthy</a> [[!SECURE-CONTEXTS]]. Non-secure endpoints will be ignored.
428428

429-
The OPTIONAL <dfn for="ReportTo">`name`</dfn> member is a string that
430-
associates a {{endpoint/name}} with the <a>endpoint</a>.
429+
No parameters are defined for <a>endpoints</a>, and any parameters which are
430+
specified will be silently ignored.
431431

432-
If present, the member's value MUST be a string. If not present, the
433-
<a>endpoint</a> will be given the {{endpoint/name}} "`default`".
432+
The header is represented by the following ABNF grammar [[!RFC5234]]:
434433

435-
<h4 id="url-member">The `url` member</h4>
436-
437-
The REQUIRED <dfn for="ReportTo">`url`</dfn> member is a string that defines
438-
the location of the <a>endpoint</a>.
439-
440-
The member's value MUST be a string. Moreover, the URL that the member's value
441-
represents MUST be <a>potentially trustworthy</a> [[!SECURE-CONTEXTS]].
442-
Non-secure endpoints will be ignored.
434+
<pre class="abnf" link-type="grammar" dfn-type="grammar">
435+
Reporting-Endpoints = <a>sh-dictionary</a>
436+
</pre>
443437

444438
<h3 id="process-header" algorithm>
445439
Process reporting endpoints for |response|
@@ -462,37 +456,35 @@ <h3 id="process-header" algorithm>
462456

463457
2. |response|'s <a for="response" attribute>header list</a> does not
464458
contain a <a>header</a> whose <a for="header" attribute>name</a> is
465-
"<a>`Report-To`</a>".
459+
"<a>`Reporting-Endpoints`</a>".
466460

467461
2. Let |header| be the <a for="header" attribute>value</a> of the
468462
<a>header</a> in |response|'s <a for="response" attribute>header list</a>
469-
whose name is "<a>`Report-To`</a>".
463+
whose name is "<a>`Reporting-Endpoints`</a>".
470464

471-
3. Let |list| be the result of executing the algorithm defined in Section 4
472-
of [[HTTP-JFV]] on |header|. If that algorithm results in an error, abort
473-
these steps.
465+
3. Let |parsed header| be the result of executing the algorithm defined in
466+
Section 4.2 of [[STRUCTURED-HEADERS]] on |header|, with <var
467+
ignore>header_type</var> set to "dictionary". If that algorithm fails
468+
parsing, abort these steps.
474469

475470
4. Let |endpoints| be an empty list.
476471

477-
5. For each |item| in |list|:
472+
5. For each |name| → |value_and_parameters| of |parsed header|:
478473

479-
1. Let |name| be |item|'s "<a for="ReportTo">`name`</a>" member's value
480-
if present, and "`default`" otherwise.
481474

482-
2. If there is already an <a>endpoint</a> in |endpoints| whose
483-
{{endpoint/name}} is |name|, skip to the next |item|.
475+
1. Let |endpoint url string| be the first element of the tuple
476+
|value_and_parameters|. If |endpoint url string| is not a string,
477+
then <a>continue</a>.
484478

485-
3. If |item| has no member named "<a for="ReportTo">`url`</a>", or that
486-
member's value is not a string, or if that value is not an
487-
<a>absolute-URL string</a> or a <a>path-absolute-URL string</a>, skip
488-
to the next |item|.
479+
2. Let |endpoint url| be the result of executing the <a>URL parser</a>
480+
on |endpoint url string|, with <a spec="url">base URL</a> set to
481+
|response|'s <a for="response" attribute>url</a>. If |endpoint url| is
482+
failure, then <a>continue</a>.
489483

490-
4. Let |url| be the result of executing the <a>URL parser</a> on |item|'s
491-
"<a for="ReportTo">`url`</a>" member's value, with <a spec="url">base
492-
URL</a> set to |response|'s <a for="response" attribute>url</a>. If
493-
|url| is failure, skip to the next |item|.
484+
3. If |endpoint url|'s <a>origin</a> is not <a>potentially
485+
trustworthy</a>, then <a>continue</a>.
494486

495-
5. Let |endpoint| be a new <a>endpoint</a> whose properties are set
487+
4. Let |endpoint| be a new <a>endpoint</a> whose properties are set
496488
as follows:
497489

498490
: {{endpoint/name}}
@@ -502,7 +494,7 @@ <h3 id="process-header" algorithm>
502494
: {{endpoint/failures}}
503495
:: 0
504496

505-
6. Add |endpoint| to |endpoints|.
497+
5. Add |endpoint| to |endpoints|.
506498

507499
6. Return |endpoints|.
508500

@@ -1090,13 +1082,13 @@ <h3 id="disable">Disabling Reporting</h3>
10901082
<section>
10911083
<h2 id="iana-considerations">IANA Considerations</h2>
10921084

1093-
<h3 id="header-field-registration">The `Report-To` Header</h3>
1085+
<h3 id="header-field-registration">The `Reporting-Endpoints` Header</h3>
10941086

10951087
The permanent message header field registry should be updated
10961088
with the following registration: [[!RFC3864]]
10971089

10981090
: Header field name
1099-
:: `Report-To`
1091+
:: `Reporting-Endpoints`
11001092
: Applicable protocol
11011093
:: http
11021094
: Status

0 commit comments

Comments
 (0)