Changelog
*********


Backwards-compatibility policy
==============================

"websockets" is intended for production use. Therefore, stability is a
goal.

"websockets" also aims at providing the best API for WebSocket in
Python.

While we value stability, we value progress more. When an improvement
requires changing a public API, we make the change and document it in
this changelog.

When possible with reasonable effort, we preserve backwards-
compatibility for five years after the release that introduced the
change.

When a release contains backwards-incompatible API changes, the major
version is increased, else the minor version is increased. Patch
versions are only for fixing regressions shortly after a release.

Only documented APIs are public. Undocumented APIs are considered
private. They may change at any time.


9.1
===

*May 27, 2021*

Note:

  **Version 9.1 fixes a security issue introduced in version
  8.0.**Version 8.0 was vulnerable to timing attacks on HTTP Basic
  Auth passwords.


9.0.2
=====

*May 15, 2021*

* Restored compatibility of "python -m websockets" with Python < 3.9.

* Restored compatibility with mypy.


9.0.1
=====

*May 2, 2021*

* Fixed issues with the packaging of the 9.0 release.


9.0
===

*May 1, 2021*

Note:

  **Version 9.0 moves or deprecates several APIs.**Aliases provide
  backwards compatibility for all previously public APIs.

  * "Headers" and "MultipleValuesError" were moved from
    "websockets.http" to "websockets.datastructures". If you're using
    them, you should adjust the import path.

  * The "client", "server", "protocol", and "auth" modules were moved
    from the "websockets" package to "websockets.legacy" sub-package,
    as part of an upcoming refactoring. Despite the name, they're
    still fully supported. The refactoring should be a transparent
    upgrade for most uses when it's available. The legacy
    implementation will be preserved according to the backwards-
    compatibility policy.

  * The "framing", "handshake", "headers", "http", and "uri" modules
    in the "websockets" package are deprecated. These modules provided
    low-level APIs for reuse by other WebSocket implementations, but
    that never happened. Keeping these APIs public makes it more
    difficult to improve websockets for no actual benefit.

Note:

  **Version 9.0 may require changes if you use static code analysis
  tools.**Convenience imports from the "websockets" module are
  performed lazily. While this is supported by Python, static code
  analysis tools such as mypy are unable to understand the behavior.If
  you depend on such tools, use the real import path, which can be
  found in the API documentation:

     from websockets.client import connect
     from websockets.server import serve

* Added compatibility with Python 3.9.

* Added support for IRIs in addition to URIs.

* Added close codes 1012, 1013, and 1014.

* Raised an error when passing a "dict" to "send()".

* Fixed sending fragmented, compressed messages.

* Fixed "Host" header sent when connecting to an IPv6 address.

* Fixed creating a client or a server with an existing Unix socket.

* Aligned maximum cookie size with popular web browsers.

* Ensured cancellation always propagates, even on Python versions
  where "CancelledError" inherits "Exception".

* Improved error reporting.


8.1
===

*November 1, 2019*

* Added compatibility with Python 3.8.


8.0.2
=====

*July 31, 2019*

* Restored the ability to pass a socket with the "sock" parameter of
  "serve()".

* Removed an incorrect assertion when a connection drops.


8.0.1
=====

*July 21, 2019*

* Restored the ability to import "WebSocketProtocolError" from
  "websockets".


8.0
===

*July 7, 2019*

Warning:

  **Version 8.0 drops compatibility with Python 3.4 and 3.5.**

Note:

  **Version 8.0 expects** "process_request" **to be a
  coroutine.**Previously, it could be a function or a coroutine.If
  you're passing a "process_request" argument to "serve()" or
  "WebSocketServerProtocol", or if you're overriding
  "process_request()" in a subclass, define it with "async def"
  instead of "def".For backwards compatibility, functions are still
  mostly supported, but mixing functions and coroutines won't work in
  some inheritance scenarios.

Note:

  **Version 8.0 changes the behavior of the** "max_queue"
  **parameter.**If you were setting "max_queue=0" to make the queue of
  incoming messages unbounded, change it to "max_queue=None".

