idnits 2.17.1 draft-yasskin-wpack-bundled-exchanges-00.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The abstract seems to contain references ([2], [1]), which it shouldn't. Please replace those with straight textual mentions of the documents in question. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (June 13, 2018) is 2116 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) -- Looks like a reference, but probably isn't: '1' on line 879 -- Looks like a reference, but probably isn't: '2' on line 881 -- Looks like a reference, but probably isn't: '3' on line 883 -- Looks like a reference, but probably isn't: '4' on line 885 == Unused Reference: 'SRI' is defined on line 850, but no explicit reference was found in the text -- Possible downref: Non-RFC (?) normative reference: ref. 'FETCH' == Outdated reference: A later version (-16) exists of draft-ietf-cbor-7049bis-02 -- Possible downref: Normative reference to a draft: ref. 'I-D.ietf-cbor-7049bis' == Outdated reference: A later version (-08) exists of draft-ietf-cbor-cddl-02 -- Possible downref: Non-RFC (?) normative reference: ref. 'INFRA' ** Obsolete normative reference: RFC 7231 (Obsoleted by RFC 9110) ** Obsolete normative reference: RFC 7540 (Obsoleted by RFC 9113) -- Possible downref: Non-RFC (?) normative reference: ref. 'SRI' -- Possible downref: Non-RFC (?) normative reference: ref. 'URL' == Outdated reference: A later version (-09) exists of draft-yasskin-http-origin-signed-responses-03 == Outdated reference: A later version (-02) exists of draft-yasskin-webpackage-use-cases-01 Summary: 3 errors (**), 0 flaws (~~), 6 warnings (==), 10 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group J. Yasskin 3 Internet-Draft Google 4 Intended status: Standards Track June 13, 2018 5 Expires: December 15, 2018 7 Bundled HTTP Exchanges 8 draft-yasskin-wpack-bundled-exchanges-00 10 Abstract 12 Bundled exchanges provide a way to bundle up groups of HTTP 13 request+response pairs to transmit or store them together. They can 14 include multiple top-level resources with one identified as the 15 default by a manifest, provide random access to their component 16 exchanges, and efficiently store 8-bit resources. 18 Note to Readers 20 Discussion of this draft takes place on the ART area mailing list 21 (art@ietf.org), which is archived at 22 https://mailarchive.ietf.org/arch/search/?email_list=art [1]. 24 The source code and issues list for this draft can be found in 25 https://github.com/WICG/webpackage [2]. 27 Status of This Memo 29 This Internet-Draft is submitted in full conformance with the 30 provisions of BCP 78 and BCP 79. 32 Internet-Drafts are working documents of the Internet Engineering 33 Task Force (IETF). Note that other groups may also distribute 34 working documents as Internet-Drafts. The list of current Internet- 35 Drafts is at https://datatracker.ietf.org/drafts/current/. 37 Internet-Drafts are draft documents valid for a maximum of six months 38 and may be updated, replaced, or obsoleted by other documents at any 39 time. It is inappropriate to use Internet-Drafts as reference 40 material or to cite them other than as "work in progress." 42 This Internet-Draft will expire on December 15, 2018. 44 Copyright Notice 46 Copyright (c) 2018 IETF Trust and the persons identified as the 47 document authors. All rights reserved. 49 This document is subject to BCP 78 and the IETF Trust's Legal 50 Provisions Relating to IETF Documents 51 (https://trustee.ietf.org/license-info) in effect on the date of 52 publication of this document. Please review these documents 53 carefully, as they describe your rights and restrictions with respect 54 to this document. Code Components extracted from this document must 55 include Simplified BSD License text as described in Section 4.e of 56 the Trust Legal Provisions and are provided without warranty as 57 described in the Simplified BSD License. 59 Table of Contents 61 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 62 1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 3 63 1.2. Mode of specification . . . . . . . . . . . . . . . . . . 3 64 2. Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . 3 65 2.1. Stream attributes and operations . . . . . . . . . . . . 4 66 2.2. Load a bundle's metadata . . . . . . . . . . . . . . . . 4 67 2.2.1. Load a bundle's metadata from the end . . . . . . . . 5 68 2.3. Load a response from a bundle . . . . . . . . . . . . . . 5 69 3. Format . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 70 3.1. Top-level structure . . . . . . . . . . . . . . . . . . . 5 71 3.2. Load a bundle's metadata . . . . . . . . . . . . . . . . 6 72 3.2.1. Parsing the index section . . . . . . . . . . . . . . 8 73 3.2.2. Parsing the manifest section . . . . . . . . . . . . 9 74 3.2.3. Parsing the critical section . . . . . . . . . . . . 10 75 3.2.4. The responses section . . . . . . . . . . . . . . . . 10 76 3.2.5. Starting from the end . . . . . . . . . . . . . . . . 10 77 3.3. Load a response from a bundle . . . . . . . . . . . . . . 11 78 3.4. Parsing CBOR items . . . . . . . . . . . . . . . . . . . 13 79 3.4.1. Parse a known-length item . . . . . . . . . . . . . . 13 80 3.4.2. Parsing variable-length data from a bytestring . . . 13 81 3.5. Interpreting CBOR HTTP headers . . . . . . . . . . . . . 14 82 4. Guidelines for bundle authors . . . . . . . . . . . . . . . . 15 83 5. Security Considerations . . . . . . . . . . . . . . . . . . . 15 84 6. IANA considerations . . . . . . . . . . . . . . . . . . . . . 16 85 6.1. Internet Media Type Registration . . . . . . . . . . . . 16 86 6.2. Web Bundle Section Name Registry . . . . . . . . . . . . 17 87 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 17 88 7.1. Normative References . . . . . . . . . . . . . . . . . . 17 89 7.2. Informative References . . . . . . . . . . . . . . . . . 19 90 7.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 19 91 Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 19 92 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 19 94 1. Introduction 96 To satisfy the use cases in [I-D.yasskin-webpackage-use-cases], this 97 document proposes a new bundling format to group HTTP resources. 98 Several of the use cases require the resources to be signed: that's 99 provided by bundling signed exchanges 100 ([I-D.yasskin-http-origin-signed-responses]) rather than natively in 101 this format. 103 1.1. Terminology 105 Exchange (noun) An HTTP request+response pair. This can either be a 106 request from a client and the matching response from a server or 107 the request in a PUSH_PROMISE and its matching response stream. 108 Defined by Section 8 of [RFC7540]. 110 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 111 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 112 "OPTIONAL" in this document are to be interpreted as described in BCP 113 14 [RFC2119] [RFC8174] when, and only when, they appear in all 114 capitals, as shown here. 116 1.2. Mode of specification 118 This specification defines how conformant bundle parsers work. It 119 does not constrain how encoders produce a bundle: although there are 120 some guidelines in Section 4, encoders MAY produce any sequence of 121 bytes that a conformant parser would parse into the intended 122 semantics. 124 This specification uses the conventions and terminology defined in 125 the Infra Standard ([INFRA]). 127 2. Semantics 129 A bundle is logically a set of HTTP exchanges, with a URL identifying 130 the manifest(s) of the bundle itself. 132 While the order of the exchanges is not semantically meaningful, it 133 can significantly affect performance when the bundle is loaded from a 134 network stream. 136 A bundle is parsed from a stream of bytes, which is assumed to have 137 the attributes and operations described in Section 2.1. 139 Bundle parsers support two operations, Load a bundle's metadata 140 (Section 2.2) and Load a response from a bundle (Section 2.3) each of 141 which can return an error instead of their normal result. 143 A client is expected to load the metadata for a bundle as soon as it 144 start downloading it or otherwise discovers it. Then, when fetching 145 ([FETCH]) a request, the cliend is expected to match it against the 146 requests in the metadata, and if one matches, load that request's 147 response. 149 2.1. Stream attributes and operations 151 o A sequence of *available bytes*. As the stream delivers bytes, 152 these are appended to the available bytes. 154 o An *EOF* flag that's true if the available bytes include the 155 entire stream. 157 o A *current offset* within the available bytes. 159 o A *seek to offset N* operation to set the current offset to N 160 bytes past the beginning of the available bytes. A seek past the 161 end of the available bytes blocks until N bytes are available. If 162 the stream ends before enough bytes are received, either due to a 163 network error or because the stream has a finite length, the seek 164 fails. 166 o A *read N bytes* operation, which blocks until N bytes are 167 available past the current offset, and then returns them and seeks 168 forward by N bytes. If the stream ends before enough bytes are 169 received, either due to a network error or because the stream has 170 a finite length, the read operation returns an error instead. 172 2.2. Load a bundle's metadata 174 This takes the bundle's stream and returns a map ([INFRA]) of 175 metadata containing at least keys named: 177 requests A map ([INFRA]) whose keys are [FETCH] requests for the 178 HTTP exchanges in the bundle, and whose values are opaque metadata 179 that Load a response from a bundle can use to find the matching 180 response. 182 manifest The URL of the bundle's manifest(s). This is a URL to 183 support bundles with multiple different manifests, where the 184 client uses content negotiation to select the most appropriate 185 one. 187 The map may include other items added by sections defined in the 188 Web Bundle Section Name Registry. 190 This operation only waits for a prefix of the stream that, if the 191 bundle is encoded with the "responses" section last, ends before the 192 first response. 194 This operation's implementation is in Section 3.2. 196 2.2.1. Load a bundle's metadata from the end 198 If a bundle's bytes are embedded in a longer sequence rather than 199 being streamed, a parser can also load them starting from a pointer 200 to the last byte of the bundle. This returns the same data as 201 Section 2.2. 203 This operation's implementation is in Section 3.2.5. 205 2.3. Load a response from a bundle 207 This takes the sequence of bytes representing the bundle and one 208 request returned from Section 2.2 with its metadata, and returns the 209 response ([FETCH]) matching that request. 211 This operation can be completed without inspecting bytes other than 212 those that make up the loaded response, although higher-level 213 operations like proving that an exchange is correctly signed 214 ([I-D.yasskin-http-origin-signed-responses]) may need to load other 215 responses. 217 Note that this operation uses the metadata for a particular request 218 returned by Section 2.2, while a client will generally want to load 219 the response for a request that the client generated. TODO: Specify 220 how a client determines the best available bundled response, if any, 221 for that client-generated request, in this or another document. 223 This operation's implementation is in Section 3.3. 225 3. Format 227 3.1. Top-level structure 229 _This section is non-normative._ 231 A bundle holds a series of named sections. The beginning of the 232 bundle maps section names to the range of bytes holding that section. 233 The most important section is the "index" (Section 3.2.1), which 234 similarly maps serialized HTTP requests to the range of bytes holding 235 that request's serialized response. Byte ranges are represented 236 using an offset from some point in the bundle _after_ the encoding of 237 the range itself, to reduce the amount of work needed to use the 238 shortest possible encoding of the range. 240 Future specifications can define new sections with extra data, and if 241 necessary, these sections can be marked "critical" (Section 3.2.3) to 242 prevent older parsers from using the rest of the bundle incorrectly. 244 The bundle is roughly a CBOR item ([I-D.ietf-cbor-7049bis]) with the 245 following CDDL ([I-D.ietf-cbor-cddl]) schema, but bundle parsers are 246 required to successfully parse some byte strings that aren't valid 247 CBOR. For example, sections might have padding between them, or even 248 overlap, as long as the embedded relative offsets cause the parsing 249 algorithms in this specification to return data. 251 webbundle = [ 252 ; 🌐📦 in UTF-8. 253 magic: h'F0 9F 8C 90 F0 9F 93 A6', 254 section-offsets: bytes .cbor {* ($section-name .within tstr) => 255 [ offset: uint, length: uint] }, 256 sections: [* $section ], 257 length: bytes .size 8, ; Big-endian number of bytes in the bundle. 258 ] 260 $section-name /= "index" / "manifest" / "critical" / "responses" 262 $section /= index / manifest / critical / responses 264 responses = [*response] 266 3.2. Load a bundle's metadata 268 A bundle holds a series of sections, which can be accessed randomly 269 using the information in the "section-offset" CBOR item: 271 section-offsets = {* tstr => [ offset: uint, length: uint] }, 273 Offsets in this item are relative to the _end_ of the section-offset 274 item. 276 To implement Section 2.2, the parser MUST run the following steps, 277 taking the "stream" as input. 279 1. Seek to offset 0 in "stream". Assert: this operation doesn't 280 fail. 282 2. If reading 10 bytes from "stream" returns an error or doesn't 283 return the bytes with hex encoding "84 48 F0 9F 8C 90 F0 9F 93 284 A6" (the CBOR encoding of the 4-item array initial byte and 285 8-byte bytestring initial byte, followed by 🌐📦 286 in UTF-8), return an error. 288 3. Let "sectionOffsetsLength" be the result of getting the length 289 of the CBOR bytestring header from "stream" (Section 3.4.2). If 290 this is an error, return that error. 292 4. If "sectionOffsetsLength" is TBD or greater, return an error. 294 5. Let "sectionOffsetsBytes" be the result of reading 295 "sectionOffsetsLength" bytes from "stream". If 296 "sectionOffsetsBytes" is an error, return that error. 298 6. Let "sectionOffsets" be the result of parsing one CBOR item 299 (Section 3.4) from "sectionOffsetsBytes", matching the section- 300 offsets rule in the CDDL ([I-D.ietf-cbor-cddl]) above. If 301 "sectionOffsets" is an error, return an error. 303 7. Let "sectionsStart" be the current offset within "stream". For 304 example, if "sectionOffsetsLength" were 52, "sectionsStart" 305 would be 64. 307 8. Let "knownSections" be the subset of the Section 6.2 that this 308 client has implemented. 310 9. Let "ignoredSections" be an empty set. 312 10. For each ""name"" key in "sectionOffsets", if ""name""'s 313 specification in "knownSections" says not to process other 314 sections, add those sections' names to "ignoredSections". 316 11. Let "metadata" be an empty map ([INFRA]). 318 12. For each ""name""/["offset", "length"] triple in 319 "sectionOffsets": 321 1. If ""name"" isn't in "knownSections", continue to the next 322 triple. 324 2. If ""name""'s Metadata field is "No", continue to the next 325 triple. 327 3. If ""name"" is in "ignoredSections", continue to the next 328 triple. 330 4. Seek to offset "sectionsStart + offset" in "stream". If 331 this fails, return an error. 333 5. Let "sectionContents" be the result of reading "length" 334 bytes from "stream". If "sectionContents" is an error, 335 return that error. 337 6. Follow ""name""'s specification from "knownSections" to 338 process the section, passing "sectionContents", "stream", 339 "sectionOffsets", "sectionsStart", and "metadata". If this 340 returns an error, return it. 342 13. If "metadata" doesn't have entries with keys "requests" and 343 "manifest", return an error. 345 14. Return "metadata". 347 3.2.1. Parsing the index section 349 The "index" section defines the set of HTTP requests in the bundle 350 and identifies their locations in the "responses" section. 352 index = {* headers => [ offset: uint, 353 length: uint] } 355 To parse the index section, given its "sectionContents", the 356 "sectionsStart" offset, the "sectionOffsets" CBOR item, and the 357 "metadata" map to fill in, the parser MUST do the following: 359 1. Let "index" be the result of parsing "sectionContents" as a CBOR 360 item matching the "index" rule in the above CDDL (Section 3.4). 361 If "index" is an error, return an error. 363 2. Let "requests" be an initially-empty map ([INFRA]) from HTTP 364 requests ([FETCH]) to structs ([INFRA]) with items named "offset" 365 and "length". 367 3. For each "cbor-http-request"/["offset", "length"] triple in 368 "index": 370 1. Let "headers"/"pseudos" be the result of converting "cbor- 371 http-request" to a header list and pseudoheaders using the 372 algorithm in Section 3.5. If this returns an error, return 373 that error. 375 2. If "pseudos" does not have keys named ':method' and ':url', 376 or its size isn't 2, return an error. 378 3. If "pseudos[':method']" is not 'GET', return an error. 380 Note: This could probably support any cacheable 381 (Section 4.2.3) of [RFC7231]) and safe (Section 4.2.1 of 382 [RFC7231]) method, matching PUSH_PROMISE (Section 8.2 of 383 [RFC7540]), but today that's only HEAD and GET, and HEAD can 384 be served as a transformation of GET, so this version of the 385 specification keeps the method simple. 387 4. Let "parsedUrl" be the result of parsing ([URL]) 388 "pseudos[':url']" with no base URL. 390 5. If "parsedUrl" is a failure, its fragment is not null, or it 391 includes credentials, return an error. 393 6. Let "http-request" be a new request ([FETCH]) whose: 395 + method is "pseudos[':method']", 397 + url is "parsedUrl", 399 + header list is "headers", and 401 + client is null. 403 7. Let "streamOffset" be "sectionsStart + section- 404 offsets["responses"].offset + offset". That is, offsets in 405 the index are relative to the start of the "responses" 406 section. 408 8. If "offset + length" is greater than 409 "sectionOffsets["responses"].length", return an error. 411 9. Set "requests"["http-request"] to a struct whose "offset" 412 item is "streamOffset" and whose "length" item is "length". 414 4. Set "metadata["requests"]" to "requests". 416 3.2.2. Parsing the manifest section 418 The "manifest" section records a single URL identifying the manifest 419 of the bundle. The bundle can contain multiple resources at this 420 URL, and the client is expected to content-negotiate for the best 421 one. For example, a client might select the one with an "accept" 422 header of "application/manifest+json" ([appmanifest]) and an "accept- 423 language" header of "es-419". 425 manifest = text 426 To parse the manifest section, given its "sectionContents" and the 427 "metadata" map to fill in, the parser MUST do the following: 429 1. Let "urlString" be the result of parsing "sectionContents" as a 430 CBOR item matching the above "manifest" rule (Section 3.4. If 431 "urlString" is an error, return that error. 433 2. Let "url" be the result of parsing ([URL]) "urlString" with no 434 base URL. 436 3. If "url" is a failure, its fragment is not null, or it includes 437 credentials, return an error. 439 4. Set "metadata["manifest"]" to "url". 441 3.2.3. Parsing the critical section 443 The "critical" section lists sections of the bundle that the client 444 needs to understand in order to load the bundle correctly. Other 445 sections are assumed to be optional. 447 critical = [*tstr] 449 To parse the critical section, given its "sectionContents" and the 450 "metadata" map to fill in, the parser MUST do the following: 452 1. Let "critical" be the result of parsing "sectionContents" as a 453 CBOR item matching the above "critical" rule (Section 3.4). If 454 "critical" is an error, return that error. 456 2. For each value "sectionName" in the "critical" list, if the 457 client has not implemented sections named "sectionName", return 458 an error. 460 This section does not modify the returned metadata. 462 3.2.4. The responses section 464 The responses section does not add any items to the bundle metadata 465 map. Instead, its offset and length are used in processing the index 466 section (Section 3.2.1). 468 3.2.5. Starting from the end 470 The length of a bundle is encoded as a big-endian integer inside a 471 CBOR byte string at the end of the bundle. 473 +------------+-----+----+----+----+----+----+----+----+----+----+ 474 | first byte | ... | 48 | 00 | 00 | 00 | 00 | 00 | BC | 61 | 4E | 475 +------------+-----+----+----+----+----+----+----+----+----+----+ 476 / \ 477 0xBC614E-10=12345668 omitted bytes 479 Figure 1: Example trailing bytes 481 Parsing from the end allows the bundle to be appended to another 482 format such as a self-extracting executable. 484 To implement Section 2.2.1, taking a sequence of bytes "bytes", the 485 client MUST: 487 1. Let "byteStringHeader" be "bytes[bytes.length - 9]". If 488 "byteStringHeader is not "0x48` (the CBOR 489 ([I-D.ietf-cbor-7049bis]) initial byte for an 8-byte byte 490 string), return an error. 492 2. Let "bundleLength" be "[bytes[bytes.length - 8], 493 bytes[bytes.length])" (the last 8 bytes) interpreted as a big- 494 endian integer. 496 3. If "bundleLength > bytes.length", return an error. 498 4. Let "stream" be a new stream whose: 500 * Available bytes are "[bytes[bytes.length - bundleLength], 501 bytes[bytes.length])". 503 * EOF flag is set. 505 * Current offset is initially 0. 507 * The seek to offset N and read N bytes operations succeed 508 immediately if "currentOffset + N <= bundleLength" and fail 509 otherwise. 511 5. Return the result of running Section 3.2 with "stream" as input. 513 3.3. Load a response from a bundle 515 The result of Load a bundle's metadata maps each request to a 516 response, which consists of headers and a payload. The headers can 517 be loaded from the bundle's stream before waiting for the payload, 518 and similarly the payload can be streamed to downstream consumers. 520 response = [headers: bstr .cbor headers, payload: bstr] 521 To implement Section 2.3, the parser MUST run the following steps, 522 taking the bundle's "stream" and one "request" and its 523 "requestMetadata" as returned by Section 2.2. 525 1. Seek to offset "requestMetadata.offset" in "stream". If this 526 fails, return an error. 528 2. Read 1 byte from "stream". If this is an error or isn't "0x82", 529 return an error. 531 3. Let "headerLength" be the result of getting the length of a CBOR 532 bytestring header from "stream" (Section 3.4.2). If 533 "headerLength" is an error, return that error. 535 4. If "headerLength" is TBD or greater, return an error. 537 5. Let "headerCbor" be the result of reading "headerLength" bytes 538 from "stream" and parsing a CBOR item from them matching the 539 "headers" CDDL rule. If either the read or parse returns an 540 error, return that error. 542 6. Let "headers"/"pseudos" be the result of converting "cbor-http- 543 request" to a header list and pseudoheaders using the algorithm 544 in Section 3.5. If this returns an error, return that error. 546 7. If "pseudos" does not have a key named ':status' or its size 547 isn't 1, return an error. 549 8. If "pseudos[':status']" isn't exactly 3 ASCII decimal digits, 550 return an error. 552 9. Let "payloadLength" be the result of getting the length of a 553 CBOR bytestring header from "stream" (Section 3.4.2). If 554 "payloadLength" is an error, return that error. 556 10. If "stream.currentOffset + payloadLength != 557 requestMetadata.offset + requestMetadata.length", return an 558 error. 560 11. Let "body" be a new body ([FETCH]) whose stream is a tee'd copy 561 of "stream" starting at the current offset and ending after 562 "payloadLength" bytes. 564 TODO: Add the rest of the details of creating a "ReadableStream" 565 object. 567 12. Let "response" be a new response ([FETCH]) whose: 569 * Url list is "request"'s url list, 571 * status is "pseudos[':status']", 573 * header list is "headers", and 575 * body is "body". 577 13. Return "response". 579 3.4. Parsing CBOR items 581 Parsing a bundle involves parsing many CBOR items. All of these 582 items need to be canonically encoded. 584 3.4.1. Parse a known-length item 586 To parse a CBOR item ([I-D.ietf-cbor-7049bis]), optionally matching a 587 CDDL rule ([I-D.ietf-cbor-cddl]), from a sequence of bytes, "bytes", 588 the parser MUST do the following: 590 1. If "bytes" are not a well-formed CBOR item, return an error. 592 2. If "bytes" does not satisfy the core canonicalization 593 requirements from Section 4.9 of [I-D.ietf-cbor-7049bis], return 594 an error. This format does not use floating point values or 595 tags, so this specification does not add any canonicalization 596 rules for them. 598 3. If "bytes" includes extra bytes after the encoding of a CBOR 599 item, return an error. 601 4. Let "item" be the result of decoding "bytes" as a CBOR item. 603 5. If a CDDL rule was specified, but "item" does not match it, 604 return an error. 606 6. Return "item". 608 3.4.2. Parsing variable-length data from a bytestring 610 Bundles encode variable-length data in CBOR bytestrings, which are 611 prefixed with their length. This algorithm returns the number of 612 bytes in the variable-length item and sets the stream's current 613 offset to the first byte of the contents. 615 To get the length of a CBOR bytestring header from a bundle's stream, 616 the parser MUST do the following: 618 1. Let "firstByte" be the result of reading 1 byte from the stream. 619 If "firstByte" is an error, return that error. 621 2. If "firstByte & 0xE0" is not "0x40", the item is not a 622 bytestring. Return an error. 624 3. If "firstByte & 0x1F" is: 626 0..23, inclusive Return "firstByte". 628 24 Let "content" be the result of reading 1 byte from the stream. 629 If "content" is an error or is less than 24, return an error. 631 25 Let "content" be the result of reading 2 bytes from the 632 stream. If "content" is an error or its first byte is 0, 633 return an error. 635 26 Let "content" be the result of reading 4 bytes from the 636 stream. If "content" is an error or its first two bytes are 637 0, return an error. 639 27 Let "content" be the result of reading 8 bytes from the 640 stream. If "content" is an error or its first four bytes are 641 0, return an error. 643 28..31, inclusive Return an error. 645 4. Return the big-endian integer encoded in "content". 647 3.5. Interpreting CBOR HTTP headers 649 Bundles represent HTTP requests and responses as a list of headers, 650 matching the following CDDL ([I-D.ietf-cbor-cddl]): 652 headers = {* bstr => bstr} 654 Pseudo-headers starting with a ":" provide the non-header information 655 needed to create a request or response as appropriate 657 To convert a CBOR item "item" into a [FETCH] header list and 658 pseudoheaders, parsers MUST do the following: 660 1. If "item" doesn't match the "headers" rule in the above CDDL, 661 return an error. 663 2. Let "headers" be a new header list ([FETCH]). 665 3. Let "pseudos" be an empty map ([INFRA]). 667 4. For each pair "name"/"value" in "item": 669 1. If "name" contains any upper-case or non-ASCII characters, 670 return an error. This matches the requirement in 671 Section 8.1.2 of [RFC7540]. 673 2. If "name" starts with a ':': 675 1. Assert: "pseudos[name]" does not exist, because CBOR maps 676 cannot contain duplicate keys. 678 2. Set "pseudos[name]" to "value". 680 3. Continue. 682 3. If "name" or "value" doesn't satisfy the requirements for a 683 header in [FETCH], return an error. 685 4. Assert: "headers" does not contain ([FETCH]) "name", because 686 CBOR maps cannot contain duplicate keys and an earlier step 687 rejected upper-case bytes. 689 Note: This means that a response cannot set more than one 690 cookie, because the "Set-Cookie" header ([RFC6265]) has to 691 appear multiple times to set multiple cookies. 693 5. Append "name"/"value" to "headers". 695 5. Return "headers"/"pseudos". 697 4. Guidelines for bundle authors 699 Bundles SHOULD consist of a single CBOR item satisfying the core 700 canonicalization requirements (Section 3.4) and matching the 701 "webbundle" CDDL rule in Section 3.1. 703 5. Security Considerations 705 Bundles currently have no mechanism for ensuring that the signed 706 exchanges they contain constitute a consistent version of those 707 resources. Even if a website never has a security vulnerability when 708 resources are fetched at a single time, an attacker might be able to 709 combine a set of resources pulled from different versions of the 710 website to build a vulnerable site. While the vulnerable site could 711 have occurred by chance on a client's machine due to normal HTTP 712 caching, bundling allows an attacker to guarantee that it happens. 713 Future work in this specification might allow a bundle to constrain 714 its resources to come from a consistent version. 716 6. IANA considerations 718 6.1. Internet Media Type Registration 720 IANA maintains the registry of Internet Media Types [RFC6838] at 721 https://www.iana.org/assignments/media-types [3]. 723 o Type name: application 725 o Subtype name: webbundle 727 o Required parameters: N/A 729 o Optional parameters: N/A 731 o Encoding considerations: binary 733 o Security considerations: See Section 5 of this document. 735 o Interoperability considerations: N/A 737 o Published specification: This document 739 o Applications that use this media type: None yet, but it is 740 expected that web browsers will use this format. 742 o Fragment identifier considerations: N/A 744 o Additional information: 746 * Deprecated alias names for this type: N/A 748 * Magic number(s): 84 48 F0 9F 8C 90 F0 9F 93 A6 750 * File extension(s): .wbn 752 * Macintosh file type code(s): N/A 754 o Person & email address to contact for further information: See the 755 Author's Address section of this specification. 757 o Intended usage: COMMON 759 o Restrictions on usage: N/A 761 o Author: See the Author's Address section of this specification. 763 o Change controller: The IESG iesg@ietf.org [4] 764 o Provisional registration? (standards tree only): Not yet. 766 6.2. Web Bundle Section Name Registry 768 IANA is directed to create a new registry with the following 769 attributes: 771 Name: Web Bundle Section Names 773 Review Process: Specification Required 775 Initial Assignments: 777 +--------------+---------------+----------+ 778 | Section Name | Specification | Metadata | 779 +--------------+---------------+----------+ 780 | "index" | Section 3.2.1 | Yes | 781 | | | | 782 | "manifest | Section 3.2.2 | Yes | 783 | | | | 784 | "critical | Section 3.2.3 | Yes | 785 | | | | 786 | "responses" | Section 3.2.4 | No | 787 +--------------+---------------+----------+ 789 Requirements on new assignments: 791 Section Names MUST be encoded in UTF-8. 793 Assignments must specify whether the section is parsed during 794 Load a bundle's metadata (Metadata=Yes) or not (Metadata=No). 796 The section's specification can use the bytes making up the section, 797 the bundle's stream (Section 2.1), the "sectionOffsets" CBOR item 798 (Section 3.2), and the offset within the stream where sections start, 799 as input, and MUST say if an error is returned, and otherwise what 800 items, if any, are added to the map that Section 3.2 returns. A 801 section's specification MAY say that, if it is present, another 802 section is not processed. 804 7. References 806 7.1. Normative References 808 [appmanifest] 809 Caceres, M., Christiansen, K., Lamouri, M., Kostiainen, 810 A., Dolin, R., and M. Giuca, "Web App Manifest", World 811 Wide Web Consortium WD WD-appmanifest-20180523, May 2018, 812 . 814 [FETCH] WHATWG, "Fetch", June 2018, 815 . 817 [I-D.ietf-cbor-7049bis] 818 Bormann, C. and P. Hoffman, "Concise Binary Object 819 Representation (CBOR)", draft-ietf-cbor-7049bis-02 (work 820 in progress), March 2018. 822 [I-D.ietf-cbor-cddl] 823 Birkholz, H., Vigano, C., and C. Bormann, "Concise data 824 definition language (CDDL): a notational convention to 825 express CBOR data structures", draft-ietf-cbor-cddl-02 826 (work in progress), February 2018. 828 [INFRA] WHATWG, "Infra", June 2018, 829 . 831 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 832 Requirement Levels", BCP 14, RFC 2119, 833 DOI 10.17487/RFC2119, March 1997, 834 . 836 [RFC7231] Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer 837 Protocol (HTTP/1.1): Semantics and Content", RFC 7231, 838 DOI 10.17487/RFC7231, June 2014, 839 . 841 [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext 842 Transfer Protocol Version 2 (HTTP/2)", RFC 7540, 843 DOI 10.17487/RFC7540, May 2015, 844 . 846 [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 847 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 848 May 2017, . 850 [SRI] Akhawe, D., Braun, F., Marier, F., and J. Weinberger, 851 "Subresource Integrity", World Wide Web Consortium 852 Recommendation REC-SRI-20160623, June 2016, 853 . 855 [URL] WHATWG, "URL", June 2018, . 857 7.2. Informative References 859 [I-D.yasskin-http-origin-signed-responses] 860 Yasskin, J., "Signed HTTP Exchanges", draft-yasskin-http- 861 origin-signed-responses-03 (work in progress), March 2018. 863 [I-D.yasskin-webpackage-use-cases] 864 Yasskin, J., "Use Cases and Requirements for Web 865 Packages", draft-yasskin-webpackage-use-cases-01 (work in 866 progress), March 2018. 868 [RFC6265] Barth, A., "HTTP State Management Mechanism", RFC 6265, 869 DOI 10.17487/RFC6265, April 2011, 870 . 872 [RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type 873 Specifications and Registration Procedures", BCP 13, 874 RFC 6838, DOI 10.17487/RFC6838, January 2013, 875 . 877 7.3. URIs 879 [1] https://mailarchive.ietf.org/arch/search/?email_list=art 881 [2] https://github.com/WICG/webpackage 883 [3] https://www.iana.org/assignments/media-types 885 [4] mailto:iesg@ietf.org 887 Appendix A. Acknowledgements 889 Author's Address 891 Jeffrey Yasskin 892 Google 894 Email: jyasskin@chromium.org