Internet-Draft web-stream: A General Purpose Message Fr June 2026
Yoshino & Zhu Expires 31 December 2026 [Page]
Workgroup:
Network Working Group
Internet-Draft:
draft-yoshino-wish-04
Published:
Intended Status:
Standards Track
Expires:
Authors:
T. Yoshino
W. Zhu
Google, Inc.

web-stream: A General Purpose Message Framing over Byte-Stream Oriented Wire Protocols

Abstract

This document defines web-stream, a general-purpose message framing designed to support message-based communication over any byte-stream oriented L4 or L7 protocols, in particular HTTP as in its standard semantics [RFC9110].

web-stream can be viewed as a binary alternative to the framing defined for the server-sent events (SSE) [SSE]. This was the original goal when the initial version of this proposal was published in 2017.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 31 December 2026.

Table of Contents

1. Background

There have been several attempts to improve message-based streaming communication on the Web.

The server-sent events (SSE) [SSE] realized message-based streaming communication in the server-to-client direction. It introduced a new Web API and a special text-based framing format while using HTTP as the wire protocol.

WebSockets realized native client-server full-duplex message-based communication for the Web by introducing both a new Web API and a new wire protocol (the WebSocket Protocol). While widely deployed, the wire protocol is incompatible with the broad HTTP ecosystem [BidiwebSurvey]. Consequently, intermediaries and frameworks have to be upgraded to understand the wire protocol to support WebSockets.

This Internet-Draft addresses the aforementioned problem space with a solution fully compliant with the standard HTTP semantics, informally referred to as "Web in Strict HTTP" (WiSH).

2. Introduction

web-stream offers a general-purpose message framing over a byte-stream. The framing is compatible with the well-adopted and security-proven base framing of the WebSocket Protocol [RFC6455]. The underlying communication protocols providing the standard HTTP semantics can be HTTP/1.1 [RFC7231], HTTP/2 [RFC7540], HTTP/3 [RFC9114]. The web-stream framing can also be used over any other byte-stream oriented protocols (over TCP or QUIC [QUIC]).

Transport-level features such as multiplexing and session priority are provided by the underlying byte-stream protocol [TransportAbstraction].

HTTP implementations may not allow earlier 2xx responses [RFC7540] or full-duplex communication [FullDuplexHTTP], particularly when HTTP/1.1 is used as the underlying byte-stream protocol. In such cases, parallel HTTP requests can be used to support full-duplex messaging between the client and server. Separately, when HTTP body streaming is unsupported by the Web client [FetchBody] or blocked by intermediaries, multiple short-lived HTTP requests can be used to send messages between the client and server.

web-stream strictly complies with the HTTP semantics. Consequently, while web-stream utilizes the base framing of the WebSocket Protocol, web-stream drops the opening handshake and the closing handshake of the WebSocket Protocol.

3. Conformance Requirements and Terminology

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("MUST", "SHOULD", "MAY", etc.) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent.

In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant.

4. Web-Stream over HTTP

This section describes how to use web-stream over HTTP [RFC9110].

To use web-stream with an HTTP request or response, the content part (i.e. body part) MUST be a sequence of zero or more web-stream frames, as defined in Section 5.

The Content-Type header for an HTTP request or response using web-stream MUST be set to the web-stream media type, application/web-stream, which includes an optional message parameter.

Example:

Content-Type: application/web-stream; message="application/json"

The message parameter specifies the content type of the web-stream message payload.

The standard HTTP semantics should be followed, particularly regarding the choice of HTTP method and headers.

Certain HTTP semantics, such as Cache-Control, may not be applicable when the HTTP body is streamed to the application. These limitations are intrinsic to streaming, not web-stream specifically. It's also possible to use web-stream without application-level streaming, such as sending batched messages over HTTP.

5. Framing

The web-stream framing is designed to be compatible with the base framing protocol of the WebSocket Protocol [RFC6455].

