3
votes

I am sending am sending an image in the base64 form, then creating an image with it and sending it to AWS.

At first, I thought it was a Nginx issue. So I changed client_max_body_size to a max value, But it didn't work. I am still getting 413 Request Entity Too Large error.

It's only happening when I am sending a high-resolution image's Base64 string. As we are using a Plug to authenticate requests. I just found out about Plug Parser Behaviour. The Plug I have created is:

defmodule EvercamMediaWeb.AuthenticationPlug do
  import Plug.Conn

  def init(_opts) do
  end

  def call(conn, _) do
    api_id = extract_credential(conn, %{header: "x-api-id", query: "api_id"})
    api_key = extract_credential(conn, %{header: "x-api-key", query: "api_key"})
    token =
      conn
      |> extract_credential(%{header: "authorization", query: "authorization"})
      |> String.downcase
      |> String.replace_leading("bearer ", "")

    case EvercamMediaWeb.Auth.validate(api_id, api_key, token) do
      :valid ->
        conn
      {:valid, user} ->
        conn
        |> assign(:current_user, user)
      :invalid ->
        conn
        |> put_resp_content_type("application/json")
        |> resp(401, Poison.encode!(%{message: "Invalid API keys"}))
        |> send_resp
        |> halt
    end
  end

  defp extract_credential(conn, %{header: header_name, query: query_string_name}) do
    extract_credential_from_query_string(conn, query_string_name) || extract_credential_from_header(conn, header_name)
  end

  defp extract_credential_from_query_string(conn, query_string_name) do
    Map.get(conn.params, query_string_name)
  end

  defp extract_credential_from_header(conn, header_name) do
    conn
    |> Plug.Conn.get_req_header(header_name)
    |> List.first
    |> to_string
  end
end

How I can modify plug's behaviour to use :query_string_length &

 {:multipart, length: 20_000_000} # Increase to 20MB max upload

in the above Plug, So it may support for max size of string and also Upload to the max as well.

thanks in advance.

1

1 Answers

6
votes

In your MyAppWeb.Endpoint file you should have something like this to configure the parser:

plug Plug.Parsers,
  parsers: [:urlencoded, :multipart, :json],
  pass: ["*/*"],
  json_decoder: Poison

Change parsers to:

  parsers: [:urlencoded, 
           {:multipart, length: 20_000_000},
            :json]
  query_string_length: 1_000_000,