Plug.Conn.read_body/2
只讀取請求主體的一個塊。您需要遞歸調用它才能讀取所有內容。你也不需要寫一個解析器來閱讀大塊的正文(如果我正確理解你的問題,我不認爲解析器甚至可以這樣做)。如果請求的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字節的塊讀取主體(它不保證返回的二進制是完全一樣大小的要求)。隨着下面的請求登載有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
你沒讀完的請求。你只是讀1個字節。 – Aetherus
你想一次讀多少數據?一次1個字節直到完成? – Dogbert
我們正在發送一個請求中的事件流,我想要讀取每個SSE來單獨處理 –