28
28
from .exceptions import (
29
29
ProtocolError , NoSuchStreamError , FlowControlError , FrameTooLargeError ,
30
30
TooManyStreamsError , StreamClosedError , StreamIDTooLowError ,
31
- NoAvailableStreamIDError , UnsupportedFrameError , RFC1122Error ,
32
- DenialOfServiceError
31
+ NoAvailableStreamIDError , RFC1122Error , DenialOfServiceError
33
32
)
34
33
from .frame_buffer import FrameBuffer
35
34
from .settings import Settings , SettingCodes
@@ -46,6 +45,15 @@ class OversizedHeaderListError(Exception):
46
45
pass
47
46
48
47
48
+ try :
49
+ from hyperframe .frame import ExtensionFrame
50
+ except ImportError : # Platform-specific: Hyperframe < 5.0.0
51
+ # If the frame doesn't exist, that's just fine: we'll define it ourselves
52
+ # and the method will just never be called.
53
+ class ExtensionFrame (object ):
54
+ pass
55
+
56
+
49
57
class ConnectionState (Enum ):
50
58
IDLE = 0
51
59
CLIENT_OPEN = 1
@@ -404,6 +412,7 @@ def __init__(self, client_side=True, header_encoding='utf-8', config=None):
404
412
GoAwayFrame : self ._receive_goaway_frame ,
405
413
ContinuationFrame : self ._receive_naked_continuation ,
406
414
AltSvcFrame : self ._receive_alt_svc_frame ,
415
+ ExtensionFrame : self ._receive_unknown_frame
407
416
}
408
417
409
418
def _prepare_for_sending (self , frames ):
@@ -1575,10 +1584,6 @@ def _receive_frame(self, frame):
1575
1584
# Closed implicitly, also a connection error, but of type
1576
1585
# PROTOCOL_ERROR.
1577
1586
raise
1578
- except KeyError as e : # pragma: no cover
1579
- # We don't have a function for handling this frame. Let's call this
1580
- # a PROTOCOL_ERROR and exit.
1581
- raise UnsupportedFrameError ("Unexpected frame: %s" % frame )
1582
1587
else :
1583
1588
self ._prepare_for_sending (frames )
1584
1589
@@ -1922,6 +1927,21 @@ def _receive_alt_svc_frame(self, frame):
1922
1927
1923
1928
return frames , events
1924
1929
1930
+ def _receive_unknown_frame (self , frame ):
1931
+ """
1932
+ We have received a frame that we do not understand. This is almost
1933
+ certainly an extension frame, though it's impossible to be entirely
1934
+ sure.
1935
+
1936
+ RFC 7540 § 5.5 says that we MUST ignore unknown frame types: so we
1937
+ do.
1938
+ """
1939
+ # All we do here is log.
1940
+ self .config .logger .debug (
1941
+ "Received unknown extension frame (ID %d)" , frame .stream_id
1942
+ )
1943
+ return [], []
1944
+
1925
1945
def _local_settings_acked (self ):
1926
1946
"""
1927
1947
Handle the local settings being ACKed, update internal state.
0 commit comments