Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure text message exists before handling on WebsocketConsumer #2097

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions channels/generic/websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def websocket_receive(self, message):
Called when a WebSocket frame is received. Decodes it and passes it
to receive().
"""
if "text" in message:
if message.get("text") is not None:
self.receive(text_data=message["text"])
else:
self.receive(bytes_data=message["bytes"])
Expand Down Expand Up @@ -200,7 +200,7 @@ async def websocket_receive(self, message):
Called when a WebSocket frame is received. Decodes it and passes it
to receive().
"""
if "text" in message:
if message.get("text") is not None:
await self.receive(text_data=message["text"])
else:
await self.receive(bytes_data=message["bytes"])
Expand Down
41 changes: 41 additions & 0 deletions tests/test_generic_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,3 +485,44 @@ async def connect(self):
assert msg["type"] == "websocket.close"
assert msg["code"] == 4007
assert msg["reason"] == "test reason"

@pytest.mark.django_db
@pytest.mark.asyncio
async def test_websocket_receive_with_none_text():
"""
Tests that the receive method handles messages with None text data correctly.
"""

class TestConsumer(WebsocketConsumer):
def receive(self, text_data=None, bytes_data=None):
if text_data:
self.send(text_data="Received text: " + text_data)
elif bytes_data:
self.send(text_data=f"Received bytes of length: {len(bytes_data)}")

app = TestConsumer()

# Open a connection
communicator = WebsocketCommunicator(app, "/testws/")
connected, _ = await communicator.connect()
assert connected

# Simulate Hypercorn behavior (both 'text' and 'bytes' keys present, but 'text' is None)
await communicator.send_input({"type": "websocket.receive", "text": None, "bytes": b"test data"})
response = await communicator.receive_output()
assert response["type"] == "websocket.send"
assert response["text"] == "Received bytes of length: 9"

# Test with only 'bytes' key (simulating uvicorn/daphne behavior)
await communicator.send_input({"type": "websocket.receive", "bytes": b"more data"})
response = await communicator.receive_output()
assert response["type"] == "websocket.send"
assert response["text"] == "Received bytes of length: 9"

# Test with valid text data
await communicator.send_input({"type": "websocket.receive", "text": "Hello, world!"})
response = await communicator.receive_output()
assert response["type"] == "websocket.send"
assert response["text"] == "Received text: Hello, world!"

await communicator.disconnect()
Loading