websocket

最後更新: 2018-08-16

介紹

 

WebSocket is a protocol providing full-duplex communication channels over a single TCP connection.

The WebSocket Protocol is an independent TCP-based protocol.

Its only relationship to HTTP is that its handshake is interpreted by HTTP servers as an Upgrade request.

The WebSocket URL requires the client to "upgrade" to a WebSocket connection; it won't handle plain HTTP "GET".

Once the connection is established, communication switches to a bidirectional binary protocol which doesn't conform to the HTTP protocol.

The data is minimally framed, with a small header followed by payload.

WebSocket enables streams of messages on top of TCP.

TCP alone deals with streams of bytes with no inherent concept of a message.

 


Header

 

Upgrade request

First, a client requests a WebSocket connection by using the GET / POST

* 需要在 HTTP/1.1 進行, 1.0 是不被支援的

# HTTP Header
Upgrade: WebSocket
Connection: Upgrade headers
Origin: https://datahunter.org
...

Server response header:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
...

or

# server refuses to perform the request using the current protocol

426 Upgrade Required

Upgrade header

The handshake resembles HTTP in allowing servers to handle HTTP connections as well as WebSocket connections on the same port.

Sec-WebSocket-Key

The client sends a Sec-WebSocket-Key header containing base64-encoded random bytes(16 bytes),

and the server replies with a hash of the key in the Sec-WebSocket-Accept header.

---

This is intended to prevent a caching proxy from re-sending a previous WebSocket conversation,

and does not provide any authentication, privacy or integrity.

---

i.e.

echo -n 1234567890123456 | base64

Origin

"Origin" header during the connection establishment process on the server side (against the expected origins)

to avoid Cross-Site WebSocket Hijacking attacks

Origin: <scheme> "://" <hostname> [ ":" <port> ]

URI schemes

  • ws:    # http
  • wss:   # https

Test with Tools

test with chrome

F12 -> Console

new WebSocket("wss://mydomain")

test with curl

#!/bin/bash

host=mydomain
port=8443
scheme=https

#### Code ####
url="$scheme://$host:$port"

curl --include --no-buffer --silent --max-time 3 \
    --header "Connection: Upgrade" \
    --header "Upgrade: websocket" \
    --header "Host: $host:$port" \
    --header "Origin: $url" \
    --header "Sec-WebSocket-Version: 13" \
    --header "Sec-WebSocket-Key: 16—bytes_base64==" \
    $url | grep X-Powered-By

if [ $? -ne 0 ]; then
    echo "Error"
else
    echo "Ok"
fi

 


Server Setting

 

nginx setting

https://datahunter.org/nginx_websocket

 


Doc

 

https://en.wikipedia.org/wiki/WebSocket#Protocol_handshake

 


 

Creative Commons license icon Creative Commons license icon