python-hyper / h2

HTTP/2 State-Machine based protocol implementation
https://h2.readthedocs.io/en/stable
MIT License
964 stars 153 forks source link

Ignores experimental range frames? #696

Open wbl opened 7 years ago

wbl commented 7 years ago

leftshark.tls13.com returns two unknown frames, one with type 0xc, and the other in the experimental range. h2 only produces one UnknownFrameEvent with type 0xc and ignores the experimental range frame entirely. I haven't tracked down the cause yet, and it might be anywhere in the dependency tree.

Lukasa commented 7 years ago

Hrm, it'd be really interesting to see a quick bit of example code that reproduces the problem so that I can check what's happening in hyper-h2. Certainly both should produce an UnknownFrameEvent.

wbl commented 7 years ago

Leftshark has been modified to produce 3 unknown frames, one of which should have a large type (not the frames of type 12 which are received correctly). The following reproduces the issue.

import socket
import h2
import h2.connection
import h2.events
import ssl
import sys

def get_url(host, port, path):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect((host, port))
    ssl_ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    ssl_ctx.verify_mode=ssl.CERT_NONE
    ssl_ctx.set_alpn_protocols(['h2'])
    tls=ssl_ctx.wrap_socket(s, server_hostname=host)
    conn = h2.connection.H2Connection()
    conn.initiate_connection()
    tls.sendall(conn.data_to_send())
    sid = conn.get_next_available_stream_id()
    conn.send_headers(sid, [
        ( ':method', 'GET'),
        ( ':authority', host),
        ( ':scheme', 'https'),
        ( ':path', path)])
    tls.sendall(conn.data_to_send())
    while 1:
        data = tls.recv(1024)
        if not data: break
        events = conn.receive_data(data)
        for event in events:
            print event
            if isinstance(event, h2.events.StreamEnded):
                sys.exit(0)
            if isinstance(event, h2.events.UnknownFrameReceived):
                print event.frame.type

get_url("leftshark.tls13.com", 443, "/")

Thanks for looking into this.