Заглушка эликсира: возврат перенаправления 302

#elixir #plug

#elixir #заглушка

Вопрос:

Я унаследовал проект, написанный на Elixir. По сути, это шлюз API. В этом случае мне нужно выполнить перенаправление с URL-адреса моего API Gateway на тот, на который перенаправляется URL-адрес назначения. Итак, ситуация такова.

Запрос к (API Gateway в Elixir)> отправляется на мой сервер, который возвращает 302 и перенаправляет на другой URL.

Я написал некоторый код, подобный этому:

 def index(%{query_string: query_string} = conn, data) do
  final_conn =
    case MyLib.index(data, [], query_string) do
      {:ok, %HTTPoison.Response{status_code: 200, body: body}} ->
        conn
        |> put_status(200)
        |> put_resp_content_type("application/vnd.api json")
        |> json(body)
      {:ok, %HTTPoison.Response{status_code: 500, body: body}} ->
        conn
        |> put_status(500)
        |> put_resp_content_type("application/vnd.api json")
        |> json(body)
      {:ok, %HTTPoison.Response{status_code: 302, body: body}} ->
        conn
        |> put_status(302)
        |> redirect(to: conn)
        |> Plug.Conn.halt()
      {:ok, %HTTPoison.Response{status_code: 303, body: body}} ->
        conn
        |> put_status(303)
        |> redirect(to: conn)
        |> Plug.Conn.halt()
      {:ok, %HTTPoison.Response{status_code: 404}} ->
        conn
        |> put_status(404)
        |> put_resp_content_type("application/vnd.api json")
        |> json(%{error_code: "404", reason_given: "Resource not found."})
      {:error, %HTTPoison.Error{reason: reason}} ->
        conn
        |> put_status(500)
        |> put_resp_content_type("application/vnd.api json")
        |> json(%{error_code: "500", reason_given: reason})
    end

    final_conn
  

где MyLib.index просто

 def index(conn, headers \ [], query_string) do
  HTTPoison.get(process_url("?#{query_string}"), headers)
end
  

Этот код корректно обрабатывает части ошибок, но я не могу заставить его работать для 301 или 302.

(Само собой разумеется, я никогда не видел Elixir в своей жизни).

Комментарии:

1. Что redirect(to: conn) предназначено для этого? Я привык видеть redirect(to: "some_actual_url.xyz")

2. Меня смущает ваше описание, например, «переходит на мой сервер» — существует ли более одного сервера? Есть ли тот, который не ваш? Можете ли вы пошагово описать запрос и объяснить желаемое поведение?

3. @PeacefulJames да, вы правы. То, что я пытаюсь сделать, это перенаправить на URL, на который перенаправляется прокси-URL. Пожалуйста, смотрите также Мой комментарий ниже, если это непонятно.

4. @Everett Да, у меня есть 2 конечные точки… Конечная точка шлюза api (эта в Elixir) является общедоступной, и она просто действует как прокси для другого сервера, который не является общедоступным. Эта конкретная конечная точка на частном внутреннем сервере возвращает 302 и перенаправляет на третий URL… (Прошу прощения за это, но это было сделано таким образом)… Итак, чего я пытаюсь добиться здесь, так это того, что общедоступной конечной точке сервера Elixir удается перенаправить внешнего вызывающего на этот конечный URL…

5. Я думаю, вы могли бы получить то, что хотите, если просто добавите :follow_redirect в свой вызов значение true HTTPoison.get/3 , например HTTPoison.get(process_url("?#{query_string}"), headers, follow_redirect: true) . (Я думаю, что HTTPoison не выполняет перенаправления по умолчанию)

Ответ №1:

Благодаря комментариям я попробовал другой подход. Проект, который я унаследовал, имеет множество специфических настроек для некоторых конечных точек, и в этом случае мне не понадобился ни один из них. Таким образом, единственным кодом, который мне был нужен, было следующее:

 def index(%{query_string: query_string} = conn, data) do
    redirect(conn, external: process_url("?#{query_string}"))
end
  

Спасибо всем за поддержку.