Features#

Feature support matrices summarize which implementations support which features.

Both sides#

asyncio

threading

Sans-I/O

Perform the opening handshake

✅

✅

✅

Send a message

✅

✅

✅

Receive a message

✅

✅

✅

Iterate over received messages

✅

✅

❌

Send a fragmented message

✅

✅

✅

Receive a fragmented message after reassembly

✅

✅

❌

Receive a fragmented message frame by frame (#479)

❌

✅

✅

Send a ping

✅

✅

✅

Respond to pings automatically

✅

✅

✅

Send a pong

✅

✅

✅

Perform the closing handshake

✅

✅

✅

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

✅

✅

✅

Enforce opening timeout

✅

✅

—

Enforce closing timeout

✅

✅

—

Keepalive

✅

❌

—

Heartbeat

✅

❌

—

Server#

asyncio

threading

Sans-I/O

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 Origin header

✅

✅

✅

Customize subprotocol selection

✅

✅

✅

Configure Server header

✅

✅

✅

Alter opening handshake request

❌

✅

✅

Alter opening handshake response

❌

✅

✅

Perform HTTP Basic Authentication

✅

❌

❌

Perform HTTP Digest Authentication

❌

❌

❌

Force HTTP response

✅

✅

✅

Client#

asyncio

threading

Sans-I/O

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 Origin header

✅

✅

✅

Configure User-Agent header

✅

✅

✅

Alter opening handshake request

✅

✅

✅

Connect to non-ASCII IRIs

✅

✅

✅

Perform HTTP Basic Authentication

✅

✅

✅

Perform HTTP Digest Authentication (#784)

❌

❌

❌

Follow HTTP redirects

✅

❌

—

Connect via a HTTP proxy (#364)

❌

❌

—

Connect via a 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 respond with a 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. However, connect() isn’t the right layer for enforcing this constraint. It’s the caller’s responsibility.