[elixir! 54] Plug.Conn.read_body 的配置問題

需求

讀取 http 請求中的大數據, 每次讀取必定的體積.socket

Plug.Conn.read_body/2

@spec read_body(t(), Keyword.t()) ::
          {:ok, binary(), t()} | {:more, binary(), t()} | {:error, term()}

此函數有三個配置選項, 根據文檔, length: 表示這一次函數調用讀取數據的長度; read_length: 表示從底層的 socket 每次讀取數據的長度; read_timeout: 表示從底層的 socket 每次讀的 timeout.函數

測試

看起來很不錯, 但其實只能起到一個大概的做用, 不能相信它返回的數據必定小於某個大小.測試

咱們對不一樣的配置選項進行測試:大數據

# defp print_size(body, config), do: 
#   IO.inspect({byte_size(body), config})

body = :binary.copy("abcdefghij", 100_000)

assert {:more, body, conn} = read_body(conn, length: 0, read_length: 1_000)
print_size(body, {0, 1000})

assert {:more, body, conn} = read_body(conn, length: 5_000, read_length: 1_000)
print_size(body, {5000, 1000})

assert {:more, body, conn} = read_body(conn, length: 20_000, read_length: 1_000)
print_size(body, {20_000, 1000})

assert {:ok, body, conn} = read_body(conn, length: 2_000_000)
print_size(body, {2_000_000, nil})

第一次結果:code

{2766, {0, 1000}}
{5840, {5000, 1000}}
{20440, {20000, 1000}}
{970954, {2000000, nil}}

第二次結果:文檔

{2766, {0, 1000}}
{8760, {5000, 1000}}
{21900, {20000, 1000}}
{966574, {2000000, nil}}

注意到每次讀取到的數額都會比咱們設置的 length 大, 甚至大於 length + read_length. 因此這個配置是不可靠的, 若是想要精確地按長度處理 body 內的數據, 仍是須要進行進一步的分割操做.class

相關文章
相關標籤/搜索