Features¶
Feature support matrices summarize which implementations support which features.
Both sides¶
|
|
|||
---|---|---|---|---|
Perform the opening handshake |
✅ |
✅ |
✅ |
✅ |
Enforce opening timeout |
✅ |
✅ |
— |
✅ |
Send a message |
✅ |
✅ |
✅ |
✅ |
Broadcast a message |
✅ |
❌ |
— |
✅ |
Receive a message |
✅ |
✅ |
✅ |
✅ |
Iterate over received messages |
✅ |
✅ |
— |
✅ |
Send a fragmented message |
✅ |
✅ |
✅ |
✅ |
Receive a fragmented message frame by frame |
✅ |
✅ |
— |
❌ |
Receive a fragmented message after reassembly |
✅ |
✅ |
— |
✅ |
Force sending a message as Text or Binary |
✅ |
✅ |
— |
❌ |
✅ |
✅ |
— |
❌ |
|
Send a ping |
✅ |
✅ |
✅ |
✅ |
Respond to pings automatically |
✅ |
✅ |
✅ |
✅ |
Send a pong |
✅ |
✅ |
✅ |
✅ |
Keepalive |
✅ |
❌ |
— |
✅ |
Heartbeat |
✅ |
❌ |
— |
✅ |
Measure latency |
✅ |
❌ |
— |
✅ |
Perform the closing handshake |
✅ |
✅ |
✅ |
✅ |
Enforce closing timeout |
✅ |
✅ |
— |
✅ |
Report close codes and reasons from both sides |
✅ |
✅ |
✅ |
❌ |
Compress messages (RFC 7692) |
✅ |
✅ |
✅ |
✅ |
Tune memory usage for compression |
✅ |
✅ |
✅ |
✅ |
Negotiate extensions |
✅ |
✅ |
✅ |
✅ |
Implement custom extensions |
✅ |
✅ |
✅ |
✅ |
Negotiate a subprotocol |
✅ |
✅ |
✅ |
✅ |
Enforce security limits |
✅ |
✅ |
✅ |
✅ |
Log events |
✅ |
✅ |
✅ |
✅ |
Server¶
|
|
|||
---|---|---|---|---|
Listen on a TCP socket |
✅ |
✅ |
— |
✅ |
Listen on a Unix socket |
✅ |
✅ |
— |
✅ |
Listen using a preexisting socket |
✅ |
✅ |
— |
✅ |
Encrypt connection with TLS |
✅ |
✅ |
— |
✅ |
Close server on context exit |
✅ |
✅ |
— |
✅ |
Close connection on handler exit |
✅ |
✅ |
— |
✅ |
Shut down server gracefully |
✅ |
✅ |
— |
✅ |
Check |
✅ |
✅ |
✅ |
✅ |
Customize subprotocol selection |
✅ |
✅ |
✅ |
✅ |
Configure |
✅ |
✅ |
✅ |
✅ |
Alter opening handshake request |
✅ |
✅ |
✅ |
❌ |
Alter opening handshake response |
✅ |
✅ |
✅ |
❌ |
Force an HTTP response |
✅ |
✅ |
✅ |
✅ |
Perform HTTP Basic Authentication |
✅ |
✅ |
❌ |
✅ |
Perform HTTP Digest Authentication |
❌ |
❌ |
❌ |
❌ |
Client¶
|
|
|||
---|---|---|---|---|
Connect to a TCP socket |
✅ |
✅ |
— |
✅ |
Connect to a Unix socket |
✅ |
✅ |
— |
✅ |
Connect using a preexisting socket |
✅ |
✅ |
— |
✅ |
Encrypt connection with TLS |
✅ |
✅ |
— |
✅ |
Close connection on context exit |
✅ |
✅ |
— |
✅ |
Reconnect automatically |
✅ |
❌ |
— |
✅ |
Configure |
✅ |
✅ |
✅ |
✅ |
Configure |
✅ |
✅ |
✅ |
✅ |
Modify opening handshake request |
✅ |
✅ |
✅ |
✅ |
Modify opening handshake response |
✅ |
✅ |
✅ |
❌ |
Connect to non-ASCII IRIs |
✅ |
✅ |
✅ |
✅ |
Follow HTTP redirects |
✅ |
❌ |
— |
✅ |
Perform HTTP Basic Authentication |
✅ |
✅ |
✅ |
✅ |
Perform HTTP Digest Authentication (#784) |
❌ |
❌ |
❌ |
❌ |
Connect via HTTP proxy (#364) |
❌ |
❌ |
— |
❌ |
Connect via SOCKS5 proxy (#475) |
❌ |
❌ |
— |
❌ |
Known limitations¶
There is no way to control compression of outgoing frames on a per-frame basis (#538). If compression is enabled, all frames are compressed.
The server doesn’t check the Host header and doesn’t respond with HTTP 400 Bad Request if it is missing or invalid (#1246).
The client API doesn’t attempt to guarantee that there is no more than one
connection to a given IP address in a CONNECTING state. This behavior is
mandated by RFC 6455, section 4.1. However, connect()
isn’t the right layer for enforcing this constraint. It’s the caller’s
responsibility.
It is possible to send or receive a text message containing invalid UTF-8 with
send(not_utf8_bytes, text=True)
and not_utf8_bytes = recv(decode=False)
respectively. As a side effect of disabling UTF-8 encoding and decoding, these
options also disable UTF-8 validation.