Skip to content

Commit a00c184

Browse files
committed
Support the legacy pattern for setting User-Agent.
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.
1 parent 321be89 commit a00c184

File tree

5 files changed

+28
-6
lines changed

5 files changed

+28
-6
lines changed

docs/howto/upgrade.rst

+10-4
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,12 @@ Arguments of :func:`~asyncio.client.connect`
259259
``extra_headers`` → ``additional_headers``
260260
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
261261

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

266269
Arguments of :func:`~asyncio.server.serve`
267270
..........................................
@@ -310,7 +313,10 @@ replace it with a ``process_request`` function or coroutine.
310313
``extra_headers`` → ``process_response``
311314
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
312315

313-
If you're adding headers to the handshake response sent by
316+
If you're setting the ``Server`` header with ``extra_headers``, you should set
317+
it with the ``server_header`` argument instead.
318+
319+
If you're adding other headers to the handshake response sent by
314320
:func:`~legacy.server.serve` with the ``extra_headers`` argument, you must write
315321
a ``process_response`` callable instead.
316322

src/websockets/asyncio/client.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ async def handshake(
8989
if additional_headers is not None:
9090
self.request.headers.update(additional_headers)
9191
if user_agent_header:
92-
self.request.headers["User-Agent"] = user_agent_header
92+
self.request.headers.setdefault("User-Agent", user_agent_header)
9393
self.protocol.send_request(self.request)
9494

9595
await asyncio.wait(

src/websockets/sync/client.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ def handshake(
8686
if additional_headers is not None:
8787
self.request.headers.update(additional_headers)
8888
if user_agent_header is not None:
89-
self.request.headers["User-Agent"] = user_agent_header
89+
self.request.headers.setdefault("User-Agent", user_agent_header)
9090
self.protocol.send_request(self.request)
9191

9292
if not self.response_rcvd.wait(timeout):

tests/asyncio/test_client.py

+8
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,14 @@ async def test_remove_user_agent(self):
121121
async with connect(get_uri(server), user_agent_header=None) as client:
122122
self.assertNotIn("User-Agent", client.request.headers)
123123

124+
async def test_legacy_user_agent(self):
125+
"""Client can override User-Agent header with additional_headers."""
126+
async with serve(*args) as server:
127+
async with connect(
128+
get_uri(server), additional_headers={"User-Agent": "Smith"}
129+
) as client:
130+
self.assertEqual(client.request.headers["User-Agent"], "Smith")
131+
124132
async def test_keepalive_is_enabled(self):
125133
"""Client enables keepalive and measures latency by default."""
126134
async with serve(*args) as server:

tests/sync/test_client.py

+8
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ def test_remove_user_agent(self):
8282
with connect(get_uri(server), user_agent_header=None) as client:
8383
self.assertNotIn("User-Agent", client.request.headers)
8484

85+
def test_legacy_user_agent(self):
86+
"""Client can override User-Agent header with additional_headers."""
87+
with run_server() as server:
88+
with connect(
89+
get_uri(server), additional_headers={"User-Agent": "Smith"}
90+
) as client:
91+
self.assertEqual(client.request.headers["User-Agent"], "Smith")
92+
8593
def test_keepalive_is_enabled(self):
8694
"""Client enables keepalive and measures latency by default."""
8795
with run_server() as server:

0 commit comments

Comments
 (0)