Skip to content

Commit

Permalink
Include non-default port in Websocket Host header
Browse files Browse the repository at this point in the history
  • Loading branch information
PierreF committed Jan 21, 2024
1 parent 4074dd4 commit 2bcd571
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 4 deletions.
2 changes: 1 addition & 1 deletion ChangeLog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ v2.0.0 - 2023-xx-xx
2. Closes #696.
- Raise error on `subscribe()` when `topic` is an empty list. Closes #690.
- Raise error on `publish.multiple()` when `msgs` is an empty list. Closes #684.
- Don't add port to Host: header for websockets connections. Closes #666.
- Don't add port to Host: header for websockets connections when the port if the default port. Closes #666.


v1.6.1 - 2021-10-21
Expand Down
16 changes: 14 additions & 2 deletions src/paho/mqtt/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -4112,11 +4112,23 @@ def _do_handshake(self, extra_headers: WebSocketHeaders | None) -> None:
sec_websocket_key = uuid.uuid4().bytes
sec_websocket_key = base64.b64encode(sec_websocket_key)

if self._ssl:
default_port = 443
http_schema = "https"
else:
default_port = 80
http_schema = "http"

if default_port == self._port:
host_port = f"{self._host}"
else:
host_port = f"{self._host}:{self._port}"

websocket_headers = {
"Host": f"{self._host}",
"Host": host_port,
"Upgrade": "websocket",
"Connection": "Upgrade",
"Origin": f"https://{self._host}:{self._port}",
"Origin": f"{http_schema}://{host_port}",
"Sec-WebSocket-Key": sec_websocket_key.decode("utf8"),
"Sec-Websocket-Version": "13",
"Sec-Websocket-Protocol": "mqtt",
Expand Down
60 changes: 59 additions & 1 deletion tests/test_websockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class TestHeaders:

@pytest.mark.parametrize("wargs,expected_sent", [
(
# HTTPS on non-default port
{
"host": "testhost.com",
"port": 1234,
Expand All @@ -19,14 +20,71 @@ class TestHeaders:
},
[
"GET /mqtt HTTP/1.1",
"Host: testhost.com",
"Host: testhost.com:1234",
"Upgrade: websocket",
"Connection: Upgrade",
"Sec-Websocket-Protocol: mqtt",
"Sec-Websocket-Version: 13",
"Origin: https://testhost.com:1234",
],
),
(
# HTTPS on default port
{
"host": "testhost.com",
"port": 443,
"path": "/mqtt",
"extra_headers": None,
"is_ssl": True,
},
[
"GET /mqtt HTTP/1.1",
"Host: testhost.com",
"Upgrade: websocket",
"Connection: Upgrade",
"Sec-Websocket-Protocol: mqtt",
"Sec-Websocket-Version: 13",
"Origin: https://testhost.com",
],
),
(
# HTTP on default port
{
"host": "testhost.com",
"port": 80,
"path": "/mqtt",
"extra_headers": None,
"is_ssl": False,
},
[
"GET /mqtt HTTP/1.1",
"Host: testhost.com",
"Upgrade: websocket",
"Connection: Upgrade",
"Sec-Websocket-Protocol: mqtt",
"Sec-Websocket-Version: 13",
"Origin: http://testhost.com",
],
),
(
# HTTP on non-default port
{
"host": "testhost.com",
"port": 443, # This isn't the default *HTTP* port. It's on purpose to use httpS port
"path": "/mqtt",
"extra_headers": None,
"is_ssl": False,
},
[
"GET /mqtt HTTP/1.1",
"Host: testhost.com:443",
"Upgrade: websocket",
"Connection: Upgrade",
"Sec-Websocket-Protocol: mqtt",
"Sec-Websocket-Version: 13",
"Origin: http://testhost.com:443",
],
),
])
def test_normal_headers(self, wargs, expected_sent):
""" Normal headers as specified in RFC 6455 """
Expand Down

0 comments on commit 2bcd571

Please sign in to comment.