Revise HTTP1Connection detach protocol.
As a side effect, this now decodes the arguments to open() in the same
way as the arguments to get().
from tornado import gen
from tornado.ioloop import IOLoop
from tornado.options import define, options, parse_command_line
-from tornado.websocket import WebSocketConnect
+from tornado.websocket import websocket_connect
define('url', default='ws://localhost:9001')
define('name', default='Tornado')
@gen.engine
def run_tests():
url = options.url + '/getCaseCount'
- control_ws = yield WebSocketConnect(url, None)
+ control_ws = yield websocket_connect(url, None)
num_tests = int((yield control_ws.read_message()))
logging.info('running %d cases', num_tests)
msg = yield control_ws.read_message()
for i in range(1, num_tests + 1):
logging.info('running test case %d', i)
url = options.url + '/runCase?case=%d&agent=%s' % (i, options.name)
- test_ws = yield WebSocketConnect(url, None)
+ test_ws = yield websocket_connect(url, None)
while True:
message = yield test_ws.read_message()
if message is None:
test_ws.write_message(message, binary=isinstance(message, bytes))
url = options.url + '/updateReports?agent=%s' % options.name
- update_ws = yield WebSocketConnect(url, None)
+ update_ws = yield websocket_connect(url, None)
msg = yield update_ws.read_message()
assert msg is None
IOLoop.instance().stop()
self._disconnect_on_finish = not self._can_keep_alive(
start_line, headers)
- ret = delegate.headers_received(start_line, headers)
- # TODO: finalize the 'detach' interface.
- if ret == 'detach':
- return
+ delegate.headers_received(start_line, headers)
+ if self.stream is None:
+ # We've been detached.
+ # TODO: where else do we need to check for detach?
+ raise gen.Return(False)
skip_body = False
if is_client:
if method == 'HEAD':
yield body_future
delegate.finish()
yield self._finish_future
+ if self.stream is None:
+ raise gen.Return(False)
except httputil.HTTPMessageException as e:
gen_log.info("Malformed HTTP message from %r: %s",
self.address, e)
# cycle and delay garbage collection of this connection.
self._clear_request_state()
+ def detach(self):
+ stream = self.stream
+ self.stream = None
+ return stream
+
def write_headers(self, start_line, headers, chunk=None, callback=None):
self._chunking = (
# TODO: should this use self._version or start_line.version?
def __init__(self, application, request, **kwargs):
tornado.web.RequestHandler.__init__(self, application, request,
**kwargs)
- self.stream = request.connection.stream
self.ws_connection = None
self.close_code = None
self.close_reason = None
- def _execute(self, transforms, *args, **kwargs):
+ @tornado.web.asynchronous
+ def get(self, *args, **kwargs):
self.open_args = args
self.open_kwargs = kwargs
- # Websocket only supports GET method
- if self.request.method != 'GET':
- self.stream.write(tornado.escape.utf8(
- "HTTP/1.1 405 Method Not Allowed\r\n\r\n"
- ))
- self.stream.close()
- return
+ self.stream = self.request.connection.detach()
# Upgrade header should be present and should be equal to WebSocket
if self.request.headers.get("Upgrade", "").lower() != 'websocket':
self.io_loop.remove_timeout(self._timeout)
self._timeout = None
+ self.stream = self.connection.detach()
self.stream.set_close_callback(self._on_close)
self.connect_future.set_result(self)
- return 'detach'
def write_message(self, message, binary=False):
"""Sends a message to the WebSocket server."""