multipart_h.erl 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. %% This module reads a multipart body and echoes it back as an Erlang term.
  2. -module(multipart_h).
  3. -export([init/2]).
  4. init(Req0, State) ->
  5. {Result, Req} = case cowboy_req:binding(key, Req0) of
  6. undefined -> acc_multipart(Req0, []);
  7. <<"skip_body">> -> skip_body_multipart(Req0, []);
  8. <<"read_part2">> -> read_part2_multipart(Req0, []);
  9. <<"read_part_body2">> -> read_part_body2_multipart(Req0, [])
  10. end,
  11. {ok, cowboy_req:reply(200, #{}, term_to_binary(Result), Req), State}.
  12. acc_multipart(Req0, Acc) ->
  13. case cowboy_req:read_part(Req0) of
  14. {ok, Headers, Req1} ->
  15. {ok, Body, Req} = stream_body(Req1, <<>>),
  16. acc_multipart(Req, [{Headers, Body}|Acc]);
  17. {done, Req} ->
  18. {lists:reverse(Acc), Req}
  19. end.
  20. stream_body(Req0, Acc) ->
  21. case cowboy_req:read_part_body(Req0) of
  22. {more, Data, Req} ->
  23. stream_body(Req, << Acc/binary, Data/binary >>);
  24. {ok, Data, Req} ->
  25. {ok, << Acc/binary, Data/binary >>, Req}
  26. end.
  27. skip_body_multipart(Req0, Acc) ->
  28. case cowboy_req:read_part(Req0) of
  29. {ok, Headers, Req} ->
  30. skip_body_multipart(Req, [Headers|Acc]);
  31. {done, Req} ->
  32. {lists:reverse(Acc), Req}
  33. end.
  34. read_part2_multipart(Req0, Acc) ->
  35. case cowboy_req:read_part(Req0, #{length => 1, period => 1}) of
  36. {ok, Headers, Req1} ->
  37. {ok, Body, Req} = stream_body(Req1, <<>>),
  38. acc_multipart(Req, [{Headers, Body}|Acc]);
  39. {done, Req} ->
  40. {lists:reverse(Acc), Req}
  41. end.
  42. read_part_body2_multipart(Req0, Acc) ->
  43. case cowboy_req:read_part(Req0) of
  44. {ok, Headers, Req1} ->
  45. {ok, Body, Req} = stream_body2(Req1, <<>>),
  46. acc_multipart(Req, [{Headers, Body}|Acc]);
  47. {done, Req} ->
  48. {lists:reverse(Acc), Req}
  49. end.
  50. stream_body2(Req0, Acc) ->
  51. case cowboy_req:read_part_body(Req0, #{length => 1, period => 1}) of
  52. {more, Data, Req} ->
  53. stream_body(Req, << Acc/binary, Data/binary >>);
  54. {ok, Data, Req} ->
  55. {ok, << Acc/binary, Data/binary >>, Req}
  56. end.