tornado_http2 icon indicating copy to clipboard operation
tornado_http2 copied to clipboard

Doesn't work with Tornado 6

Open oamm opened this issue 3 years ago • 3 comments

i'm trying to use this module in tornado 6.1 but when i try to execute the script i have a exception that tell WARNING:tornado.general:Script exited with uncaught exception Traceback (most recent call last): File "C:\Users\oamor\.virtualenvs\Hades2.0-srxBvY7H\lib\site-packages\tornado\autoreload.py", line 326, in main exec_in(f.read(), globals(), globals()) File "C:\Users\oamor\.virtualenvs\Hades2.0-srxBvY7H\lib\site-packages\tornado\util.py", line 167, in exec_in exec(code, glob, loc) File "<string>", line 25, in <module> File "C:\Users\oamor\.virtualenvs\Hades2.0-srxBvY7H\lib\site-packages\tornado\util.py", line 332, in configure impl = typing.cast(Type[Configurable], import_object(impl)) File "C:\Users\oamor\.virtualenvs\Hades2.0-srxBvY7H\lib\site-packages\tornado\util.py", line 153, in import_object obj = __import__(".".join(parts[:-1]), fromlist=[parts[-1]]) File "C:\Users\oamor\.virtualenvs\Hades2.0-srxBvY7H\lib\site-packages\tornado_http2\server.py", line 11, in <module> from tornado import stack_context ImportError: cannot import name 'stack_context' from 'tornado' (C:\Users\oamor\.virtualenvs\Hades2.0-srxBvY7H\lib\site-packages\tornado\__init__.py)

i read about the tornado.stack_context module is deprecated so how can i config the modulo to run in tornado 6?

oamm avatar Apr 09 '21 01:04 oamm

Looks like you're the first person to try this module in Tornado 6 :)

This would be a two-line fix (remove the import of stack_context and the call to stack_context.wrap). I'm not sure if there will be other issues once that's fixed.

bdarnell avatar Apr 10 '21 15:04 bdarnell

thanks for the advice, i removed the uses of stack_context and get it to work but I also have to update handle_stream, I notice that the _handle_handshake now gets an additional argument but I don't know what it is and if it should be used Could you bring me any ideas about it? before:

`

def handle_stream(self, stream, address):
    if isinstance(stream, SSLIOStream):
        stream.wait_for_handshake(
            functools.partial(self._handle_handshake, stream, address))
    else:
        self._handle_handshake(stream, address)

def _handle_handshake(self, stream, address):
    if isinstance(stream, SSLIOStream):
        assert stream.socket.cipher(), 'handshake incomplete'
        # TODO: alpn when available
        proto = stream.socket.selected_alpn_protocol()
        if proto == constants.HTTP2_TLS:
            self._start_http2(stream, address)
            return
    self._start_http1(stream, address)

` after:

`

def handle_stream(self, stream, address):
    if isinstance(stream, SSLIOStream):
        future = stream.wait_for_handshake()
        future.add_done_callback(functools.partial(self._handle_handshake, stream, address))
    else:
        self._handle_handshake(stream, address)

def _handle_handshake(self, stream, address, unknow=None):
    if isinstance(stream, SSLIOStream):
        assert stream.socket.cipher(), 'handshake incomplete'
        # TODO: alpn when available
        proto = stream.socket.selected_alpn_protocol()
        if proto == constants.HTTP2_TLS:
            self._start_http2(stream, address)
            return
    self._start_http1(stream, address)`

oamm avatar Apr 11 '21 18:04 oamm

The Future returned by wait_for_handshake is intended for use in coroutines. The new argument (which is the only one added by add_done_callback; the rest are bound in the partial) is a Future which always resolves to None. The idomatic way to rewrite handle_stream would be (untested):

async def handle_stream(self, stream, address):
    if isinstance(stream, SSLIOStream):
        await stream.wait_for_handshake()
    self._handle_handshake(stream, address)

(at this point I'd probably just merge _handle_handshake into the same method).

bdarnell avatar Apr 12 '21 02:04 bdarnell