Packages
plug
0.8.2
1.20.3
1.20.2
1.20.1
retired
1.20.0
retired
1.19.5
1.19.4
1.19.3
1.19.2
1.19.1
1.19.0
1.18.5
1.18.4
1.18.3
1.18.2
1.18.1
1.18.0
1.17.4
1.17.3
1.17.2
1.17.1
1.17.0
1.16.6
1.16.5
1.16.4
1.16.3
1.16.2
1.16.1
1.16.0
1.15.6
1.15.5
1.15.4
1.15.3
1.15.2
1.15.1
1.15.0
1.14.2
1.14.1
1.14.0
1.13.6
1.13.5
1.13.4
1.13.3
1.13.2
1.13.1
retired
1.13.0
retired
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
1.9.0
1.8.3
1.8.2
1.8.1
1.8.0
1.7.2
1.7.1
1.7.0
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.5.0-rc.2
1.5.0-rc.1
1.5.0-rc.0
1.4.5
1.4.4
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-rc.0
1.3.6
1.3.5
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.2.0-rc.0
1.1.9
1.1.8
1.1.7
1.1.6
1.1.5
1.1.4
1.1.3
1.1.2
1.1.1
1.1.0
1.0.6
1.0.5
1.0.4
1.0.3
1.0.2
1.0.1
1.0.0
0.14.0
0.13.1
0.13.0
0.12.2
0.12.1
0.12.0
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
Compose web applications with functions
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/plug/adapters/test/conn.ex
defmodule Plug.Adapters.Test.Conn do
@behaviour Plug.Conn.Adapter
@moduledoc false
## Test helpers
def conn(method, uri, body_or_params, opts) do
uri = URI.parse(uri)
method = method |> to_string |> String.upcase
{body, params, headers} = body_or_params(body_or_params, opts[:headers] || [])
state = %{method: method, params: params, req_body: body, chunks: nil}
%Plug.Conn{
adapter: {__MODULE__, state},
host: uri.host || "www.example.com",
method: method,
path_info: split_path(uri.path),
port: uri.port || 80,
req_headers: headers,
query_string: uri.query || "",
params: params || %Plug.Conn.Unfetched{aspect: :params},
scheme: (uri.scheme || "http") |> String.downcase |> String.to_atom
}
end
## Connection adapter
def send_resp(%{method: "HEAD"} = state, _status, _headers, _body),
do: {:ok, "", state}
def send_resp(%{} = state, _status, _headers, body),
do: {:ok, IO.iodata_to_binary(body), state}
def send_file(%{method: "HEAD"} = state, _status, _headers, _path, _offset, _length),
do: {:ok, "", state}
def send_file(%{} = state, _status, _headers, path, offset, length) do
%File.Stat{type: :regular, size: size} = File.stat!(path)
length =
cond do
length == :all -> size
is_integer(length) -> length
end
{:ok, data} = File.open!(path, [:read, :binary], fn device ->
:file.pread(device, offset, length)
end)
{:ok, data, state}
end
def send_chunked(state, _status, _headers),
do: {:ok, "", %{state | chunks: ""}}
def chunk(%{method: "HEAD"} = state, _body),
do: {:ok, "", state}
def chunk(%{chunks: chunks} = state, body) do
body = chunks <> IO.iodata_to_binary(body)
{:ok, body, %{state | chunks: body}}
end
def read_req_body(%{req_body: body} = state, opts \\ []) do
size = min(byte_size(body), Keyword.get(opts, :length, 8_000_000))
data = :binary.part(body, 0, size)
rest = :binary.part(body, size, byte_size(body) - size)
tag =
case rest do
"" -> :ok
_ -> :more
end
{tag, data, %{state | req_body: rest}}
end
def parse_req_multipart(%{params: multipart} = state, _limit, _callback) do
{:ok, multipart, %{state | params: nil}}
end
## Private helpers
defp body_or_params(nil, headers),
do: {"", nil, headers}
defp body_or_params(body, headers) when is_binary(body) do
unless List.keyfind(headers, "content-type", 0) do
raise ArgumentError, message: "a content-type header is required when setting the body in a test connection"
end
{body, nil, headers}
end
defp body_or_params(params, headers) when is_list(params) do
body_or_params(Enum.into(params, %{}), headers)
end
defp body_or_params(params, headers) when is_map(params) do
headers = :lists.keystore("content-type", 1, headers,
{"content-type", "multipart/mixed; charset: utf-8"})
{"", stringify_params(params), headers}
end
defp stringify_params([_|_] = params),
do: Enum.map(params, &stringify_params/1)
defp stringify_params(%{} = params),
do: Enum.into(params, %{}, &stringify_kv/1)
defp stringify_params(other),
do: other
defp stringify_kv({k, v}),
do: {to_string(k), stringify_params(v)}
defp split_path(path) do
segments = :binary.split(path, "/", [:global])
for segment <- segments, segment != "", do: segment
end
end