Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 34 additions & 24 deletions lib/reverse_proxy/runner.ex
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,39 @@ defmodule ReverseProxy.Runner do
|> process_response(conn)
end

@spec get_body(Conn.t) :: String.t
def get_body(conn) do
case conn.body_params do
%Plug.Conn.Unfetched{aspect: :body_params} ->
case Conn.read_body(conn) do
{:ok, body, _conn} ->
body
{:more, body, conn} ->
{:stream,
Stream.resource(
fn -> {body, conn} end,
fn
{body, conn} ->
{[body], conn}
nil ->
{:halt, nil}
conn ->
case Conn.read_body(conn) do
{:ok, body, _conn} ->
{[body], nil}
{:more, body, conn} ->
{[body], conn}
end
end,
fn _ -> nil end
)
}
end
_ -> # this makes the assumption that we are dealing with JSON
Poison.encode!(conn.body_params)
end
end

@spec prepare_request(String.t, Conn.t) :: {Atom.t,
String.t,
String.t,
Expand All @@ -42,30 +75,7 @@ defmodule ReverseProxy.Runner do
method = conn.method |> String.downcase |> String.to_atom
url = "#{prepare_server(conn.scheme, server)}#{conn.request_path}?#{conn.query_string}"
headers = conn.req_headers
body = case Conn.read_body(conn) do
{:ok, body, _conn} ->
body
{:more, body, conn} ->
{:stream,
Stream.resource(
fn -> {body, conn} end,
fn
{body, conn} ->
{[body], conn}
nil ->
{:halt, nil}
conn ->
case Conn.read_body(conn) do
{:ok, body, _conn} ->
{[body], nil}
{:more, body, conn} ->
{[body], conn}
end
end,
fn _ -> nil end
)
}
end
body = get_body(conn)

{method, url, body, headers}
end
Expand Down
1 change: 1 addition & 0 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ defmodule ReverseProxy.Mixfile do
[{:plug, "~> 1.2"},
{:cowboy, "~> 1.0"},
{:httpoison, "~> 0.9"},
{:poison, "~> 3.1"},

{:earmark, "~> 1.0", only: :dev},
{:ex_doc, "~> 0.14", only: :dev},
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"mime": {:hex, :mime, "1.0.1", "05c393850524767d13a53627df71beeebb016205eb43bfbd92d14d24ec7a1b51", [:mix], []},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []},
"plug": {:hex, :plug, "1.2.2", "cfbda521b54c92ab8ddffb173fbaabed8d8fc94bec07cd9bb58a84c1c501b0bd", [:mix], [{:cowboy, "~> 1.0", [hex: :cowboy, optional: true]}, {:mime, "~> 1.0", [hex: :mime, optional: false]}]},
"poison": {:hex, :poison, "3.0.0", "625ebd64d33ae2e65201c2c14d6c85c27cc8b68f2d0dd37828fde9c6920dd131", [:mix], []},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [], [], "hexpm"},
"ranch": {:hex, :ranch, "1.2.1", "a6fb992c10f2187b46ffd17ce398ddf8a54f691b81768f9ef5f461ea7e28c762", [:make], []},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.0", "edee20847c42e379bf91261db474ffbe373f8acb56e9079acb6038d4e0bf414f", [:make, :rebar], []},
"ssl_verify_hostname": {:hex, :ssl_verify_hostname, "1.0.5"}}
9 changes: 9 additions & 0 deletions test/fixtures/body.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
defmodule ReverseProxyTest.Body do
def request(_method, _url, body, _headers, _opts \\ []) do
{:ok, %{
:headers => [],
:status_code => 200,
:body => body
}}
end
end
20 changes: 20 additions & 0 deletions test/reverse_proxy/runner_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,26 @@ defmodule ReverseProxy.RunnerTest do
assert conn.resp_body == "8000001"
end

def parse(conn, opts \\ []) do
opts = opts
|> Keyword.put_new(:parsers, [:json])
|> Keyword.put_new(:json_decoder, Poison)
Plug.Parsers.call(conn, Plug.Parsers.init(opts))
end

test "retrieve/3 - body parsed with Poison" do
conn =
conn(:post, "/", "{\"test\": \"data\"}")
|> put_req_header("content-type", "application/json")
|> parse()
|> ReverseProxy.Runner.retreive(
["localhost"],
ReverseProxyTest.Body
)

assert conn.resp_body == "{\"test\":\"data\"}"
end

test "retrieve/3 - chunked response" do
conn =
conn(:get, "/")
Expand Down