Note:

  **Version 8.0 deprecates the** "host" **,** "port" **, and**
  "secure" **attributes of** "WebSocketCommonProtocol".Use
  "local_address" in servers and "remote_address" in clients instead
  of "host" and "port".

Note:

  **Version 8.0 renames the** "WebSocketProtocolError" **exception**
  to "ProtocolError" **.**A "WebSocketProtocolError" alias provides
  backwards compatibility.

Note:

  **Version 8.0 adds the reason phrase to the return type of the low-
  level API** "read_response()" **.**

Also:

* "send()", "ping()", and "pong()" support bytes-like types
  "bytearray" and "memoryview" in addition to "bytes".

* Added "ConnectionClosedOK" and "ConnectionClosedError" subclasses of
  "ConnectionClosed" to tell apart normal connection termination from
  errors.

* Added "basic_auth_protocol_factory()" to enforce HTTP Basic Auth on
  the server side.

* "connect()" handles redirects from the server during the handshake.

* "connect()" supports overriding "host" and "port".

* Added "unix_connect()" for connecting to Unix sockets.

* Improved support for sending fragmented messages by accepting
  asynchronous iterators in "send()".

* Prevented spurious log messages about "ConnectionClosed" exceptions
  in keepalive ping task. If you were using "ping_timeout=None" as a
  workaround, you can remove it.

* Changed "WebSocketServer.close()" to perform a proper closing
  handshake instead of failing the connection.

* Avoided a crash when a "extra_headers" callable returns "None".

* Improved error messages when HTTP parsing fails.

* Enabled readline in the interactive client.

* Added type hints (**PEP 484**).

* Added a FAQ to the documentation.

* Added documentation for extensions.

* Documented how to optimize memory usage.

* Improved API documentation.


7.0
===

*November 1, 2018*

Warning:

  "websockets" **now sends Ping frames at regular intervals and closes
  the connection if it doesn't receive a matching Pong frame.**See
  "WebSocketCommonProtocol" for details.

Warning:

  **Version 7.0 changes how a server terminates connections when it's
  closed with** "WebSocketServer.close()" **.**Previously, connections
  handlers were canceled. Now, connections are closed with close code
  1001 (going away). From the perspective of the connection handler,
  this is the same as if the remote endpoint was disconnecting. This
  removes the need to prepare for "CancelledError" in connection
  handlers.You can restore the previous behavior by adding the
  following line at the beginning of connection handlers:

     def handler(websocket, path):
         closed = asyncio.ensure_future(websocket.wait_closed())
         closed.add_done_callback(lambda task: task.cancel())

Note:

  **Version 7.0 renames the** "timeout" **argument of** "serve()"
  **and** "connect()" **to** "close_timeout" **.**This prevents
  confusion with "ping_timeout".For backwards compatibility, "timeout"
  is still supported.

Note:

  **Version 7.0 changes how a** "ping()" **that hasn't received a pong
  yet behaves when the connection is closed.**The ping — as in "ping =
  await websocket.ping()" — used to be canceled when the connection is
  closed, so that "await ping" raised "CancelledError". Now "await
  ping" raises "ConnectionClosed" like other public APIs.

Note:

  **Version 7.0 raises a** "RuntimeError" **exception if two
  coroutines call** "recv()" **concurrently.**Concurrent calls lead to
  non-deterministic behavior because there are no guarantees about
  which coroutine will receive which message.

Also:

* Added "process_request" and "select_subprotocol" arguments to
  "serve()" and "WebSocketServerProtocol" to customize
  "process_request()" and "select_subprotocol()" without subclassing
  "WebSocketServerProtocol".

* Added support for sending fragmented messages.

* Added the "wait_closed()" method to protocols.

* Added an interactive client: "python -m websockets <uri>".

* Changed the "origins" argument to represent the lack of an origin
  with "None" rather than "''".

* Fixed a data loss bug in "recv()": canceling it at the wrong time
  could result in messages being dropped.

* Improved handling of multiple HTTP headers with the same name.

* Improved error messages when a required HTTP header is missing.


6.0
===

*July 16, 2018*

