leifg
leifg

Reputation: 9028

Phoenix tests don't accept capitalized response Headers

I've been playing around with Phoenix and I want to provide a download link to a PDF file:

The following code works fine in my dev environment. When I click on the link a PDF file is downloaded.

case  File.read(localpath) do
  {:ok, pdf_content} ->
    conn
    |> put_resp_header("Content-Type", "application/pdf")
    |> put_resp_header("Content-Disposition", ~s[attachment; filename="#{file}"])
    |>200, pdf_content)
  {:error, _} ->
    conn
    |>:not_found, "Not Found")
end

However when I run tests to verify the behaviour I'll get an error:

 ** (Plug.Conn.InvalidHeaderError) header key is not lowercase: "Content-Type"
 stacktrace:
   (plug) lib/plug/conn.ex:957: Plug.Conn.validate_header_key!/2
   (plug) lib/plug/conn.ex:556: Plug.Conn.put_resp_header/3

This seems weird to me for 2 reasons:

  1. Why has the Header have to be in lower characters?
  2. Why is the behaviour different in dev and in test environment?

Upvotes: 2

Views: 750

Answers (2)

Ambareesha Av
Ambareesha Av

Reputation: 21

if anyone looking for ways to pass the test, this is how I passed the test

   conn
    |> put_resp_header("content-type", "application/pdf")
    |> put_resp_header("content-disposition", "attachment; filename=#{filename}")
    |> resp(200, pdf_binary)

I made header keys to lower-case in my respective controller

Upvotes: 0

whatyouhide
whatyouhide

Reputation: 16781

The reason this error is only raised in the test environment can be seen in the source code for Plug.Conn, specifically these lines:

defp validate_header_key!({Plug.Adapters.Test.Conn, _}, key) do
  unless valid_header_key?(key) do
    raise InvalidHeaderError, message: "header key is not lowercase: " <> inspect(key)
  end
end

defp validate_header_key!(_adapter, _key) do
  :ok
end

As this code shows, the header key is actually validated only if the adapter is Plug's test adapter. The reason this only happens in the test environment is because it can be expensive to perform these validations on the headers and so they are skipped in non-test environments. This commit is the commit where the restriction on validating only in the test environment was introduced.

By the way, the header doesn't have to be lowercase (as you can tell by the fact that it works in non-test environments), but I think that by Plug's convention it should be.

Upvotes: 4

Related Questions