mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-15 20:50:24 +00:00
Add multipart support
This commit is contained in:
parent
a5b47fda8d
commit
528507c7de
7 changed files with 382 additions and 6 deletions
|
@ -1,4 +1,5 @@
|
|||
%% Copyright (c) 2011, Loïc Hoguin <essen@dev-extend.eu>
|
||||
%% Copyright (c) 2011, Anthony Ramine <nox@dev-extend.eu>
|
||||
%%
|
||||
%% Permission to use, copy, modify, and/or distribute this software for any
|
||||
%% purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -19,7 +20,7 @@
|
|||
-export([all/0, groups/0, init_per_suite/1, end_per_suite/1,
|
||||
init_per_group/2, end_per_group/2]). %% ct.
|
||||
-export([chunked_response/1, headers_dupe/1, headers_huge/1,
|
||||
keepalive_nl/1, nc_rand/1, nc_zero/1, pipeline/1, raw/1,
|
||||
keepalive_nl/1, multipart/1, nc_rand/1, nc_zero/1, pipeline/1, raw/1,
|
||||
ws0/1, ws8/1, ws8_single_bytes/1, ws8_init_shutdown/1,
|
||||
ws13/1, ws_timeout_hibernate/1]). %% http.
|
||||
-export([http_200/1, http_404/1]). %% http and https.
|
||||
|
@ -35,7 +36,7 @@ groups() ->
|
|||
[{http, [], [chunked_response, headers_dupe, headers_huge,
|
||||
keepalive_nl, nc_rand, nc_zero, pipeline, raw,
|
||||
ws0, ws8, ws8_single_bytes, ws8_init_shutdown, ws13,
|
||||
ws_timeout_hibernate] ++ BaseTests},
|
||||
ws_timeout_hibernate, multipart] ++ BaseTests},
|
||||
{https, [], BaseTests}, {misc, [], [http_10_hostless]}].
|
||||
|
||||
init_per_suite(Config) ->
|
||||
|
@ -100,6 +101,7 @@ init_http_dispatch() ->
|
|||
{[<<"long_polling">>], http_handler_long_polling, []},
|
||||
{[<<"headers">>, <<"dupe">>], http_handler,
|
||||
[{headers, [{<<"Connection">>, <<"close">>}]}]},
|
||||
{[<<"multipart">>], http_handler_multipart, []},
|
||||
{[], http_handler, []}
|
||||
]}
|
||||
].
|
||||
|
@ -148,6 +150,24 @@ keepalive_nl_loop(Socket, N) ->
|
|||
ok = gen_tcp:send(Socket, "\r\n"), %% extra nl
|
||||
keepalive_nl_loop(Socket, N - 1).
|
||||
|
||||
multipart(Config) ->
|
||||
Url = build_url("/multipart", Config),
|
||||
Body = <<
|
||||
"This is a preamble."
|
||||
"\r\n--OHai\r\nX-Name:answer\r\n\r\n42"
|
||||
"\r\n--OHai\r\nServer:Cowboy\r\n\r\nIt rocks!\r\n"
|
||||
"\r\n--OHai--"
|
||||
"This is an epiloque."
|
||||
>>,
|
||||
Request = {Url, [], "multipart/x-makes-no-sense; boundary=OHai", Body},
|
||||
{ok, {{"HTTP/1.1", 200, "OK"}, _Headers, Response}} =
|
||||
httpc:request(post, Request, [], [{body_format, binary}]),
|
||||
Parts = binary_to_term(Response),
|
||||
Parts = [
|
||||
{[{<<"X-Name">>, <<"answer">>}], <<"42">>},
|
||||
{[{'Server', <<"Cowboy">>}], <<"It rocks!\r\n">>}
|
||||
].
|
||||
|
||||
nc_rand(Config) ->
|
||||
nc_reqs(Config, "/dev/urandom").
|
||||
|
||||
|
|
29
test/http_handler_multipart.erl
Normal file
29
test/http_handler_multipart.erl
Normal file
|
@ -0,0 +1,29 @@
|
|||
%% Feel free to use, reuse and abuse the code in this file.
|
||||
|
||||
-module(http_handler_multipart).
|
||||
-behaviour(cowboy_http_handler).
|
||||
-export([init/3, handle/2, terminate/2]).
|
||||
|
||||
init({_Transport, http}, Req, []) ->
|
||||
{ok, Req, {}}.
|
||||
|
||||
handle(Req, State) ->
|
||||
{Result, Req2} = acc_multipart(Req, []),
|
||||
{ok, Req3} = cowboy_http_req:reply(200, [], term_to_binary(Result), Req2),
|
||||
{ok, Req, State}.
|
||||
|
||||
terminate(_Req, _State) ->
|
||||
ok.
|
||||
|
||||
acc_multipart(Req, Acc) ->
|
||||
{Result, Req2} = cowboy_http_req:multipart_data(Req),
|
||||
acc_multipart(Req2, Acc, Result).
|
||||
|
||||
acc_multipart(Req, Acc, {headers, Headers}) ->
|
||||
acc_multipart(Req, [{Headers, []}|Acc]);
|
||||
acc_multipart(Req, [{Headers, BodyAcc}|Acc], {body, Data}) ->
|
||||
acc_multipart(Req, [{Headers, [Data|BodyAcc]}|Acc]);
|
||||
acc_multipart(Req, [{Headers, BodyAcc}|Acc], end_of_part) ->
|
||||
acc_multipart(Req, [{Headers, list_to_binary(lists:reverse(BodyAcc))}|Acc]);
|
||||
acc_multipart(Req, Acc, eof) ->
|
||||
{lists:reverse(Acc), Req}.
|
Loading…
Add table
Add a link
Reference in a new issue