Change to accept being part of send/close

This commit is contained in:
Andrew Godwin 2016-10-05 15:59:55 -07:00
parent 5d697c9308
commit 09b2a12be1
3 changed files with 49 additions and 31 deletions

View File

@ -122,7 +122,7 @@ class Worker(object):
# They want to deny a WebSocket connection.
if message.channel.name != "websocket.connect":
raise ValueError("You cannot DenyConnection from a non-websocket.connect handler.")
message.reply_channel.send({"accept": False})
message.reply_channel.send({"close": True})
except ConsumeLater:
# They want to not handle it yet. Re-inject it with a number-of-tries marker.
content['__retries__'] = content.get("__retries__", 0) + 1

View File

@ -735,7 +735,7 @@ server must close the connection with either HTTP status code ``503`` or
WebSocket close code ``1013``.
This message must be responded to on the ``reply_channel`` with a
*Connection Reply* message before the socket will pass messages on the
*Send/Close/Accept* message before the socket will pass messages on the
``receive`` channel. The protocol server should ideally send this message
during the handshake phase of the WebSocket and not complete the handshake
until it gets a reply, returning HTTP status code ``403`` if the connection is
@ -743,10 +743,6 @@ denied. If this is not possible, it must buffer WebSocket frames and not
send them onto ``websocket.receive`` until a reply is received, and if the
connection is rejected, return WebSocket close code ``4403``.
Receiving a WebSocket *Send/Close* message while waiting for a
*Connection Reply* must make the server accept the connection and then send
the message immediately.
Channel: ``websocket.connect``
Keys:
@ -782,25 +778,6 @@ Keys:
* ``order``: The integer value ``0``.
Connection Reply
''''''''''''''''
Sent back on the reply channel from an application when a ``connect`` message
is received to say if the connection should be accepted or dropped.
Behaviour on WebSocket rejection is defined in the Connection section above.
If received while the socket is already accepted, the protocol server should
log an error, but not do anything.
Channel: ``websocket.send!``
Keys:
* ``accept``: If the connection should be accepted (``True``) or rejected and
dropped (``False``).
Receive
'''''''
@ -852,14 +829,27 @@ Keys:
``order`` values in ``websocket.receive``.
Send/Close
''''''''''
Send/Close/Accept
'''''''''''''''''
Sends a data frame to the client and/or closes the connection from the
server end. If ``ChannelFull`` is raised, wait and try again.
server end and/or accepts a connection. If ``ChannelFull`` is raised, wait
and try again.
If sent while the connection is waiting for acceptance or rejection,
will accept the connection before the frame is sent.
If received while the connection is waiting for acceptance after a ``connect``
message:
* If ``bytes`` or ``text`` is present, accept the connection and send the data.
* If ``accept`` is ``True``, accept the connection and do nothing else.
* If ``close`` is ``True``, reject the connection. If ``bytes`` or ``text`` is
also set, it should accept the connection, send the frame, then immediately
close the connection.
If received while the connection is established:
* If ``bytes`` or ``text`` is present, send the data.
* If ``close`` is ``True``, close the connection after any send.
* ``accept`` is ignored.
Channel: ``websocket.send!``
@ -872,6 +862,9 @@ Keys:
* ``close``: Boolean saying if the connection should be closed after data
is sent, if any. Optional, default ``False``.
* ``accept``: Boolean saying if the connection should be accepted without
sending a frame if it is in the handshake phase.
A maximum of one of ``bytes`` or ``text`` may be provided. If both are
provided, the protocol server should ignore the message entirely.

View File

@ -52,7 +52,7 @@ you can still do that by passing the ``immediately`` argument::
Channel("thumbnailing-tasks").send({"id": 34245}, immediately=True)
This should be entirely backwards compatible, and may actually fix race
This should be mostly backwards compatible, and may actually fix race
conditions in some apps that were pre-existing.
@ -60,3 +60,28 @@ Demultiplexer Overhaul
~~~~~~~~~~~~~~~~~~~~~~
TBD
Backwards Incompatible Changes
------------------------------
Connect Consumers
~~~~~~~~~~~~~~~~~
If you have a custom consumer for ``websocket.connect``, you must ensure that
it either:
* Sends at least one message onto the ``reply_channel`` that generates a
WebSocket frame (either ``bytes`` or ``text`` is set), either directly
or via a group.
* Sends a message onto the ``reply_channel`` that is ``{"accept": True}``,
to accept a connection without sending data.
* Sends a message onto the ``reply_channel`` that is ``{"close": True}``,
to reject a connection mid-handshake.
Many consumers already do the former, but if your connect consumer does not
send anything you MUST now send an accept message or the socket will remain
in the handshaking phase forever and you'll never get any messages.
All built-in Channels consumers (e.g. in the generic consumers) have been
upgraded to do this.