Current section
Files
Jump to
Current section
Files
lib/regc/oci/transport/http/response_parser.ex
defmodule Regc.Oci.Transport.Http.ResponseParser do
@moduledoc false
alias Regc.Oci.Transport.Response
alias Regc.Oci.Transport.Http.{BodyReader, Deadline, HeadReader, Socket}
@max_informational_responses 16
@body_statuses [200, 206]
@type socket :: Socket.t()
@type deadline :: Deadline.t()
@spec read(socket(), non_neg_integer() | :infinity, deadline()) ::
{:ok, Response.t()} | {:error, term()}
def read(socket, max_bytes, deadline) do
read(socket, max_bytes, deadline, @max_informational_responses)
end
defp read(socket, max_bytes, deadline, informational_left) do
with {:ok, status, headers} <- HeadReader.read(socket, deadline) do
cond do
status == 101 ->
{:error, :unsupported_protocol_switch}
status in 100..199 and informational_left == 0 ->
{:error, :too_many_informational_responses}
status in 100..199 ->
read(socket, max_bytes, deadline, informational_left - 1)
status in @body_statuses ->
with {:ok, body} <- BodyReader.read(socket, headers, max_bytes, deadline) do
{:ok, %Response{status: status, headers: headers, body: body}}
end
true ->
{:ok, %Response{status: status, headers: headers, body: ""}}
end
end
end
end