Warning:

  **Version 6.0 introduces the** "Headers" **class for managing HTTP
  headers and changes several public APIs:**

  * "process_request()" now receives a "Headers" instead of a
    "http.client.HTTPMessage" in the "request_headers" argument.

  * The "request_headers" and "response_headers" attributes of
    "WebSocketCommonProtocol" are "Headers" instead of
    "http.client.HTTPMessage".

  * The "raw_request_headers" and "raw_response_headers" attributes of
    "WebSocketCommonProtocol" are removed. Use "raw_items()" instead.

  * Functions defined in the "handshake" module now receive "Headers"
    in argument instead of "get_header" or "set_header" functions.
    This affects libraries that rely on low-level APIs.

  * Functions defined in the "http" module now return HTTP headers as
    "Headers" instead of lists of "(name, value)" pairs.

  Since "Headers" and "http.client.HTTPMessage" provide similar APIs,
  this change won't affect most of the code dealing with HTTP headers.

Also:

* Added compatibility with Python 3.7.


5.0.1
=====

*May 24, 2018*

* Fixed a regression in 5.0 that broke some invocations of "serve()"
  and "connect()".


5.0
===

*May 22, 2018*

Note:

  **Version 5.0 fixes a security issue introduced in version
  4.0.**Version 4.0 was vulnerable to denial of service by memory
  exhaustion because it didn't enforce "max_size" when decompressing
  compressed messages (CVE-2018-1000518).

Note:

  **Version 5.0 adds a** "user_info" **field to the return value of**
  "parse_uri()" **and** "WebSocketURI" **.**If you're unpacking
  "WebSocketURI" into four variables, adjust your code to account for
  that fifth field.

Also:

* "connect()" performs HTTP Basic Auth when the URI contains
  credentials.

* Iterating on incoming messages no longer raises an exception when
  the connection terminates with close code 1001 (going away).

* A plain HTTP request now receives a 426 Upgrade Required response
  and doesn't log a stack trace.

* "unix_serve()" can be used as an asynchronous context manager on
  Python ≥ 3.5.1.

* Added the "closed" property to protocols.

* If a "ping()" doesn't receive a pong, it's canceled when the
  connection is closed.

* Reported the cause of "ConnectionClosed" exceptions.

* Added new examples in the documentation.

* Updated documentation with new features from Python 3.6.

* Improved several other sections of the documentation.

* Fixed missing close code, which caused "TypeError" on connection
  close.

* Fixed a race condition in the closing handshake that raised
  "InvalidState".

* Stopped logging stack traces when the TCP connection dies
  prematurely.

* Prevented writing to a closing TCP connection during unclean
  shutdowns.

* Made connection termination more robust to network congestion.

* Prevented processing of incoming frames after failing the
  connection.


4.0.1
=====

*November 2, 2017*

* Fixed issues with the packaging of the 4.0 release.


4.0
===

*November 2, 2017*

Warning:

  **Version 4.0 drops compatibility with Python 3.3.**

Note:

  **Version 4.0 enables compression with the permessage-deflate
  extension.**In August 2017, Firefox and Chrome support it, but not
  Safari and IE.Compression should improve performance but it
  increases RAM and CPU use.If you want to disable compression, add
  "compression=None" when calling "serve()" or "connect()".

Note:

  **Version 4.0 removes the** "state_name" **attribute of
  protocols.**Use "protocol.state.name" instead of
  "protocol.state_name".

Also:

* "WebSocketCommonProtocol" instances can be used as asynchronous
  iterators on Python ≥ 3.6. They yield incoming messages.

* Added "unix_serve()" for listening on Unix sockets.

* Added the "sockets" attribute to the return value of "serve()".

* Reorganized and extended documentation.

* Aborted connections if they don't close within the configured
  "timeout".

* Rewrote connection termination to increase robustness in edge cases.

* Stopped leaking pending tasks when "cancel()" is called on a
  connection while it's being closed.

* Reduced verbosity of "Failing the WebSocket connection" logs.

* Allowed "extra_headers" to override "Server" and "User-Agent"
  headers.


3.4
===

*August 20, 2017*

* Renamed "serve()" and "connect()"'s "klass" argument to
  "create_protocol" to reflect that it can also be a callable. For
  backwards compatibility, "klass" is still supported.

