使用 hackney 流式传输文件

Streaming a file using hackney

我正在尝试使用 hackney 流式传输多部分表单。

这是我当前的代码:

method = :post
path = "https://httpbin.org/post"
req_headers = [
  {"Content-Type", "multipart/form-data"}
]

{:ok, pid} = :hackney.request(method, path, req_headers, :stream, [])

:hackney.send_multipart_body(pid, {:file, "/Users/gmile/.vimrc"})

{:ok, _status, _headers, pid} = :hackney.start_response(pid)

{:ok, body} = :hackney.body(pid)

:hackney.send_multipart_body/2 上,我看到异常:

** (ArgumentError) argument error
    :erlang.byte_size(nil)
    (hackney) src/hackney_multipart.erl:134: :hackney_multipart.mp_header/2
    (hackney) src/hackney_multipart.erl:239: :hackney_multipart.mp_file_header/2
    (hackney) src/hackney_request.erl:222: :hackney_request.stream_multipart/2
    (hackney) src/hackney.erl:432: anonymous fn/2 in :hackney.send_multipart_body/2
    read_and_stream.exs:13: (file)

问题:我做错了什么?

我的代码中显然存在错误,但由于关于 :hackney.send_multipart_body/2 的文档很少,我无法解决这个问题。


我开始调试了。

这是调用顺序中堆栈跟踪的执行路径:

  1. https://github.com/benoitc/hackney/blob/master/src/hackney.erl#L432
  2. https://github.com/benoitc/hackney/blob/master/src/hackney_request.erl#L222
  3. https://github.com/benoitc/hackney/blob/master/src/hackney_multipart.erl#L239
  4. https://github.com/benoitc/hackney/blob/master/src/hackney_multipart.erl#L134

如果我没理解错的话,应该在HTTP客户端进程中设置了一个Boundary变量。但是我似乎无法理解它的设置位置。

为了使用 :hackney.send_multipart_body/2,您的请求正文(第四个参数)应该是 :stream_multipart,而不是 :stream:

{:ok, pid} = :hackney.request(method, path, req_headers, :stream_multipart, [])