Packages
bandit
1.11.1
1.12.1
1.12.0
1.11.1
1.11.0
1.10.4
1.10.3
1.10.2
1.10.1
1.10.0
retired
1.9.0
1.8.0
1.7.0
1.6.11
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.7
1.5.6
1.5.5
1.5.4
1.5.3
1.5.2
1.5.1
1.5.0
1.4.2
1.4.1
1.4.0
1.3.0
1.2.3
1.2.2
1.2.1
1.2.0
1.1.3
1.1.2
1.1.1
1.1.0
1.0.0
1.0.0-pre.18
1.0.0-pre.17
1.0.0-pre.16
1.0.0-pre.15
1.0.0-pre.14
1.0.0-pre.13
1.0.0-pre.12
1.0.0-pre.11
1.0.0-pre.10
1.0.0-pre.9
1.0.0-pre.8
1.0.0-pre.7
1.0.0-pre.6
1.0.0-pre.5
1.0.0-pre.4
1.0.0-pre.3
1.0.0-pre.2
1.0.0-pre.1
0.7.7
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.11
0.6.10
0.6.9
0.6.8
0.6.7
0.6.6
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.11
0.5.10
0.5.9
0.5.8
0.5.7
0.5.6
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.10
0.4.9
0.4.8
0.4.7
0.4.6
0.4.5
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.9
0.3.8
0.3.7
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.2.3
0.2.2
0.2.1
0.2.0
0.1.1
0.1.0
A pure-Elixir HTTP server built for Plug & WebSock apps
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/bandit/http2/frame/data.ex
defmodule Bandit.HTTP2.Frame.Data do
@moduledoc false
import Bandit.HTTP2.Frame.Flags
defstruct stream_id: nil,
end_stream: false,
data: nil
@typedoc "An HTTP/2 DATA frame"
@type t :: %__MODULE__{
stream_id: Bandit.HTTP2.Stream.stream_id(),
end_stream: boolean(),
data: iodata()
}
@end_stream_bit 0
@padding_bit 3
@spec deserialize(Bandit.HTTP2.Frame.flags(), Bandit.HTTP2.Stream.stream_id(), iodata()) ::
{:ok, t()} | {:error, Bandit.HTTP2.Errors.error_code(), binary()}
def deserialize(_flags, 0, _payload) do
{:error, Bandit.HTTP2.Errors.protocol_error(), "DATA frame with zero stream_id (RFC9113§6.1)"}
end
def deserialize(flags, stream_id, <<padding_length::8, rest::binary>>)
when set?(flags, @padding_bit) and byte_size(rest) >= padding_length do
{:ok,
%__MODULE__{
stream_id: stream_id,
end_stream: set?(flags, @end_stream_bit),
data: binary_part(rest, 0, byte_size(rest) - padding_length)
}}
end
def deserialize(flags, stream_id, <<data::binary>>) when clear?(flags, @padding_bit) do
{:ok,
%__MODULE__{
stream_id: stream_id,
end_stream: set?(flags, @end_stream_bit),
data: data
}}
end
def deserialize(flags, _stream_id, <<_padding_length::8, _rest::binary>>)
when set?(flags, @padding_bit) do
{:error, Bandit.HTTP2.Errors.protocol_error(),
"DATA frame with invalid padding length (RFC9113§6.1)"}
end
defimpl Bandit.HTTP2.Frame.Serializable do
@end_stream_bit 0
def serialize(%Bandit.HTTP2.Frame.Data{} = frame, max_frame_size) do
data_length = IO.iodata_length(frame.data)
if data_length <= max_frame_size do
flags = if frame.end_stream, do: [@end_stream_bit], else: []
[{0x0, set(flags), frame.stream_id, frame.data}]
else
<<this_frame::binary-size(max_frame_size), rest::binary>> =
IO.iodata_to_binary(frame.data)
[
{0x0, 0x00, frame.stream_id, this_frame}
| Bandit.HTTP2.Frame.Serializable.serialize(
%Bandit.HTTP2.Frame.Data{
stream_id: frame.stream_id,
end_stream: frame.end_stream,
data: rest
},
max_frame_size
)
]
end
end
end
end