HTTP Upgrade using REST in NodeJS (Practical Example)

Subhajit Dutta
3 min readMar 24, 2022

First thing, What is HTTP Upgrade

HTTP Upgrade feature can be used to upgrade an already established client/server connection to a different protocol (must be over the same transport protocol). It was introduced in HTTP/1.1. Check the IETF doc.

Using this method one can upgrade the existing HTTP connection to HTTP 2.0 or HTTPS or even a bi-directional connection. ( Websocket ).

### This feature has been deprecated in HTTP 2.0 versions.

How it works

If a client wants to upgrade the underlying HTTP protocol, it starts the initial handshake by sending The Upgrade header field in the request as per RFC 2616.

The Upgrade header field only applies to the immediate connection and as it works hop-to-hop, it also needs to be listed in the Connection header.

A typical HTTP upgrade request looks like this…

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

If the server agrees on the upgrade, then it sends back a 101 Switching Protocol response. If the server does not agree to the upgrade, then it sends back a regular response ( Eg. 200 / 400 ). Right after sending the 101 status code, the server can begin speaking the new protocol. As soon as the upgrade response is complete, the connection becomes a two-way pipe.

A typical server response looks like this…

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

A practical example

In this session, we will write a Websocket upgrade with a typical REST API and I will show you, from scratch, how to do it.

First thing, a little intro on Websocket(Skip if you know)

A WebSocket is a persistent connection between a client and a server. WebSockets provide a bidirectional, full-duplex communications channel that operates over HTTP through a single TCP/IP socket connection. Check this IETF doc.

It is a layer 7 protocol of the OSI Model and works under TCP at layer 4.

Enough talks, let's get started…

Client-Side initiatives…

<script>
webSocket = new WebSocket("ws://0.0.0.0:4000/sock-test");
</script>

Or Using Fetch API below is the request pattern

Sec-WebSocket-Version: 13
Sec-WebSocket-Key: kfp9XPVd4Xs5kktlrU6/0Q==
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Host: 0.0.0.0:4000

Sec-WebSocket-Key
Provides information to the server which is needed in order to confirm that the client is entitled to request an upgrade to WebSocket.

Sec-WebSocket-Extensions
Specifies one or more protocol-level WebSocket extensions to ask the server to use. Using more than one Sec-WebSocket-Extension header in a request is permitted.

Server-Side (I have written it in Fastify framework)

fastify.get('/sock-test', async (request, response)=>{
let magic_string = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
let websocket_key = request.headers["sec-websocket-key"];
let concat_string = websocket_key + magic_string
var shasum = crypto.createHash('sha1')
shasum.update(concat_string)
let encrypted_data = shasum.digest('base64')
console.log(encrypted_data)
response
.code(101)
.headers({
'Upgrade': 'websocket',
'Connection': 'Upgrade',
'Sec-WebSocket-Accept': encrypted_data,
'Sec-WebSocket-Version':13
})
.send("ok")
});

Sec-WebSocket-Version
A comma-delineated list of the WebSocket protocol versions supported by the server.

Sec-WebSocket-Accept (Important)
The server takes the value of the Sec-WebSocket-Key sent in the handshake request, appends 258EAFA5-E914–47DA-95CA-C5AB0DC85B11 (Magic String), takes SHA-1 of the new value, and is then base64 encoded, resulting in a 20-byte value. (Don't use HEXDigest).

In Chrome it looks like this

Typical WebSocket example in chrome

Give me a thumbs up if you can implement it yourself. If you have any questions, please write them in the comment section.

Additional Reads

--

--