features.rst (10470B)
1 Features 2 ======== 3 4 .. currentmodule:: websockets 5 6 Feature support matrices summarize which implementations support which features. 7 8 .. raw:: html 9 10 <style> 11 .support-matrix-table { width: 100%; } 12 .support-matrix-table th:first-child { text-align: left; } 13 .support-matrix-table th:not(:first-child) { text-align: center; width: 15%; } 14 .support-matrix-table td:not(:first-child) { text-align: center; } 15 </style> 16 17 .. |aio| replace:: :mod:`asyncio` 18 .. |sync| replace:: :mod:`threading` 19 .. |sans| replace:: `Sans-I/O`_ 20 .. _Sans-I/O: https://sans-io.readthedocs.io/ 21 22 Both sides 23 ---------- 24 25 .. table:: 26 :class: support-matrix-table 27 28 +------------------------------------+--------+--------+--------+ 29 | | |aio| | |sync| | |sans| | 30 +====================================+========+========+========+ 31 | Perform the opening handshake | ✅ | ✅ | ✅ | 32 +------------------------------------+--------+--------+--------+ 33 | Send a message | ✅ | ✅ | ✅ | 34 +------------------------------------+--------+--------+--------+ 35 | Receive a message | ✅ | ✅ | ✅ | 36 +------------------------------------+--------+--------+--------+ 37 | Iterate over received messages | ✅ | ✅ | ❌ | 38 +------------------------------------+--------+--------+--------+ 39 | Send a fragmented message | ✅ | ✅ | ✅ | 40 +------------------------------------+--------+--------+--------+ 41 | Receive a fragmented message after | ✅ | ✅ | ❌ | 42 | reassembly | | | | 43 +------------------------------------+--------+--------+--------+ 44 | Receive a fragmented message frame | ❌ | ✅ | ✅ | 45 | by frame (`#479`_) | | | | 46 +------------------------------------+--------+--------+--------+ 47 | Send a ping | ✅ | ✅ | ✅ | 48 +------------------------------------+--------+--------+--------+ 49 | Respond to pings automatically | ✅ | ✅ | ✅ | 50 +------------------------------------+--------+--------+--------+ 51 | Send a pong | ✅ | ✅ | ✅ | 52 +------------------------------------+--------+--------+--------+ 53 | Perform the closing handshake | ✅ | ✅ | ✅ | 54 +------------------------------------+--------+--------+--------+ 55 | Report close codes and reasons | ❌ | ✅ | ✅ | 56 | from both sides | | | | 57 +------------------------------------+--------+--------+--------+ 58 | Compress messages (:rfc:`7692`) | ✅ | ✅ | ✅ | 59 +------------------------------------+--------+--------+--------+ 60 | Tune memory usage for compression | ✅ | ✅ | ✅ | 61 +------------------------------------+--------+--------+--------+ 62 | Negotiate extensions | ✅ | ✅ | ✅ | 63 +------------------------------------+--------+--------+--------+ 64 | Implement custom extensions | ✅ | ✅ | ✅ | 65 +------------------------------------+--------+--------+--------+ 66 | Negotiate a subprotocol | ✅ | ✅ | ✅ | 67 +------------------------------------+--------+--------+--------+ 68 | Enforce security limits | ✅ | ✅ | ✅ | 69 +------------------------------------+--------+--------+--------+ 70 | Log events | ✅ | ✅ | ✅ | 71 +------------------------------------+--------+--------+--------+ 72 | Enforce opening timeout | ✅ | ✅ | — | 73 +------------------------------------+--------+--------+--------+ 74 | Enforce closing timeout | ✅ | ✅ | — | 75 +------------------------------------+--------+--------+--------+ 76 | Keepalive | ✅ | ❌ | — | 77 +------------------------------------+--------+--------+--------+ 78 | Heartbeat | ✅ | ❌ | — | 79 +------------------------------------+--------+--------+--------+ 80 81 .. _#479: https://github.com/python-websockets/websockets/issues/479 82 83 Server 84 ------ 85 86 .. table:: 87 :class: support-matrix-table 88 89 +------------------------------------+--------+--------+--------+ 90 | | |aio| | |sync| | |sans| | 91 +====================================+========+========+========+ 92 | Listen on a TCP socket | ✅ | ✅ | — | 93 +------------------------------------+--------+--------+--------+ 94 | Listen on a Unix socket | ✅ | ✅ | — | 95 +------------------------------------+--------+--------+--------+ 96 | Listen using a preexisting socket | ✅ | ✅ | — | 97 +------------------------------------+--------+--------+--------+ 98 | Encrypt connection with TLS | ✅ | ✅ | — | 99 +------------------------------------+--------+--------+--------+ 100 | Close server on context exit | ✅ | ✅ | — | 101 +------------------------------------+--------+--------+--------+ 102 | Close connection on handler exit | ✅ | ✅ | — | 103 +------------------------------------+--------+--------+--------+ 104 | Shut down server gracefully | ✅ | ✅ | — | 105 +------------------------------------+--------+--------+--------+ 106 | Check ``Origin`` header | ✅ | ✅ | ✅ | 107 +------------------------------------+--------+--------+--------+ 108 | Customize subprotocol selection | ✅ | ✅ | ✅ | 109 +------------------------------------+--------+--------+--------+ 110 | Configure ``Server`` header | ✅ | ✅ | ✅ | 111 +------------------------------------+--------+--------+--------+ 112 | Alter opening handshake request | ❌ | ✅ | ✅ | 113 +------------------------------------+--------+--------+--------+ 114 | Alter opening handshake response | ❌ | ✅ | ✅ | 115 +------------------------------------+--------+--------+--------+ 116 | Perform HTTP Basic Authentication | ✅ | ❌ | ❌ | 117 +------------------------------------+--------+--------+--------+ 118 | Perform HTTP Digest Authentication | ❌ | ❌ | ❌ | 119 +------------------------------------+--------+--------+--------+ 120 | Force HTTP response | ✅ | ✅ | ✅ | 121 +------------------------------------+--------+--------+--------+ 122 123 Client 124 ------ 125 126 .. table:: 127 :class: support-matrix-table 128 129 +------------------------------------+--------+--------+--------+ 130 | | |aio| | |sync| | |sans| | 131 +====================================+========+========+========+ 132 | Connect to a TCP socket | ✅ | ✅ | — | 133 +------------------------------------+--------+--------+--------+ 134 | Connect to a Unix socket | ✅ | ✅ | — | 135 +------------------------------------+--------+--------+--------+ 136 | Connect using a preexisting socket | ✅ | ✅ | — | 137 +------------------------------------+--------+--------+--------+ 138 | Encrypt connection with TLS | ✅ | ✅ | — | 139 +------------------------------------+--------+--------+--------+ 140 | Close connection on context exit | ✅ | ✅ | — | 141 +------------------------------------+--------+--------+--------+ 142 | Reconnect automatically | ✅ | ❌ | — | 143 +------------------------------------+--------+--------+--------+ 144 | Configure ``Origin`` header | ✅ | ✅ | ✅ | 145 +------------------------------------+--------+--------+--------+ 146 | Configure ``User-Agent`` header | ✅ | ✅ | ✅ | 147 +------------------------------------+--------+--------+--------+ 148 | Alter opening handshake request | ✅ | ✅ | ✅ | 149 +------------------------------------+--------+--------+--------+ 150 | Connect to non-ASCII IRIs | ✅ | ✅ | ✅ | 151 +------------------------------------+--------+--------+--------+ 152 | Perform HTTP Basic Authentication | ✅ | ✅ | ✅ | 153 +------------------------------------+--------+--------+--------+ 154 | Perform HTTP Digest Authentication | ❌ | ❌ | ❌ | 155 | (`#784`_) | | | | 156 +------------------------------------+--------+--------+--------+ 157 | Follow HTTP redirects | ✅ | ❌ | — | 158 +------------------------------------+--------+--------+--------+ 159 | Connect via a HTTP proxy (`#364`_) | ❌ | ❌ | — | 160 +------------------------------------+--------+--------+--------+ 161 | Connect via a SOCKS5 proxy | ❌ | ❌ | — | 162 | (`#475`_) | | | | 163 +------------------------------------+--------+--------+--------+ 164 165 .. _#364: https://github.com/python-websockets/websockets/issues/364 166 .. _#475: https://github.com/python-websockets/websockets/issues/475 167 .. _#784: https://github.com/python-websockets/websockets/issues/784 168 169 Known limitations 170 ----------------- 171 172 There is no way to control compression of outgoing frames on a per-frame basis 173 (`#538`_). If compression is enabled, all frames are compressed. 174 175 .. _#538: https://github.com/python-websockets/websockets/issues/538 176 177 The server doesn't check the Host header and respond with a HTTP 400 Bad Request 178 if it is missing or invalid (`#1246`). 179 180 .. _#1246: https://github.com/python-websockets/websockets/issues/1246 181 182 The client API doesn't attempt to guarantee that there is no more than one 183 connection to a given IP address in a CONNECTING state. This behavior is 184 `mandated by RFC 6455`_. However, :func:`~client.connect()` isn't the right 185 layer for enforcing this constraint. It's the caller's responsibility. 186 187 .. _mandated by RFC 6455: https://www.rfc-editor.org/rfc/rfc6455.html#section-4.1