idnits 2.17.1 draft-xie-bidirectional-messaging-02.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 document seems to lack a Security Considerations section. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (July 08, 2019) is 1753 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) ** Downref: Normative reference to an Informational RFC: RFC 6202 ** Obsolete normative reference: RFC 7540 (Obsoleted by RFC 9113) Summary: 3 errors (**), 0 flaws (~~), 1 warning (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 httpbis Working Group G. Xie 3 Internet-Draft A. Frindell 4 Intended status: Standards Track Facebook Inc. 5 Expires: January 9, 2020 July 08, 2019 7 An HTTP/2 Extension for Bidirectional Message Communication 8 draft-xie-bidirectional-messaging-02 10 Abstract 12 This draft proposes an HTTP/2 protocol extension that enables 13 bidirectional messaging communication between client and server. 15 Status of This Memo 17 This Internet-Draft is submitted in full conformance with the 18 provisions of BCP 78 and BCP 79. 20 Internet-Drafts are working documents of the Internet Engineering 21 Task Force (IETF). Note that other groups may also distribute 22 working documents as Internet-Drafts. The list of current Internet- 23 Drafts is at https://datatracker.ietf.org/drafts/current/. 25 Internet-Drafts are draft documents valid for a maximum of six months 26 and may be updated, replaced, or obsoleted by other documents at any 27 time. It is inappropriate to use Internet-Drafts as reference 28 material or to cite them other than as "work in progress." 30 This Internet-Draft will expire on January 9, 2020. 32 Copyright Notice 34 Copyright (c) 2019 IETF Trust and the persons identified as the 35 document authors. All rights reserved. 37 This document is subject to BCP 78 and the IETF Trust's Legal 38 Provisions Relating to IETF Documents 39 (https://trustee.ietf.org/license-info) in effect on the date of 40 publication of this document. Please review these documents 41 carefully, as they describe your rights and restrictions with respect 42 to this document. Code Components extracted from this document must 43 include Simplified BSD License text as described in Section 4.e of 44 the Trust Legal Provisions and are provided without warranty as 45 described in the Simplified BSD License. 47 1. Introduction 49 HTTP/2 [RFC7540] transports HTTP messages via a framing layer that 50 includes many technologies and optimizations designed to make 51 communication more efficient between clients and servers. These 52 include multiplexing of multiple streams on a single underlying 53 transport connection, flow control, stream dependencies and 54 priorities, header compression, and exchange of configuration 55 information between endpoints. 57 Many of these capabilities are generic and can be useful in 58 applications beyond web browsing, such as Publish/Subscribe protocols 59 or RPC. However, HTTP/2 framing's request/response client to server 60 communication pattern prevents wider use in this type of application. 61 This draft proposes an HTTP/2 protocol extension that enables 62 bidirectional communication between client and server. 64 Currently, the only mechanism in HTTP/2 for server to client 65 communication is server push. That is, servers can initiate 66 unidirectional push promised streams to clients, but clients cannot 67 respond to them and either accept or discard them silently. 68 Additionally, intermediaries along the path may have different server 69 push policies and may not forward push promised streams to the 70 downstream client. This best effort mechanism is not sufficient to 71 reliably deliver content from servers to clients, limiting additional 72 use-cases, such as sending messages and notifications from servers to 73 clients immediately when they become available. 75 Several techniques have been developed to workaround these 76 limitations: long polling [RFC6202], WebSocket [RFC8441], and 77 tunneling using the CONNECT method. All of these approaches layer an 78 application protocol on top of HTTP/2, using HTTP/2 streams as 79 transport connections. This layering defeats the optimizations 80 provided by HTTP/2. For example, multiplexing multiple parallel 81 interactions onto one HTTP/2 stream reintroduces head of line 82 blocking. Also, application metadata is encapsulated into DATA 83 frames, rather than HEADERS frames, making header compression 84 impossible. Further, user data is framed multiple times at different 85 protocol layers, which offsets the wire efficiency of HTTP/2 binary 86 framing. Take WebSocket over HTTP/2 as an example, user data is 87 framed at the application protocol, WebSocket, and HTTP/2 layers. 88 This not only introduces overhead on the wire, but also complicates 89 data processing. Finally, intermediaries have no visibility to user 90 interactions layered on a single HTTP/2 stream, and lose the 91 capability to collect telemetry metrics (e.g., time to the first/last 92 byte of request and response) for services. 94 These techniques also pose new operational challenges to 95 intermediaries. Because all traffic from a user's session is 96 encapsulated into one HTTP/2 stream, this stream can last a very long 97 time. Intermediaries may take a long time to drain these streams. 98 HTTP/2 GOAWAY only signals the remote endpoint to stop using the 99 connection for new streams; additional work is required to prevent 100 new application messages from being initiated on the long lived 101 stream. 103 In this draft, a new HTTP/2 frame is introduced which has the routing 104 properties of a PUSH_PROMISE frame and the bi-directionality of a 105 HEADERS frame. The extension provides several benefits: 107 1. After a HTTP/2 connection is established, a server can initiate 108 streams to the client at any time, and the client can respond to 109 the incoming streams accordingly. That is, the communication 110 over HTTP/2 is bidirectional and symmetric. 112 2. All of the HTTP/2 technologies and optimizations still apply. 113 Intermediaries also have all the necessary metadata to properly 114 handle the communication between the client and the server. 116 3. Clients are able to group streams together for routing purposes, 117 such that each individual stream group can be used for a 118 different service, within the same HTTP/2 connection. 120 2. Conventions and Terminology 122 The keywords *MUST*, *MUST NOT*, *REQUIRED*, *SHALL*, *SHALL NOT*, 123 *SHOULD*, *SHOULD NOT*, *RECOMMENDED*, *MAY*, and *OPTIONAL*, when 124 they appear in this document, are to be interpreted as described in 125 [RFC2119]. 127 All the terms defined in the Conventions and Terminology section in 128 [RFC7540] apply to this document. 130 3. Solution Overview 132 3.1. RStream and XStream 134 A routing stream (RStream) is a regular HTTP/2 stream. It is opened 135 by a HEADERS frame, and *MAY* be continued by CONTINUATION and DATA 136 frames. RStreams are initiated by clients to servers, and can be 137 independently routed by intermediaries on the network path. The main 138 purpose for an RStream is to facilitate XStreams' intermediary 139 traversal. 141 A new HTTP/2 stream called eXtended stream (XStream) is introduced 142 for exchanging user data bidirectionally. An XStream is opened by an 143 XHEADERS frame, and *MAY* be continued by CONTINUATION and DATA 144 frames. XStreams can be initiated by either clients or servers. 145 Unlike a regular stream, an XStream *MUST* be associated with an open 146 RStream. In this way, XStreams can be routed according to their 147 RStreams by intermediaries and servers. XStream *MUST NOT* be 148 associated with any other XStream, or any closed RStream. Otherwise, 149 it cannot be routed properly. 151 3.2. Bidirectional Communication 153 With RStreams and XStreams, HTTP/2 framing can be used natively for 154 bidirectional communication. As shown in Figure 1 and Figure 2 , as 155 long as an RStream is open from client to server, either endpoint can 156 initiate an XStream to its peer. 158 +--------+ RStream (5) +---------+ RStream (1) +--------+ 159 | client |>--------------->| proxy |>---------------->| server | 160 +--------+ +---------+ +--------+ 161 v ^ v ^ 162 | XStream(7, RS=5) | | XStream(3, RS=1) | 163 +------------------------+ +------------------------+ 165 Figure 1: Client initiates an XStream to server. 167 +--------+ RStream (5) +---------+ RStream (1) +--------+ 168 | client |>--------------->| proxy |>---------------->| server | 169 +--------+ +---------+ +--------+ 170 ^ v ^ v 171 | XStream(4, RS=5) | | XStream(2, RS=1) | 172 +------------------------+ +------------------------+ 174 Figure 2: Server initiates an XStream to client. 176 3.3. XStream Grouping 178 A client can multiplex RStreams, XStreams and regular HTTP/2 streams 179 into a single HTTP/2 connection. Additionally, all of the XStreams 180 associated with the same RStream form a logical stream group, and are 181 routed to the same endpoint. This enables clients to access 182 different services without initiating new connections,or including 183 routing metadata in every message. As shown in Figure 3, the client 184 can exchange data with three different services (PubSub, RPC, and 185 CDN) using one HTTP/2 connection. 187 +--------+ RStream (5) +---------+ RStream (1) +----------+ 188 | client |>--------------->| proxy |>---------------->| PubSub | 189 +--------+ XStream (7) +---------+ XStream (3) +----------+ 190 v v ^ ^ v v 191 | | | | | | 192 | | RStream (11) | | | | RStream (5) +----------+ 193 | +--------------------+ | | +------------------>| RPC | 194 | XStream (13) | | XStream (7) +----------+ 195 | | | 196 | | | 197 | Stream (21) | | Stream (9) +----------+ 198 +---------------------------+ +--------------------->| CDN | 199 +----------+ 201 Figure 3: Client opens multiple RStreams, XStreams and an HTTP/2 202 stream within one HTTP/2 connection. 204 Reusing one connection for different purposes saves the latency of 205 setting up new connections. This is especially desirable for mobile 206 devices which often have higher latency network connectivity and 207 tighter battery constraints. Multiplexing these services also allows 208 them to share a single transport connection congestion control 209 context. It also opens new optimization opportunities, like 210 prioritizing interactive streams over streams used to fetch static 211 content. It also reduces the number of connections that are adding 212 load to intermediaries and servers in the network. 214 3.4. Recommended Usage 216 RStreams and XStreams are designed for different purposes. RStreams 217 are *RECOMMENDED* for exchanging metadata only, and *SHOULD* be long 218 lived, as once an RStream is closed any routing information it 219 carried is lost. Unless a new RStream is re-established promptly, no 220 new XStreams can be initiated. To keep an RStream open, endpoints 221 *SHOULD NOT* send a HEADERS or DATA frame containing the END_STREAM 222 flag. Implementations might require special logic to prevent 223 RStreams from timing out. For example, refresh the timeouts on 224 RStreams if a new XStream is exchanged. 226 By contrast, XStreams are *RECOMMENDED* for exchanging user data, and 227 *SHOULD* be short lived. In long polling, WebSocket and tunneling 228 solutions, streams have to be kept alive for a long time because 229 servers need those streams for sending data to the client in the 230 future. With this extension, servers are able to initiate new 231 XStreams as long as RStreams are still open and no longer need to 232 keep idle streams around for future use. This allows all parties 233 involved in the connection to keep resource usage to a minimum. 234 Morever, short lived XStreams make graceful shutdown of a connection 235 easier for intermediaries and servers. After exchanging GOAWAY 236 frames, short lived XStreams will naturally drain within a short 237 period of time. 239 3.5. States of RStream and XStream 241 RStreams are regular HTTP/2 streams that follow the stream lifecycle 242 described in [RFC7540], section 5.1. XStreams use the same lifecycle 243 as regular HTTP/2 streams, but have extra dependency on their 244 RStreams. If an RStream is reset, endpoints *MUST* reset the 245 XStreams associated with that RStream. If the RStream is closed, 246 endpoints *SHOULD* allow the existing XStreams to complete normally. 247 The RStream *SHOULD* remain open while communication is ongoing. 248 Endpoints *SHOULD* refresh any timeout on the RStream while its 249 associated XStreams are open. 251 A sender *MUST NOT* initiate new XStreams with an RStream that is in 252 the closed or half closed (remote) state. 254 Endpoints process new XStreams only when the associated RStream is in 255 the open or half closed (local) state. If an endpoint receives an 256 XHEADERS frame specifying an RStream in the closed or half closed 257 (remote) state, it *MUST* respond with a connection error of type 258 ROUTING_STREAM_ERROR. 260 3.6. Negotiating the Extension 262 The extension *SHOULD* be disabled by default. As noted in 263 [RFC7540], section 5.5, HTTP/2 compliant implementations which do not 264 support this extension *MUST* ignore the unknown ENABLE_XHEADERS 265 setting and XHEADERS frame. Endpoints can negotiate the use of this 266 extension through the SETTINGS frame, and once enabled, this 267 extension *MUST NOT* be disabled over the lifetime of the connection. 269 This document introduces another SETTINGS parameter, ENABLE_XHEADERS, 270 which *MUST* have a value of 0 or 1. 272 Once a ENABLE_XHEADERS parameter has been sent with a value of 1, an 273 endpoint *MUST NOT* send the parameter with a value of 0. 275 If an implementation supports the extension, it is *RECOMMENDED* to 276 include the ENABLE_XHEADERS setting in the initial SETTINGS frame, 277 such that the remote endpoint can disover the support at the earliest 278 possible time. 280 An endpoint can send XHEADERS frames immediately upon receiving a 281 SETTINGS frame with ENABLE_XHEADERS=1. An endpoint *MUST NOT* send 282 out XHEADERS before receiving a SETTINGS frame with the 283 ENABLE_XHEADERS=1. If a remote endpoint does not support this 284 extension, the XHEADERS will be ignored, making the header 285 compression context inconsistent between sender and receiver. 287 If an endpoint supports this extension, but receives XHEADERS frames 288 before ENABLE_XHEADERS, it *SHOULD* to respond with a connection 289 error XHEADER_NOT_ENABLED_ERROR. This helps the remote endpoint to 290 implement this extension properly. 292 Intermediaries *SHOULD* send the ENABLE_XHEADERS setting to clients 293 only if intermediaries and their upstream servers support this 294 extension. If an intermediary receives an XStream but discovers the 295 destination endpoint does not support the extension, it *MUST* reset 296 the stream with XHEADER_NOT_ENABLED_ERROR. 298 3.7. Interaction with Standard HTTP/2 Features 300 XStreams are extended HTTP/2 streams, thus all the standard HTTP/2 301 features for streams still apply to XStreams. For example, like 302 streams, XStreams are counted against the concurrent stream limit, 303 defined in [RFC7540], Section 5.1.2. The connection level and stream 304 level flow control principles are still valid for XStreams. However, 305 for the stream priority and dependencies, XStreams have one extra 306 constraint: a XStream can have a dependency on its RStream, or any 307 XStream sharing with the same RStream. Prioritizing the XStreams 308 across different RStream groups does not make sense, because they 309 belong to different services. 311 4. HTTP/2 XHEADERS Frame 313 The XHEADERS frame (type=0xfb) has all the fields and frame header 314 flags defined by HEADERS frame in HEADERS [RFC7540], section 6.2. 315 The XHEADERS frame has one extra field, Routing Stream ID. It is 316 used to open an XStream, and additionally carries a header block 317 fragment. XHEADERS frames can be sent on a stream in the "idle", 318 "open", or "half-closed (remote)" state. 320 Like HEADERS, the CONTINUATION frame (type=0x9) is used to continue a 321 sequence of header block fragments, if the headers do not fit into 322 one XHEADERS frame. 324 4.1. Definition 325 +---------------+ 326 |Pad Length? (8)| 327 +-+-------------+-----------------------------------------------+ 328 |E| Stream Dependency? (31) | 329 +-+-------------+-----------------------------------------------+ 330 | Weight? (8) | 331 +-+-------------+-----------------------------------------------+ 332 |R| Routing Stream ID (31) | 333 +-+-------------+-----------------------------------------------+ 334 | Header Block Fragment (*) ... 335 +---------------------------------------------------------------+ 336 | Padding (*) ... 337 +---------------------------------------------------------------+ 339 Figure 4: XHEADERS Frame Payload 341 The RStream specified in a XHEADERS frame *MUST* be an open stream. 342 The recipient *MUST* respond with a connection error of type 343 ROUTING_STREAM_ERROR PROTOCOL_ERROR, if the specified RStream is 344 missing, is an XStream rather than a regualr HTTP/2 stream, or is 345 closed or half-closed (remote). Otherwise, the states maintained for 346 header compression or flow control may be out of sync. 348 4.2. Examples 350 This section shows HTTP/1.1 request and response messages that are 351 transmitted on an RStream with regualar HEADERS frames, and on an 352 XStream with HTTP/2 XHAEDERS frames. 354 GET /login HTTP/1.1 HEADERS 355 Host: example.org ==> - END_STREAM 356 + END_HEADERS 357 :method = GET 358 :scheme = https 359 :path = /login 360 host = example.org 362 {binary data .... } ==> DATA 363 - END_STREAM 364 {binary data ... } 366 Figure 5: The request message and HEADERS frame on an RStream 368 HTTP/1.1 200 OK HEADERS 369 ==> - END_STREAM 370 + END_HEADERS 371 :status = 200 373 {binary data .... } ==> DATA 374 - END_STREAM 375 {binary data...} 377 Figure 6: The response message and HEADERS frame on an RStream 379 The server initiates an XStream to this client. 381 POST /new_msg HTTP/1.1 XHEADERS 382 RStream_ID = 3 383 Host: example.org ==> - END_STREAM 384 + END_HEADERS 385 :method = POST 386 :scheme = https 387 :path = /new_msg 388 host = example.org 389 {binary data} ==> DATA 390 + END_STREAM 391 {binary data} 393 Figure 7: The request message and XHEADERS frame on an XStream 395 HTTP/1.1 200 OK XHEADERS 396 RStream_ID = 3 397 ==> + END_STREAM 398 + END_HEADERS 399 :status = 200 401 Figure 8: The response message and XHEADERS frame on an XStream 403 5. IANA Considerations 405 This specification adds an entry to the "HTTP/2 Frame Type" registry, 406 the "HTTP/2 Settings" registry, and the "HTTP/2 Error Code" registry, 407 all defined in [RFC7540]. 409 5.1. FRAME TYPE Registry 411 The entry in the following table are registered by this document. 413 +---------------+------+--------------+ 414 | Frame Type | Code | Section | 415 +---------------+------+--------------+ 416 | XHEADERS | 0xfb | | 417 +---------------+------+--------------+ 419 5.2. Settings Registry 421 The entry in the following table are registered by this document. 423 +------------------------+--------+---------------+---------------+ 424 | Name | Code | Initial Value | Specification | 425 +------------------------+--------+---------------+---------------+ 426 | ENABLE_XHEADERS | 0xfbfb | 0 | | 427 +------------------------+--------+---------------+---------------+ 429 5.3. Error Code Registry 431 The entry in the following table are registered by this document. 433 +----------------------+------+-------------------+---------------+ 434 | Name | Code | Description | Specification | 435 +----------------------+------+-------------------+---------------+ 436 | ROUTING_STREAM_ERROR | 0xfb | Routing stream is | | 437 | | | not open | | 438 | XHEADERS_NOT_ | 0xfc | XHEADERS is not | | 439 | ENABLED_ERROR | | enabled yet | | 440 +----------------------+------+-------------------+---------------+ 442 6. Normative References 444 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 445 Requirement Levels", BCP 14, RFC 2119, 446 DOI 10.17487/RFC2119, March 1997, 447 . 449 [RFC6202] Loreto, S., Saint-Andre, P., Salsano, S., and G. Wilkins, 450 "Known Issues and Best Practices for the Use of Long 451 Polling and Streaming in Bidirectional HTTP", RFC 6202, 452 DOI 10.17487/RFC6202, April 2011, 453 . 455 [RFC7540] Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext 456 Transfer Protocol Version 2 (HTTP/2)", RFC 7540, 457 DOI 10.17487/RFC7540, May 2015, 458 . 460 [RFC8441] McManus, P., "Bootstrapping WebSockets with HTTP/2", 461 RFC 8441, DOI 10.17487/RFC8441, September 2018, 462 . 464 Authors' Addresses 466 Guowu Xie 467 Facebook Inc. 469 Email: woo@fb.com 471 Alan Frindell 472 Facebook Inc. 474 Email: afrind@fb.com