[英]How to read small chunks of data in phoenix controller, using Plug.Conn
我的目標是能夠在phoenix控制器中處理分塊的HTTP請求。 我認為解決方案是使用Plug.Conn.read_body
但是我收到錯誤或超時。
目前我認為最好的解決方案是自定義解析器。
defmodule Plug.EventStreamParser do
@behaviour Plug.Parsers
alias Plug.Conn
def parse(conn, "text", "event-stream", _headers, _opts) do
Conn.read_body(conn, length: 2, read_length: 1, read_timeout: 1_000)
|> IO.inspect
{:ok, %{}, conn}
end
end
但是我總是在檢查線上得到{:error :timeout}
。
Plug.Conn.read_body/2
只讀取請求正文的一個塊。 您需要遞歸調用它才能讀取所有內容。 你也不需要編寫一個Parser來只讀塊(如果我正確理解你的問題,我認為Parser甚至不能這樣做); 如果請求的Content-Type
不是默認情況下Plug解析的,則可以從控制器調用Plug.Conn.read_body/2
。
這是一個從控制器遞歸調用Plug.Conn.read_body/2
的小實現:
defmodule MyApp.PageController do
use MyApp.Web, :controller
def index(conn, _params) do
{:ok, conn} = read_body(conn, [length: 1024, read_length: 1024], fn chunk ->
# We just print the size of each chunk we receive.
IO.inspect byte_size(chunk)
end)
text conn, "ok"
end
def read_body(conn, opts, f) do
case Plug.Conn.read_body(conn, opts) do
{:ok, binary, conn} ->
f.(binary)
{:ok, conn}
{:more, binary, conn} ->
f.(binary)
read_body(conn, opts, f)
{:error, term} ->
{:error, term}
end
end
end
這將以大約1024字節的塊的形式讀取正文(不能保證返回的二進制文件與請求的大小完全相同)。 使用以下請求POST 4000個字節:
$ head -c 4000 /dev/urandom | curl -XPOST http://localhost:4000 --data-binary @- -H 'Content-Type: application/vnd.me.raw'
ok
以下內容記錄到控制台:
[info] POST /
[debug] Processing by MyApp.PageController.index/2
Parameters: %{}
Pipelines: [:api]
1024
1024
1024
928
[info] Sent 200 in 3ms
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.