From c69e36924e1849fdc9b7fc49a3f4c550efa3468a Mon Sep 17 00:00:00 2001 From: Hamish Willee Date: Mon, 9 Sep 2024 11:22:22 +1000 Subject: [PATCH] HTTP Sec-WebSocket-* headers (#35606) * Sec-WebSocket-Protocol docs * Sec-WebSocket-Protocol fix * Sec-WebSocket-Version - add docs * Sec-WebSocket-Extensions - add docs * Cross link the headers * Update files/en-us/web/api/websocket/websocket/index.md Co-authored-by: Joshua Chen * Update files/en-us/web/http/headers/sec-websocket-protocol/index.md Co-authored-by: Joshua Chen * Apply suggestions from code review Co-authored-by: Brian Thomas Smith * Apply suggestions from code review * Update files/en-us/web/api/websockets_api/index.md Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update files/en-us/web/api/websockets_api/index.md Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Update files/en-us/web/api/websockets_api/index.md --------- Co-authored-by: Joshua Chen Co-authored-by: Brian Thomas Smith Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .../en-us/web/api/websocket/protocol/index.md | 9 +- .../web/api/websocket/websocket/index.md | 14 ++- files/en-us/web/api/websockets_api/index.md | 21 ++++ .../writing_websocket_servers/index.md | 2 +- files/en-us/web/http/headers/index.md | 15 ++- .../headers/sec-websocket-extensions/index.md | 106 ++++++++++++++++++ .../headers/sec-websocket-protocol/index.md | 103 +++++++++++++++++ .../headers/sec-websocket-version/index.md | 93 +++++++++++++++ 8 files changed, 351 insertions(+), 12 deletions(-) create mode 100644 files/en-us/web/http/headers/sec-websocket-extensions/index.md create mode 100644 files/en-us/web/http/headers/sec-websocket-protocol/index.md create mode 100644 files/en-us/web/http/headers/sec-websocket-version/index.md diff --git a/files/en-us/web/api/websocket/protocol/index.md b/files/en-us/web/api/websocket/protocol/index.md index 959ce777f1d0308..766650be131e57e 100644 --- a/files/en-us/web/api/websocket/protocol/index.md +++ b/files/en-us/web/api/websocket/protocol/index.md @@ -8,10 +8,7 @@ browser-compat: api.WebSocket.protocol {{APIRef("WebSockets API")}} -The **`WebSocket.protocol`** read-only property returns the -name of the sub-protocol the server selected; this will be one of the strings specified -in the `protocols` parameter when creating the {{domxref("WebSocket")}} -object, or the empty string if no connection is established. +The **`WebSocket.protocol`** read-only property returns the name of the [sub-protocol](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#subprotocols) the server selected; this will be one of the strings specified in the [`protocols`](/en-US/docs/Web/API/WebSocket/WebSocket#protocols) parameter when creating the {{domxref("WebSocket")}} object, or the empty string if no connection is established. ## Value @@ -24,3 +21,7 @@ A string. ## Browser compatibility {{Compat}} + +## See also + +- {{httpheader("Sec-WebSocket-Protocol")}} diff --git a/files/en-us/web/api/websocket/websocket/index.md b/files/en-us/web/api/websocket/websocket/index.md index a5db8f1d9fbe28c..a34aad77cb92bbb 100644 --- a/files/en-us/web/api/websocket/websocket/index.md +++ b/files/en-us/web/api/websocket/websocket/index.md @@ -22,19 +22,23 @@ new WebSocket(url, protocols) - `url` - : The URL of the target WebSocket server to connect to. - The URL must use one of the following schemes: `ws`, `wss`, `http`, or `https`, and cannot include a [URL fragment](/en-US/docs/Web/HTTP/Basics_of_HTTP/Identifying_resources_on_the_Web#fragment). + The URL must use one of the following schemes: `ws`, `wss`, `http`, or `https`, and cannot include a [URL fragment](/en-US/docs/Web/URI/Fragment). If a relative URL is provided, it is relative to the base URL of the calling script. - `protocols` {{optional_inline}} - - : A single string or an array of strings representing the sub-protocol(s) that the client would like to use. + - : A single string or an array of strings representing the [sub-protocol(s)](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#subprotocols) that the client would like to use, in order of preference. If it is omitted, an empty array is used by default, i.e. `[]`. A single server can implement multiple WebSocket sub-protocols, and handle different types of interactions depending on the specified value. + Note however that only one sub-protocol can be selected per connection. + The allowed values are those that can be specified in the {{httpheader("Sec-WebSocket-Protocol")}} HTTP header. + These are values selected from the [IANA WebSocket Subprotocol Name Registry](https://www.iana.org/assignments/websocket/websocket.xml#subprotocol-name), such as `soap`, `wamp`, `ship` and so on, or may be a custom name jointly understood by the client and the server. - Note that the connection is not established until the sub-protocol is negotiated with the server. - The selected protocol can then be read from {{domxref("WebSocket.protocol")}}. + > [!NOTE] + > The connection is not established until the sub-protocol is negotiated with the server. + > The selected protocol can then be read from {{domxref("WebSocket.protocol")}}: it will be the empty string if a connection cannot be established. ### Exceptions @@ -44,7 +48,7 @@ new WebSocket(url, protocols) - parsing of [`url`](#url) fails - [`url`](#url) has a scheme other than `ws`, `wss`, `http`, or `https` - - [`url`](#url) has a [fragment](/en-US/docs/Web/URI#fragment) + - [`url`](#url) has a [fragment](/en-US/docs/Web/URI/Fragment) - any of the values in [`protocols`](#protocols) occur more than once, or otherwise fail to match the requirements for elements that comprise the value of [`Sec-WebSocket-Protocol`](/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism#sec-websocket-protocol) fields as defined by the WebSocket Protocol specification ## Examples diff --git a/files/en-us/web/api/websockets_api/index.md b/files/en-us/web/api/websockets_api/index.md index e74539a819187ac..4417e6be6fbdd0d 100644 --- a/files/en-us/web/api/websockets_api/index.md +++ b/files/en-us/web/api/websockets_api/index.md @@ -21,6 +21,27 @@ The **WebSocket API** is an advanced technology that makes it possible to open a - [`MessageEvent`](/en-US/docs/Web/API/MessageEvent) - : The event sent by the WebSocket object when a message is received from the server. +## Related HTTP headers + +The HTTP headers are used in the [WebSocket handshake](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#the_websocket_handshake): + +- {{HTTPHeader("Sec-WebSocket-Key")}} + - : An HTTP request header that contains a nonce from the client. + This is used in the [WebSocket opening handshake](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#the_websocket_handshake) to verify that the client explicitly intends to open a WebSocket. + It is added automatically by the browser. +- {{HTTPHeader("Sec-WebSocket-Accept")}} + - : An HTTP {{glossary("response header")}} used in the _WebSocket opening handshake_ to indicate that the server is willing to upgrade to a WebSocket connection. + The value in the directive is calculated from the value of `Sec-WebSocket-Key` in the corresponding request. +- {{HTTPHeader("Sec-WebSocket-Version")}} + - : An HTTP header that in requests indicates the version of the WebSocket protocol understood by the client. + In responses, it is sent only if the requested protocol version is not supported by the server, and lists the versions that the server supports. +- {{HTTPHeader("Sec-WebSocket-Protocol")}} + - : An HTTP header that in requests indicates the sub-protocols supported by the client in preferred order. + In responses, it indicates the the sub-protocol selected by the server from the client's preferences. +- {{HTTPHeader("Sec-WebSocket-Extensions")}} + - : An HTTP header that in requests indicates the WebSocket extensions supported by the client in preferred order. + In responses, it indicates the extension selected by the server from the client's preferences. + ## Guides - [Writing WebSocket client applications](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications) diff --git a/files/en-us/web/api/websockets_api/writing_websocket_servers/index.md b/files/en-us/web/api/websockets_api/writing_websocket_servers/index.md index f6189d7b90d0690..f6c6c3e29162bb2 100644 --- a/files/en-us/web/api/websockets_api/writing_websocket_servers/index.md +++ b/files/en-us/web/api/websockets_api/writing_websocket_servers/index.md @@ -222,7 +222,7 @@ Sec-WebSocket-Protocol: wamp Now the server must pick one of the protocols that the client suggested and it supports. If there is more than one, send the first one the client sent. Imagine our server can use both `soap` and `wamp`. Then, in the response handshake, it sends: -```bash +```http Sec-WebSocket-Protocol: soap ``` diff --git a/files/en-us/web/http/headers/index.md b/files/en-us/web/http/headers/index.md index ebb13177dd40da4..8d65f60dfbd47c1 100644 --- a/files/en-us/web/http/headers/index.md +++ b/files/en-us/web/http/headers/index.md @@ -292,10 +292,21 @@ The following request headers are not _strictly_ "fetch metadata request headers ## WebSockets +Headers used by the [WebSockets API](/en-US/docs/Web/API/WebSockets_API) in the [WebSocket handshake](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#the_websocket_handshake): + - {{HTTPHeader("Sec-WebSocket-Accept")}} - - : Sent from server to client and indicates that the server is willing to initiate a WebSocket connection. + - : Response header that indicates that the server is willing to upgrade to a WebSocket connection. +- {{HTTPHeader("Sec-WebSocket-Extensions")}} + - : In requests, this header indicates the WebSocket extensions supported by the client in preferred order. + In responses, it indicates the extension selected by the server from the client's preferences. - {{HTTPHeader("Sec-WebSocket-Key")}} - - : Sent from client to server to confirm that it "really wants" to request that an HTTP client is upgraded to become a WebSocket. + - : Request header containing a key that verifies that the client explicitly intends to open a `WebSocket`. +- {{HTTPHeader("Sec-WebSocket-Protocol")}} + - : In requests, this header indicates the sub-protocols supported by the client in preferred order. + In responses, it indicates the the sub-protocol selected by the server from the client's preferences. +- {{HTTPHeader("Sec-WebSocket-Version")}} + - : In requests, this header indicates the version of the WebSocket protocol used by the client. + In responses, it is sent only if the requested protocol version is not supported by the server, and lists the versions that the server supports. ## Other diff --git a/files/en-us/web/http/headers/sec-websocket-extensions/index.md b/files/en-us/web/http/headers/sec-websocket-extensions/index.md new file mode 100644 index 000000000000000..6274ae57bc10fea --- /dev/null +++ b/files/en-us/web/http/headers/sec-websocket-extensions/index.md @@ -0,0 +1,106 @@ +--- +title: Sec-WebSocket-Extensions +slug: Web/HTTP/Headers/Sec-WebSocket-Extensions +page-type: http-header +browser-compat: http.headers.Sec-WebSocket-Extensions +spec-urls: https://datatracker.ietf.org/doc/html/rfc6455#section-11.3.2 +--- + +{{HTTPSidebar}} + +The **Sec-WebSocket-Extensions** HTTP {{glossary("request header", "request")}} and {{glossary("response header")}} is used in the [WebSocket](/en-US/docs/Web/API/WebSockets_API) opening [handshake](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#the_websocket_handshake) to negotiate a protocol extension used by the client and server. + +In a request the header specifies one or more extensions that the web application would like to use, in order of preference. +These can be added as in multiple headers, or as comma separate values added to a single header. + +In a response the header can only appear once, where it specifies the extension selected by the server from the client's preferences. +This value must be the first extension that the server supports from the list provided in the request header. + +The request header is automatically added by the browser based on its own capabilities, and does not depend on parameters passed to the constructor when the `WebSocket` is created. + + + + + + + + + + + + +
Header type{{Glossary("Request header")}}, {{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}yes
+ +## Syntax + +Request + +```http +Sec-WebSocket-Extensions: +``` + +Response + +```http +Sec-WebSocket-Extensions: +``` + +## Directives + +- `` + - : A comma-separated list of extensions to request (or for the server to agree to support). + These should be selected from the [IANA WebSocket Extension Name Registry](https://www.iana.org/assignments/websocket/websocket.xml#extension-name). + Extensions which take parameters delineate them with semicolons. + +## Examples + +The HTTP request below shows the opening handshake where a client supports the `permessage-deflate` and `client_max_window_bits` extensions. + +```http +GET /chat HTTP/1.1 +Host: example.com:8000 +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Sec-WebSocket-Version: 13 +Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits +``` + +The request below with separate headers for each extension is equivalent: + +```http +GET /chat HTTP/1.1 +Host: example.com:8000 +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Sec-WebSocket-Version: 13 +Sec-WebSocket-Extensions: permessage-deflate +Sec-WebSocket-Extensions: client_max_window_bits +``` + +The response below might be sent from a server to indicate that it will support the `permessage-deflate` extension: + +```http +HTTP/1.1 101 Switching Protocols +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= +Sec-WebSocket-Extensions: permessage-deflate +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{HTTPHeader("Sec-WebSocket-Accept")}} +- {{HTTPHeader("Sec-WebSocket-Key")}} +- {{HTTPHeader("Sec-WebSocket-Version")}} +- {{HTTPHeader("Sec-WebSocket-Protocol")}} +- [The WebSocket handshake](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#the_websocket_handshake) and [Subprotocols](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#subprotocols) in _Writing WebSocket servers_ diff --git a/files/en-us/web/http/headers/sec-websocket-protocol/index.md b/files/en-us/web/http/headers/sec-websocket-protocol/index.md new file mode 100644 index 000000000000000..59ab9e025cd6007 --- /dev/null +++ b/files/en-us/web/http/headers/sec-websocket-protocol/index.md @@ -0,0 +1,103 @@ +--- +title: Sec-WebSocket-Protocol +slug: Web/HTTP/Headers/Sec-WebSocket-Protocol +page-type: http-header +browser-compat: http.headers.Sec-WebSocket-Protocol +spec-urls: https://datatracker.ietf.org/doc/html/rfc6455#section-11.3.4 +--- + +{{HTTPSidebar}} + +The **`Sec-WebSocket-Protocol`** HTTP {{glossary("request header", "request")}} and {{glossary("response header")}} is used in the [WebSocket](/en-US/docs/Web/API/WebSockets_API) opening [handshake](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#the_websocket_handshake) to negotiate a [sub-protocol](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#subprotocols) to use in the communication. +This can be a well understood protocol, such as SOAP or WAMP, or a custom protocol understood by the client and server. + +In a request the header specifies one or more WebSocket sub-protocols that the web application would like to use, in order of preference. +These can be added as protocol values in multiple headers, or as comma separate values added to a single header. + +In a response it specifies the sub-protocol selected by the server. +This must be the first sub-protocol that the server supports from the list provided in the request header. + +The request header is automatically added and populated by the browser using values specified by the application in the [`protocols`](/en-US/docs/Web/API/WebSocket/WebSocket#protocols) argument to the `WebSocket()`. +The sub-protocol selected by the server is made available to the web application in {{domxref("WebSocket.protocol")}}. + + + + + + + + + + + + +
Header type{{Glossary("Request header")}}, {{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}yes
+ +## Syntax + +Request: + +```http +Sec-WebSocket-Protocol: +``` + +Response: + +```http +Sec-WebSocket-Protocol: +``` + +## Directives + +- `` + - : A comma-separated list of sub-protocol names, in the order of preference. + The sub-protocols may be selected from the [IANA WebSocket Subprotocol Name Registry](https://www.iana.org/assignments/websocket/websocket.xml#subprotocol-name), or may be a custom name jointly understood by the client and the server. + +## Examples + +The sub-protocol is specified in the original WebSocket [handshake request](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#the_websocket_handshake). +The request below shows that the client prefers `soap`, but also supports `wamp`. + +```http +GET /chat HTTP/1.1 +Host: example.com:8000 +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Sec-WebSocket-Version: 13 +Sec-WebSocket-Protocol: soap, wamp +``` + +Specifying the protocols like this has the same effect: + +```http +Sec-WebSocket-Protocol: soap +Sec-WebSocket-Protocol: wamp +``` + +The response from the server will include the `Sec-WebSocket-Protocol` header, selecting the first sub-protocol that it supports from the client's preferences. +Below that is shown as `soap`: + +```http +HTTP/1.1 101 Switching Protocols +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= +Sec-WebSocket-Protocol: soap +``` + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{HTTPHeader("Sec-WebSocket-Accept")}} +- {{HTTPHeader("Sec-WebSocket-Key")}} +- {{HTTPHeader("Sec-WebSocket-Version")}} +- {{HTTPHeader("Sec-WebSocket-Extensions")}} +- [The WebSocket handshake](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#the_websocket_handshake) and [Subprotocols](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#subprotocols) in _Writing WebSocket servers_ diff --git a/files/en-us/web/http/headers/sec-websocket-version/index.md b/files/en-us/web/http/headers/sec-websocket-version/index.md new file mode 100644 index 000000000000000..af38edf4da19869 --- /dev/null +++ b/files/en-us/web/http/headers/sec-websocket-version/index.md @@ -0,0 +1,93 @@ +--- +title: Sec-WebSocket-Version +slug: Web/HTTP/Headers/Sec-WebSocket-Version +page-type: http-header +browser-compat: http.headers.Sec-WebSocket-Version +spec-urls: https://datatracker.ietf.org/doc/html/rfc6455#section-11.3.5 +--- + +{{HTTPSidebar}} + +The **Sec-WebSocket-Version** HTTP {{glossary("request header", "request")}} and {{glossary("response header")}} is used in the [WebSocket](/en-US/docs/Web/API/WebSockets_API) opening [handshake](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#the_websocket_handshake) to indicate the WebSocket protocol supported by the client, and the protocol versions supported by the server if it does _not_ support the version specified in the request. + +The header can only appear once in a request, and specifies the WebSocket version that web application is using. +The current version of the protocol at time of writing is 13. +The header is automatically added to requests by user agents when a {{domxref("WebSocket")}} connection is established. + +The server uses the version to determine if it can understand the protocol. +If the server doesn't support the version, or any header in the handshake is not understood or has an incorrect value, the server should send a response with status {{httpstatus("400", "400 Bad Request")}} and immediately close the socket. +It should also include `Sec-WebSocket-Version` in the `400` response, listing the versions that it does support. +The versions can be specified in individual headers, or as comma-separate values in a single header. + +The header should not be sent in responses if the server understands the version specified by the client. + + + + + + + + + + + + +
Header type{{Glossary("Response header")}}
{{Glossary("Forbidden header name")}}yes
+ +## Syntax + +Request + +```http +Sec-WebSocket-Version: +``` + +Response (on error only): + +```http +Sec-WebSocket-Version: +``` + +## Directives + +- `` + + - : The WebSocket protocol version the client wishes to use when communicating with the server. + This number should be the most recent version possible listed in the [IANA WebSocket Version Number Registry](https://www.iana.org/assignments/websocket/websocket.xml#version-number). + The most recent final version of the WebSocket protocol is version 13. + +- `` + - : On error, a comma-delineated list of the WebSocket protocol versions supported by the server. + The header is not sent in responses if `` is supported. + +## Examples + +The version supported by the client is specified in the original `WebSocket` [handshake request](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#the_websocket_handshake). +For the current protocol, the version is "13", as shown below. + +```http +GET /chat HTTP/1.1 +Host: example.com:8000 +Upgrade: websocket +Connection: Upgrade +Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== +Sec-WebSocket-Version: 13 +``` + +If the server supports version 13 of the protocol, then `Sec-WebSocket-Version` will not appear in the response. + +## Specifications + +{{Specifications}} + +## Browser compatibility + +{{Compat}} + +## See also + +- {{HTTPHeader("Sec-WebSocket-Accept")}} +- {{HTTPHeader("Sec-WebSocket-Key")}} +- {{HTTPHeader("Sec-WebSocket-Protocol")}} +- {{HTTPHeader("Sec-WebSocket-Extensions")}} +- [The WebSocket handshake](/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_servers#the_websocket_handshake) in _Writing WebSocket servers_