使用Plug过滤API连接

时间:2017-08-01 12:31:22

标签: elixir phoenix-framework

我正在尝试过滤与API的连接。

mix.exs我已添加:

pipeline :some_validation do
  plug VerifyLogicPlug
end

### INSIDE MY SCOPE:

  pipe_through [:some_validation, :previous_pipeline]

我的插件如下:

defmodule VerifyLogicPlug do

  import Plug.Conn

  def init(options), do: options

  def call(conn, _options) do
    if some_logic do
      respond_blocked(conn)
    else
      conn # Continue the normal execution of the pipeline
    end
  end

  defp respond_blocked(conn) do
    response = %{
      error: %{
        status: 401,
        code: "BLOCKED",
        title: "BLOCKED"
      }
    }

    conn
    |> put_resp_content_type("application/json")
    |> send_resp(status, Poison.encode!(response))
    halt(conn) # I've tried both with and without this line
  end
end

我在API中获得了所需的响应:

{
    "error": {
        "title": "BLOCKED",
        "status": 401,
        "code": "BLOCKED"
    }
}

但是在服务器中我会遇到一些错误,具体取决于我是否使用halt(conn)。 使用halt(conn)

[error] #PID<0.1003.0> running MyProject.Endpoint terminated
Server: localhost:4000 (http)
Request: GET (...)
** (exit) an exception was raised:
    ** (Plug.Conn.NotSentError) a response was neither set nor sent from the connection

没有halt(conn)

[error] #PID<0.1404.0> running MyProject.Endpoint terminated
Server: localhost:4000 (http)
Request: GET (...)
** (exit) an exception was raised:
    ** (Plug.Conn.AlreadySentError) the response was already sent

我想要的(我认为)是使用halt(conn)但是没有获得Plug.Conn.NotSentError,因为正在发送回复。关于什么缺失的任何提示?

谢谢!

1 个答案:

答案 0 :(得分:1)

您要发送两次回复。

respond_block(我建议重命名为block_request)更改为:

conn
|> put_resp_content_type("application/json")
|> send_resp(status, Poison.encode!(response))
|> halt()