* "serve()" can be used as an asynchronous context manager on Python ≥
  3.5.1.

* Added support for customizing handling of incoming connections with
  "process_request()".

* Made read and write buffer sizes configurable.

* Rewrote HTTP handling for simplicity and performance.

* Added an optional C extension to speed up low-level operations.

* An invalid response status code during "connect()" now raises
  "InvalidStatusCode" with a "code" attribute.

* Providing a "sock" argument to "connect()" no longer crashes.


3.3
===

*March 29, 2017*

* Ensured compatibility with Python 3.6.

* Reduced noise in logs caused by connection resets.

* Avoided crashing on concurrent writes on slow connections.


3.2
===

*August 17, 2016*

* Added "timeout", "max_size", and "max_queue" arguments to
  "connect()" and "serve()".

* Made server shutdown more robust.


3.1
===

*April 21, 2016*

* Avoided a warning when closing a connection before the opening
  handshake.

* Added flow control for incoming data.


3.0
===

*December 25, 2015*

Warning:

  **Version 3.0 introduces a backwards-incompatible change in the**
  "recv()" **API.****If you're upgrading from 2.x or earlier, please
  read this carefully.**"recv()" used to return "None" when the
  connection was closed. This required checking the return value of
  every call:

     message = await websocket.recv()
     if message is None:
         return

  Now it raises a "ConnectionClosed" exception instead. This is more
  Pythonic. The previous code can be simplified to:

     message = await websocket.recv()

  When implementing a server, which is the more popular use case,
  there's no strong reason to handle such exceptions. Let them bubble
  up, terminate the handler coroutine, and the server will simply
  ignore them.In order to avoid stranding projects built upon an
  earlier version, the previous behavior can be restored by passing
  "legacy_recv=True" to "serve()", "connect()",
  "WebSocketServerProtocol", or "WebSocketClientProtocol".
  "legacy_recv" isn't documented in their signatures but isn't
  scheduled for deprecation either.

Also:

* "connect()" can be used as an asynchronous context manager on Python
  ≥ 3.5.1.

* Updated documentation with "await" and "async" syntax from Python
  3.5.

* "ping()" and "pong()" support data passed as "str" in addition to
  "bytes".

* Worked around an "asyncio" bug affecting connection termination
  under load.

* Made "state_name" attribute on protocols a public API.

* Improved documentation.


2.7
===

*November 18, 2015*

* Added compatibility with Python 3.5.

* Refreshed documentation.


2.6
===

*August 18, 2015*

* Added "local_address" and "remote_address" attributes on protocols.

* Closed open connections with code 1001 when a server shuts down.

* Avoided TCP fragmentation of small frames.


2.5
===

*July 28, 2015*

* Improved documentation.

* Provided access to handshake request and response HTTP headers.

* Allowed customizing handshake request and response HTTP headers.

* Added support for running on a non-default event loop.

* Returned a 403 status code instead of 400 when the request Origin
  isn't allowed.

* Canceling "recv()" no longer drops the next message.

* Clarified that the closing handshake can be initiated by the client.

* Set the close code and reason more consistently.

* Strengthened connection termination by simplifying the
  implementation.

* Improved tests, added tox configuration, and enforced 100% branch
  coverage.


2.4
===

*January 31, 2015*

* Added support for subprotocols.

* Added "loop" argument to "connect()" and "serve()".


2.3
===

*November 3, 2014*

* Improved compliance of close codes.


2.2
===

*July 28, 2014*

* Added support for limiting message size.


2.1
===

*April 26, 2014*

* Added "host", "port" and "secure" attributes on protocols.

* Added support for providing and checking Origin.


2.0
===

*February 16, 2014*

Warning:

  **Version 2.0 introduces a backwards-incompatible change in the**
  "send()", "ping()", and "pong()" **APIs.****If you're upgrading from
  1.x or earlier, please read this carefully.**These APIs used to be
  functions. Now they're coroutines.Instead of:

     websocket.send(message)

  you must now write:

     await websocket.send(message)

Also:

* Added flow control for outgoing data.


1.0
===

*November 14, 2013*

* Initial public release.
