Those of you who have used MQTT know that the status in the Network panel is 101 when an MQTT connection is made.
Name | Status | Time |
---|---|---|
mqtt | 101 (Switching Protocols) | Pending |
So what does 101 (Switching Protocols) mean? This article will take you through what 101 interchange protocol is and the protocol upgrade mechanism used by 101 interchange protocol.
- 101 Switching Protocol
- Protocol Upgrade Mechanism
101 Switching Protocol
The 101 switching protocol of HTTP means that the client sends a message to the server containing the Upgrade request header. The server switches the protocol based on the request header sent by the client.
The server will add an Upgrade response header to the response to indicate the protocol to which the server has switched.
In a word, the client tells the server to switch the protocol by adding Upgrade in the request header, and the server adds Upgrade in the response header to indicate the switched protocol.
Even simpler: the client tells the server to switch protocols.
General
Request URL: wss://foo.bar
Request Method: GET
Status Code: 101 Switching Protocols
Copy the code
Request Headers
Connection: Upgrade Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits Sec-WebSocket-Key: xxx Sec-WebSocket-Protocol: mqtt Sec-WebSocket-Version: 13 Upgrade: Websocket // Client tells server to use websocket...Copy the code
Response Headers
connection: Upgrade sec-websocket-accept: FNs9ByuvC +rD75+tj2GMQAzbJms= // server is calculated based on the sec-websocket-key: XXX issued by the client. MQTT Upgrade: Websocket // server tells client that we (client, server) use the WebSocket protocol...Copy the code
What do these request headers mean? Connection, SEC-websocket-extensions, SEC-websocket-key, SEC-websocket-protocol, sec-websocket-version, etc. What about the response header? The SEC – websocket – accept, the SEC – websocket – protocol.
Take a look at the protocol upgrade mechanism below.
Protocol Upgrade Mechanism
The HTTP1.1 version of the protocol has a special mechanism for upgrading an established connection to another protocol, usually through the Upgrade header.
This mechanism is optional and does not force protocol changes. While the implementation supports the new protocol, you may choose not to upgrade. In practice, this mechanism is usually used to bootstrap webSockets to connect.
Note that the HTTP2.0 version explicitly prohibits the use of this mechanism. Only available for HTTP1.1.
Upgrade HTTP/1.1 connections
The client can use the Upgrade header to invite the server to switch to one of the protocols in descending order.
Because Upgrade is a hop-by-hop header, it requires a Connection header. This means that a typical request containing the Upgrade header is:
GET /index.html HTTP/1.1
Host: www.example.com
Connection: upgrade
Upgrade: example/1, foo/2
Copy the code
Other headers are generally protocol-dependent; For example, WebSocket upgrades allow additional headers to configure WebSocket connections and have some security when opened.
If the server decides to upgrade the connection, the upgrade succeeds or fails:
- Upgrade successful: It returns a 101-switching Protocols response status, and the Upgrade header indicates the protocol it switched.
- Upgrade failure: If the server cannot Upgrade the connection, it ignores the Upgrade header and returns a normal response (for example, 200 OK)
Once the server sends the 101 status code, it can immediately start using the new protocol and handshake with other protocols. Once the connection is established, it becomes a bidirectional pipe and requests to initiate escalation can be initiated over the protocol.
General usage of the protocol upgrade mechanism
In what scenarios will the Upgrade header be used? And what are the request headers associated with WebSocket connections?
- Upgrade to WebSocket connection
- The request header associated with the WebSocket connection
- Sec-WebSocket-Extensions
- Sec-WebSocket-Key
- Sec-WebSocket-Protocol
- Sec-WebSocket-Version
- Sec-websocket-accept (read only)
Upgrade to WebSocket connection
The most common scenario for upgrading HTTP connections is WebSockets, usually by upgrading HTTP or HTTPS connections. If you use the WebSocket API to open a connection, or any WebSockets library, most or all of this is already done for you.
For example, setting up a WebSocket connection is as simple as this:
webSocket = new WebSocket("ws://destination.server.ext"."optionalProtocol")
Copy the code
The WebSockek() constructor does all the work internally for the developer to create an HTTP/1.1 connection, handshake, and upgrade.
You can use “WSS ://” to establish a secure WebSocket connection.
If you want to manually set up a WebSocket connection yourself, you’ll need to handle the handshake yourself. After the HTTP/1.1 session is created, you need to add the Upgrade and Connection headers to the request.
Connection: Upgrade
Upgrade: websocket
Copy the code
The request header associated with the WebSocket connection
The following request headers are included in the WebSocket upgrade process. Unlike the Upgrade and Connection headers, these request headers follow
Sec-WebSocket-Extensions
Declare one or more protocol-level WebSocket extensions to tell the server to use. It is possible to use one or more SEC-websocket-extension headers in a request; Put them together and separate them with a semicolon.
Sec-WebSocket-Extensions: extensions
Copy the code
Extensions need to be separated by a semicolon. Need to select from the list of plug-ins.
For example, sec-websocket-extensions: superspeed, colormode; depth=16
Permessage-deflate in our example above is also included.
permessage-deflate | WebSocket Per-Message Deflate | [RFC7692] | None | [RFC7692]
Sec-WebSocket-Key
Provides the server with information about the client’s right to upgrade to a WebSocket. This header can be used when insecure HTTP wants to be upgraded in order to provide some degree of protection against abuse. The key value is generated using an algorithm defined in the WebSocket specification, so this does not guarantee security.
This key is used to place unintentional WebSocket connections or misuse by non-Websocket clients. In essence, this key says: “Yes, I do want to open a WebSocket connection.”
This header will be automatically added by the use of its client, cannot be XMLHttpRequest. SetRequestHeader () to add
Sec-WebSocket-Key: key
Copy the code
Based on this key, the server adds a calculation based on this key to the sec-websocket-Accept header of the response.
Sec-WebSocket-Protocol
This header declares one or more WebSocket protocols you want to use. The request hair is sent to sec-websocket-protocol, and the response header is returned to sec-websocket-protocol.
Sec-WebSocket-Protocol: subprotocols
Copy the code
Subprotocols include the following protocols: www.iana.org/assignments…
In the above example MQTT is among them: the MQTT | MQTT | [MQTT Version 5.0]
Sec-WebSocket-Version
As the request header: Declares the version of the WebSocket protocol used by the client.
Sec-WebSocket-Version: version
Copy the code
Version of the WebSocket protocol used by the server to communicate with the client: www.iana.org/assignments…
The most common one is 13.
As response header: If the server does not support the WebSocket protocol, something like 426 (Upgrade Required) is returned and a list of supported WebSocket versions is returned in the sec-websocket-version header. If not supported, the sec-websocket-version header is not returned.
Sec-WebSocket-Version: supportedVersions
Copy the code
Sec-WebSocket-Accept
The server establishes the response header during the handshake with the client. At most once:
Sec-WebSocket-Accept: hash
Copy the code
If the sec-websocket-key exists, connect the string 258eafa5-e914-47DA-95CA-C5AB0DC85b11 to the string and take the 20-bit hash value of SHA-1. Finally, base64 encoding is performed.
In our example:
Sec-WebSocket-Key: xxx
Sec-WebSocket-Accept: fNs9ByuvC+rD75+tj2GMQAzbJms=
Copy the code
Sec-websocket-accept is generated by sec-websocket-key as follows:
const SecWebSocketKey = "xxx"
const helper = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
const result = SecWebSocketKey + helper
const crypto = require('crypto')
const shasum = crypto.createHash('sha1')
shasum.update(result)
const SecWebSocketAccept = shasum.digest('base64');
console.log(SecWebSocketAccept) // fNs9ByuvC+rD75+tj2GMQAzbJms=
Copy the code
Online demo: www.jdoodle.com/ia/e3G
Now that the key-accept algorithm is clear, can we reverse solve the key through accept? The answer is no. This is because of sha1 encryption.
Cryptographic strong hash functions have two characteristics, one of which is irreversible. Irreversibility means that the original data cannot be reconstructed from its hash, so the key cannot be solved backwards by accept.
References:
Developer.mozilla.org/en-US/docs/… Developer.mozilla.org/en-US/docs/… Stackoverflow.com/questions/6… Nodejs.org/api/buffer…. Stackoverflow.com/questions/1…
The first article in front of the public number: big big front
Strive to be an excellent front-end development engineer!