A high-level overview of the framing is provided in the figure below.

   `0                   1                   2                   3`
    `0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1`
   `+-+-+-+-+-------+-+-------------+-------------------------------+`
   `|F|C|0|0|opcode |0|Payload      |Extended payload length        |`
   `|I|M| | |4 bit  | |length       |16 bit if payload length is 126|`
   `|N|P| | |       | |7 bit        |64 bit if payload length is 127|`
   `+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +`
   `|                                                               |`
   `+ - - - - - - - - - - - - - - - +-------------------------------+`
   `|                               |Payload Data                   |`
   `+-------------------------------+ - - - - - - - - - - - - - - - +`
   `|                                                               |`
   `+---------------------------------------------------------------+`

5.1. Payload length

The payload length and extended payload length fields are used to determine the length of the Payload Data field of the frame, following the exact mechanism defined in the WebSocket Protocol.

5.2. Fragmentation

The FIN bit and the continuation frame opcode enable a fragmentation mechanism, which is identical to that of the WebSocket Protocol. One or more continuous frames constitute a web-stream message. The FIN bit indicates that the frame is the final frame of a web-stream message. For the second and following frames of a web-stream message, the opcode field MUST be set to the continuation frame opcode.

The mechanism allows for sending portions of a web-stream message with a large payload before the total size of the message is determined.

5.3. Payload Compression

web-stream defines the CMP bit as the second most significant bit of the first octet of a frame. The CMP bit in the first frame of a message indicates whether that message's payload is compressed. When the message payload is compressed, the CMP bit of the first frame MUST be set to 1; otherwise, it MUST be set to 0. The CMP bit MUST always be set to 0 for all non-first frames. See Section 6 for details of the payload compression.

5.4. Opcode

For the "opcode" field, web-stream uses the following opcodes:

  • %x0 denotes a continuation frame

  • %x1 denotes the first frame of a text message

  • %x2 denotes the first frame of a binary message

  • %x3 denotes the first frame of a metadata message

  • %x9 denotes a ping

  • %xA denotes a pong

Any values not listed above are reserved.

The opcodes for continuation frames, text messages, and binary messages are identical to those specified in the WebSocket Protocol.

web-stream introduces the metadata message opcode (%x3), which is used for exchanging in-stream metadata between the client and server. When the opcode field of the first frame is set to %x3, the message contains metadata. The application-level protocol determines the encoding of the metadata message payload. Support for metadata is optional; web-stream implementations that do not support or consume metadata messages MAY discard them.

We don't expect the WebSocket Protocol to introduce any new opcodes in future.

The WebSocket Protocol's connection close frame opcode (%x8) is ignored for web-stream. The ping (%x9) and pong (%xA) control frames are retained from the WebSocket Protocol. web-stream endpoints MAY alternatively rely on keep-alive mechanisms provided by the underlying transport.

6. Compression over HTTP

6.1. General Guidelines about Compression

For short-lived streaming, the content codings (for HTTP body) MAY be applied in the underlying HTTP layer for web-stream as specified in Section 8.4. Content-Encoding of [RFC9110]. HTTP compression is transparent to the web-stream framing and is generally efficient for short-lived streaming.

For long-lived streaming, Per-message Compression for WebSocket (PMCE) [RFC7692] may provide better performance. Implementations may port PMCE to web-stream as described in the following section.

web-stream compression and HTTP compression SHOULD NOT be enabled simultaneously to avoid redundant compression.

6.2. web-stream Compression

[RFC7692] defined a general framework on how to implement message-oriented compression for [RFC6455] using its extension framework. This is named Per-message Compression for WebSocket (PMCE). The web-stream compression is an adaptation (port) of PMCE for web-stream.

6.2.1. Negotiation

Enabling the web-stream compression requires the participating endpoints to perform the extension negotiation defined in [RFC7692] through HTTP request and response headers. The name of the header MUST be Web-Stream-Extensions instead of Sec-WebSocket-Extensions.

Example negotiation:

The client includes the following header in HTTP request to offer use of a compression that is equivalent to the permessage-deflate PMCE for the WebSocket Protocol.

Web-Stream-Extensions: permessage-deflate

Some parameters can be added to the permessage-deflate entry as follows:

Web-Stream-Extensions: permessage-deflate; client_max_window_bits=10

The server includes the following header in HTTP response to accept use of the compression as follows:

Web-Stream-Extensions: permessage-deflate

6.2.2. Framing

web-stream compression uses the second significant bit of the first octet of a frame to indicate whether the message payload is compressed. This bit is referred to as the "Per-Message Compressed" bit in the PMCE specification. In the web-stream framing, this bit is named the CMP bit.

When the CMP bit is set in the first frame of a message, the message payload MUST be compressed.

6.2.3. Compression Methods other than DEFLATE

While DEFLATE is the only compression algorithm supported by the WebSocket Protocol, web-stream may support additional compression algorithms, such as Zstandard. A separate Internet-Draft will be published in the future to specify these web-stream compression methods.

7. UTF-8 Vallidation

The WebSocket Protocol [RFC6455] requires the endpoints to _Fail the WebSocket Connection_ when they encounter an invalid UTF-8 byte sequence in a text message. Consequently, [RFC6455] server frameworks typically check for UTF-8 validity.

While the contents of web-stream text messages also MUST be a valid UTF-8 sequence, web-stream endpoints are not REQUIRED to perform UTF-8 validation. This design choice provides greater flexibility to server implementations, which may, for example, choose to perform UTF-8 validation within a JSON parser.

8. Acknowledgements

The authors gratefully acknowledge the feedback received on the original version of this draft from the IETF BiDirectional or Server-Initiated HTTP (hybi) Working Group and the IETF HTTP Working Group during 2016-2017.

9. References

9.1. Normative References

[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC6455]
Fette, I. and A. Melnikov, "The WebSocket Protocol", RFC 6455, DOI 10.17487/RFC6455, , <https://www.rfc-editor.org/info/rfc6455>.
[RFC7231]
Fielding, R., Ed. and J. Reschke, Ed., "Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content", RFC 7231, DOI 10.17487/RFC7231, , <https://www.rfc-editor.org/info/rfc7231>.
[RFC7540]
Belshe, M., Peon, R., and M. Thomson, Ed., "Hypertext Transfer Protocol Version 2 (HTTP/2)", RFC 7540, DOI 10.17487/RFC7540, , <https://www.rfc-editor.org/info/rfc7540>.
[RFC7692]
Yoshino, T., "Compression Extensions for WebSocket", RFC 7692, DOI 10.17487/RFC7692, , <https://www.rfc-editor.org/info/rfc7692>.
[RFC9110]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke, Ed., "HTTP Semantics", STD 97, RFC 9110, DOI 10.17487/RFC9110, , <https://www.rfc-editor.org/info/rfc9110>.
[RFC9114]
Bishop, M., Ed., "HTTP/3", RFC 9114, DOI 10.17487/RFC9114, , <https://www.rfc-editor.org/info/rfc9114>.

9.2. Informative References

[FetchBody]
WHATWG, "Fetch Standard - body stream", n.d., <https://fetch.spec.whatwg.org/#concept-body-stream>.
[QUIC]
Iyengar, J. and M. Thomson, "QUIC: A UDP-Based Multiplexed and Secure Transport", RFC 9000, , <https://www.rfc-editor.org/rfc/rfc9000>.
[SSE]
WHATWG, "HTML Living Standard - Server-sent events", , <https://html.spec.whatwg.org/multipage/comms.html#server-sent-events>.
[FullDuplexHTTP]
Zhu, W. and M. Jennings, "Implications of Full-Duplex HTTP", , <https://datatracker.ietf.org/doc/html/draft-zhu-http-fullduplex>.
[BidiwebSurvey]
Yoshino, T. and W. Zhu, "Non Request-Response Communication over the Web, and What's Missing", , <https://github.com/bidiweb/bidiweb-semantics/blob/master/SurveyOfProtocolGaps.md>.
[TransportAbstraction]
Zhu, W., "http-transport-abstraction", , <https://github.com/bidiweb/http-transport-abstraction>.
[WebStreamReferecenImplementation]
"web-stream reference implementation in C++", n.d., <https://github.com/bidiweb/web-stream-reference-implementation>.

Authors' Addresses

Takeshi Yoshino
Wenbo Zhu
Google, Inc.