blob: 7576472cd0be62633f1146d4c835abf09f2d0985 [file]
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import Union
from dubbo.remoting.aio.http2.headers import Http2Headers
from dubbo.remoting.aio.http2.registries import Http2ErrorCode, Http2FrameType
__all__ = [
"Http2Frame",
"HeadersFrame",
"DataFrame",
"WindowUpdateFrame",
"RstStreamFrame",
"PingFrame",
"UserActionFrames",
]
class Http2Frame:
"""
HTTP/2 frame class. It is used to represent an HTTP/2 frame.
"""
__slots__ = ["stream_id", "frame_type", "end_stream", "timestamp"]
def __init__(
self,
stream_id: int,
frame_type: Http2FrameType,
end_stream: bool = False,
):
"""
Initialize the HTTP/2 frame.
:param stream_id: The stream identifier. 0 for connection-level frames.
:type stream_id: int
:param frame_type: The frame type.
:type frame_type: Http2FrameType
:param end_stream: Whether the stream is ended.
:type end_stream: bool
"""
self.stream_id = stream_id
self.frame_type = frame_type
self.end_stream = end_stream
def __repr__(self) -> str:
return f"<Http2Frame stream_id={self.stream_id} frame_type={self.frame_type} end_stream={self.end_stream}>"
class HeadersFrame(Http2Frame):
"""
HTTP/2 headers frame.
"""
__slots__ = ["headers"]
def __init__(
self,
stream_id: int,
headers: Http2Headers,
end_stream: bool = False,
):
"""
Initialize the HTTP/2 headers frame.
:param stream_id: The stream identifier.
:type stream_id: int
:param headers: The headers to send.
:type headers: Http2Headers
:param end_stream: Whether the stream is ended.
:type end_stream: bool
"""
super().__init__(stream_id, Http2FrameType.HEADERS, end_stream)
self.headers = headers
def __repr__(self) -> str:
return (
f"<HeadersFrame stream_id={self.stream_id} headers={self.headers.to_list()} end_stream={self.end_stream}>"
)
class DataFrame(Http2Frame):
"""
HTTP/2 data frame.
"""
__slots__ = ["data", "padding"]
def __init__(
self,
stream_id: int,
data: bytes,
length: int,
end_stream: bool = False,
):
"""
Initialize the HTTP/2 data frame.
:param stream_id: The stream identifier.
:type stream_id: int
:param data: The data to send.
:type data: bytes
:param length: The length of the data.
:type length: int
:param end_stream: Whether the stream is ended.
"""
super().__init__(stream_id, Http2FrameType.DATA, end_stream)
self.data = data
self.padding = length
def __repr__(self) -> str:
return f"<DataFrame stream_id={self.stream_id} data={self.data} end_stream={self.end_stream}>"
class WindowUpdateFrame(Http2Frame):
"""
HTTP/2 window update frame.
"""
__slots__ = ["delta"]
def __init__(
self,
stream_id: int,
delta: int,
):
"""
Initialize the HTTP/2 window update frame.
:param stream_id: The stream identifier.
:type stream_id: int
:param delta: The delta value.
:type delta: int
"""
super().__init__(stream_id, Http2FrameType.WINDOW_UPDATE, False)
self.delta = delta
def __repr__(self) -> str:
return f"<WindowUpdateFrame stream_id={self.stream_id} delta={self.delta}>"
class RstStreamFrame(Http2Frame):
"""
HTTP/2 reset stream frame.
"""
__slots__ = ["error_code"]
def __init__(
self,
stream_id: int,
error_code: Http2ErrorCode,
):
"""
Initialize the HTTP/2 reset stream frame.
:param stream_id: The stream identifier.
:type stream_id: int
:param error_code: The error code.
:type error_code: Http2ErrorCode
"""
super().__init__(stream_id, Http2FrameType.RST_STREAM, True)
self.error_code = error_code
def __repr__(self) -> str:
return f"<RstStreamFrame stream_id={self.stream_id} error_code={self.error_code}>"
class PingFrame(Http2Frame):
"""
HTTP/2 ping frame.
"""
__slots__ = ["data", "ack"]
def __init__(self, data: bytes, ack: bool = False):
"""
Initialize the HTTP/2 ping frame.
:param data: The data.
:type data: bytes
"""
super().__init__(0, Http2FrameType.PING, False)
self.data = data
self.ack = ack
def __repr__(self) -> str:
return f"<PingFrame data={self.data}>"
# User action frames.
UserActionFrames = Union[HeadersFrame, DataFrame, RstStreamFrame]