diff --git a/lib/plug/forward_request.ex b/lib/plug/forward_request.ex index e58582d..16dea76 100644 --- a/lib/plug/forward_request.ex +++ b/lib/plug/forward_request.ex @@ -10,6 +10,7 @@ defmodule Heimdall.Plug.ForwardRequest do """ import Rackla + import Plug.Conn @doc """ Init will reshape the data coming in from @@ -35,13 +36,29 @@ defmodule Heimdall.Plug.ForwardRequest do base <> request_path <> query_string end + defp set_headers(conn, headers) do + Enum.reduce(headers, conn, fn({key, value}, conn) -> + put_resp_header(conn, key, value) + end) + end + defp forward_conn(conn, forward_url) do {_, {:ok, forward_request}} = incoming_request_conn(conn) new_url = build_url(forward_url, conn) - forward_request - |> Map.put(:url, new_url) - |> request(follow_redirect: true, force_redirect: true) - |> response + rackla_response = + forward_request + |> Map.put(:url, new_url) + |> request(follow_redirect: true, force_redirect: true, full: true) + |> collect + case rackla_response do + %Rackla.Response{status: status, headers: headers, body: body} -> + conn + |> resp(status, body) + |> set_headers(headers) + other -> + conn + |> resp(500, "An error occured communicating with service, reason: #{inspect(other)}") + end end @doc """ diff --git a/mix.exs b/mix.exs index 4ae2b2d..04894aa 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Heimdall.Mixfile do def project do [ app: :heimdall, - version: "0.2.2", + version: "0.2.3", elixir: "~> 1.3", build_embedded: Mix.env == :prod, start_permanent: Mix.env == :prod, diff --git a/test/plug/forward_request_test.exs b/test/plug/forward_request_test.exs index be5d462..30ac127 100644 --- a/test/plug/forward_request_test.exs +++ b/test/plug/forward_request_test.exs @@ -3,6 +3,7 @@ defmodule Heimdall.Test.Plug.ForwardRequestTest do use Plug.Test import Plug.Test + import ExUnit.CaptureLog alias Heimdall.Plug.ForwardRequest @@ -49,6 +50,32 @@ defmodule Heimdall.Test.Plug.ForwardRequestTest do assert conn.status == 200 assert conn.resp_body == "forwarded" end + + test "forwards headers from response" do + forward_url = %{"forward_url" => "http://localhost:8088"} + conn = + :get + |> conn("http://localhost/forward-test/headers") + |> ForwardRequest.call(ForwardRequest.init(forward_url)) + + assert conn.status == 200 + assert conn.resp_body == "forwarded" + assert conn |> get_resp_header("x-test-forward") == ["forwarded"] + end + + test "gives 500 if cannot connect to service" do + forward_url = %{"forward_url" => "http://localhost:50000"} + + capture_log fn -> + conn = + :get + |> conn("http://localhost/forward-test") + |> ForwardRequest.call(ForwardRequest.init(forward_url)) + + assert conn.status == 500 + assert conn.resp_body != "forwarded" + end + end end test "changing the path info changes the request path" do diff --git a/test/test_router.ex b/test/test_router.ex index 7149910..8a069f4 100644 --- a/test/test_router.ex +++ b/test/test_router.ex @@ -14,6 +14,12 @@ defmodule Heimdall.Test.TestRouter do |> resp(200, "forwarded") end + get "/forward-test/headers" do + conn + |> put_resp_header("x-test-forward", "forwarded") + |> resp(200, "forwarded") + end + get "/test" do conn |> resp(200, "ok")