Skip to content

Commit 7c1d1d9

Browse files
committed
Add a respond method to server connections.
It's an alias of the reject method of the underlying server protocol. It makes it easier to write process_request It's called respond because the semantics are "consider the request as an HTTP request and create an HTTP response". There isn't a similar alias for accept because process_request should just return and websockets will call accept.
1 parent 7c8e0b9 commit 7c1d1d9

File tree

8 files changed

+66
-19
lines changed

8 files changed

+66
-19
lines changed

docs/howto/upgrade.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ an example::
247247
# New implementation
248248

249249
def process_request(connection, request):
250-
return connection.protocol.reject(http.HTTPStatus.OK, "OK\n")
250+
return connection.respond(http.HTTPStatus.OK, "OK\n")
251251

252252
serve(..., process_request=process_request, ...)
253253

docs/reference/new-asyncio/server.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ Using a connection
5252

5353
.. automethod:: pong
5454

55+
.. automethod:: respond
56+
5557
WebSocket connection objects also provide these attributes:
5658

5759
.. autoattribute:: id

docs/reference/sync/server.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ Using a connection
4040

4141
.. automethod:: pong
4242

43+
.. automethod:: respond
44+
4345
WebSocket connection objects also provide these attributes:
4446

4547
.. autoattribute:: id

src/websockets/asyncio/server.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from ..http11 import SERVER, Request, Response
2424
from ..protocol import CONNECTING, Event
2525
from ..server import ServerProtocol
26-
from ..typing import LoggerLike, Origin, Subprotocol
26+
from ..typing import LoggerLike, Origin, StatusLike, Subprotocol
2727
from .compatibility import asyncio_timeout
2828
from .connection import Connection
2929

@@ -75,6 +75,27 @@ def __init__(
7575
self.server = server
7676
self.request_rcvd: asyncio.Future[None] = self.loop.create_future()
7777

78+
def respond(self, status: StatusLike, text: str) -> Response:
79+
"""
80+
Create a plain text HTTP response.
81+
82+
``process_request`` and ``process_response`` may call this method to
83+
return an HTTP response instead of performing the WebSocket opening
84+
handshake.
85+
86+
You can modify the response before returning it, for example by changing
87+
HTTP headers.
88+
89+
Args:
90+
status: HTTP status code.
91+
text: HTTP response body; it will be encoded to UTF-8.
92+
93+
Returns:
94+
HTTP response to send to the client.
95+
96+
"""
97+
return self.protocol.reject(status, text)
98+
7899
async def handshake(
79100
self,
80101
process_request: (

src/websockets/server.py

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -113,18 +113,22 @@ def accept(self, request: Request) -> Response:
113113
"""
114114
Create a handshake response to accept the connection.
115115
116-
If the connection cannot be established, the handshake response
117-
actually rejects the handshake.
116+
If the handshake request is valid and the handshake successful,
117+
:meth:`accept` returns an HTTP response with status code 101.
118+
119+
Else, it returns an HTTP response with another status code. This rejects
120+
the connection, like :meth:`reject` would.
118121
119122
You must send the handshake response with :meth:`send_response`.
120123
121-
You may modify it before sending it, for example to add HTTP headers.
124+
You may modify the response before sending it, typically by adding HTTP
125+
headers.
122126
123127
Args:
124-
request: WebSocket handshake request event received from the client.
128+
request: WebSocket handshake request received from the client.
125129
126130
Returns:
127-
WebSocket handshake response event to send to the client.
131+
WebSocket handshake response or HTTP response to send to the client.
128132
129133
"""
130134
try:
@@ -485,11 +489,7 @@ def select_subprotocol(protocol, subprotocols):
485489
+ ", ".join(self.available_subprotocols)
486490
)
487491

488-
def reject(
489-
self,
490-
status: StatusLike,
491-
text: str,
492-
) -> Response:
492+
def reject(self, status: StatusLike, text: str) -> Response:
493493
"""
494494
Create a handshake response to reject the connection.
495495
@@ -498,14 +498,15 @@ def reject(
498498
499499
You must send the handshake response with :meth:`send_response`.
500500
501-
You can modify it before sending it, for example to alter HTTP headers.
501+
You may modify the response before sending it, for example by changing
502+
HTTP headers.
502503
503504
Args:
504505
status: HTTP status code.
505-
text: HTTP response body; will be encoded to UTF-8.
506+
text: HTTP response body; it will be encoded to UTF-8.
506507
507508
Returns:
508-
WebSocket handshake response event to send to the client.
509+
HTTP response to send to the client.
509510
510511
"""
511512
# If a user passes an int instead of a HTTPStatus, fix it automatically.

src/websockets/sync/server.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from ..http11 import SERVER, Request, Response
2020
from ..protocol import CONNECTING, OPEN, Event
2121
from ..server import ServerProtocol
22-
from ..typing import LoggerLike, Origin, Subprotocol
22+
from ..typing import LoggerLike, Origin, StatusLike, Subprotocol
2323
from .connection import Connection
2424
from .utils import Deadline
2525

@@ -66,6 +66,27 @@ def __init__(
6666
close_timeout=close_timeout,
6767
)
6868

69+
def respond(self, status: StatusLike, text: str) -> Response:
70+
"""
71+
Create a plain text HTTP response.
72+
73+
``process_request`` and ``process_response`` may call this method to
74+
return an HTTP response instead of performing the WebSocket opening
75+
handshake.
76+
77+
You can modify the response before returning it, for example by changing
78+
HTTP headers.
79+
80+
Args:
81+
status: HTTP status code.
82+
text: HTTP response body; it will be encoded to UTF-8.
83+
84+
Returns:
85+
HTTP response to send to the client.
86+
87+
"""
88+
return self.protocol.reject(status, text)
89+
6990
def handshake(
7091
self,
7192
process_request: (

tests/asyncio/test_server.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ async def test_process_request_abort_handshake(self):
144144
"""Server aborts handshake if process_request returns a response."""
145145

146146
def process_request(ws, request):
147-
return ws.protocol.reject(http.HTTPStatus.FORBIDDEN, "Forbidden")
147+
return ws.respond(http.HTTPStatus.FORBIDDEN, "Forbidden")
148148

149149
async with run_server(process_request=process_request) as server:
150150
with self.assertRaises(InvalidStatus) as raised:
@@ -159,7 +159,7 @@ async def test_async_process_request_abort_handshake(self):
159159
"""Server aborts handshake if async process_request returns a response."""
160160

161161
async def process_request(ws, request):
162-
return ws.protocol.reject(http.HTTPStatus.FORBIDDEN, "Forbidden")
162+
return ws.respond(http.HTTPStatus.FORBIDDEN, "Forbidden")
163163

164164
async with run_server(process_request=process_request) as server:
165165
with self.assertRaises(InvalidStatus) as raised:

tests/sync/test_server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def test_process_request_abort_handshake(self):
131131
"""Server aborts handshake if process_request returns a response."""
132132

133133
def process_request(ws, request):
134-
return ws.protocol.reject(http.HTTPStatus.FORBIDDEN, "Forbidden")
134+
return ws.respond(http.HTTPStatus.FORBIDDEN, "Forbidden")
135135

136136
with run_server(process_request=process_request) as server:
137137
with self.assertRaises(InvalidStatus) as raised:

0 commit comments

Comments
 (0)