Skip to content

Commit

Permalink
Support the legacy pattern for setting User-Agent.
Browse files Browse the repository at this point in the history
Support setting it with additional_headers for backwards compatibility
with the legacy implementation and the API until websoockets 10.4.

Before this change, the header was added twice: once with the custom
value and once with the default value.

Fix #1583.
  • Loading branch information
aaugustin committed Jan 29, 2025
1 parent 321be89 commit a00c184
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 6 deletions.
14 changes: 10 additions & 4 deletions docs/howto/upgrade.rst
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,12 @@ Arguments of :func:`~asyncio.client.connect`
``extra_headers`` → ``additional_headers``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you're adding headers to the handshake request sent by
:func:`~legacy.client.connect` with the ``extra_headers`` argument, you must
rename it to ``additional_headers``.
If you're setting the ``User-Agent`` header with the ``extra_headers`` argument,
you should set it with ``user_agent_header`` instead.

If you're adding other headers to the handshake request sent by
:func:`~legacy.client.connect` with ``extra_headers``, you must rename it to
``additional_headers``.

Arguments of :func:`~asyncio.server.serve`
..........................................
Expand Down Expand Up @@ -310,7 +313,10 @@ replace it with a ``process_request`` function or coroutine.
``extra_headers`` → ``process_response``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you're adding headers to the handshake response sent by
If you're setting the ``Server`` header with ``extra_headers``, you should set
it with the ``server_header`` argument instead.

If you're adding other headers to the handshake response sent by
:func:`~legacy.server.serve` with the ``extra_headers`` argument, you must write
a ``process_response`` callable instead.

Expand Down
2 changes: 1 addition & 1 deletion src/websockets/asyncio/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ async def handshake(
if additional_headers is not None:
self.request.headers.update(additional_headers)
if user_agent_header:
self.request.headers["User-Agent"] = user_agent_header
self.request.headers.setdefault("User-Agent", user_agent_header)
self.protocol.send_request(self.request)

await asyncio.wait(
Expand Down
2 changes: 1 addition & 1 deletion src/websockets/sync/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ def handshake(
if additional_headers is not None:
self.request.headers.update(additional_headers)
if user_agent_header is not None:
self.request.headers["User-Agent"] = user_agent_header
self.request.headers.setdefault("User-Agent", user_agent_header)
self.protocol.send_request(self.request)

if not self.response_rcvd.wait(timeout):
Expand Down
8 changes: 8 additions & 0 deletions tests/asyncio/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ async def test_remove_user_agent(self):
async with connect(get_uri(server), user_agent_header=None) as client:
self.assertNotIn("User-Agent", client.request.headers)

async def test_legacy_user_agent(self):
"""Client can override User-Agent header with additional_headers."""
async with serve(*args) as server:
async with connect(
get_uri(server), additional_headers={"User-Agent": "Smith"}
) as client:
self.assertEqual(client.request.headers["User-Agent"], "Smith")

async def test_keepalive_is_enabled(self):
"""Client enables keepalive and measures latency by default."""
async with serve(*args) as server:
Expand Down
8 changes: 8 additions & 0 deletions tests/sync/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ def test_remove_user_agent(self):
with connect(get_uri(server), user_agent_header=None) as client:
self.assertNotIn("User-Agent", client.request.headers)

def test_legacy_user_agent(self):
"""Client can override User-Agent header with additional_headers."""
with run_server() as server:
with connect(
get_uri(server), additional_headers={"User-Agent": "Smith"}
) as client:
self.assertEqual(client.request.headers["User-Agent"], "Smith")

def test_keepalive_is_enabled(self):
"""Client enables keepalive and measures latency by default."""
with run_server() as server:
Expand Down

0 comments on commit a00c184

Please sign in to comment.