aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMikkel Jensen <[email protected]>2014-08-27 12:31:45 +0200
committerMikkel Jensen <[email protected]>2014-11-06 15:24:44 +0100
commitf87a4712a154664f640ad5078a4d282bb22795a2 (patch)
treec5aef65cc4fcd3e0fff6d8121467b8f4ae35758d
parentd544a494af4dbc810fc9c15eaf5cc050cced1501 (diff)
downloadcowlib-f87a4712a154664f640ad5078a4d282bb22795a2.tar.gz
cowlib-f87a4712a154664f640ad5078a4d282bb22795a2.tar.bz2
cowlib-f87a4712a154664f640ad5078a4d282bb22795a2.zip
No line break required after close-delimiter
RFC 1341 does not specify this and indeed some upload clients (for example Flash) do not terminate the request with line breaks
-rw-r--r--src/cow_multipart.erl52
1 files changed, 47 insertions, 5 deletions
diff --git a/src/cow_multipart.erl b/src/cow_multipart.erl
index c412497..d2b45a4 100644
--- a/src/cow_multipart.erl
+++ b/src/cow_multipart.erl
@@ -47,7 +47,7 @@
"\r\n"
"PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg\r\n"
"Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==\r\n"
- "--frontier--\r\n"
+ "--frontier--"
>>).
-define(TEST1_BOUNDARY, <<"frontier">>).
@@ -72,10 +72,32 @@
"\r\n"
"...contents of file2.gif...\r\n"
"--BbC04y--\r\n"
- "--AaB03x--\r\n"
+ "--AaB03x--"
>>).
-define(TEST2_BOUNDARY, <<"AaB03x">>).
+-define(TEST3_MIME, <<
+ "This is the preamble.\r\n"
+ "--boundary\r\n"
+ "Content-Type: text/plain\r\n"
+ "\r\n"
+ "This is the body of the message.\r\n"
+ "--boundary--"
+ "\r\nThis is the epilogue. Here it includes leading CRLF"
+>>).
+-define(TEST3_BOUNDARY, <<"boundary">>).
+
+-define(TEST4_MIME, <<
+ "This is the preamble.\r\n"
+ "--boundary\r\n"
+ "Content-Type: text/plain\r\n"
+ "\r\n"
+ "This is the body of the message.\r\n"
+ "--boundary--"
+ "\r\n"
+>>).
+-define(TEST4_BOUNDARY, <<"boundary">>).
+
%% Parsing.
%%
%% The multipart format is defined in RFC 2045.
@@ -98,7 +120,7 @@ parse_headers(<< "--", Stream/bits >>, Boundary) ->
BoundarySize = byte_size(Boundary),
case Stream of
%% Last boundary. Return the epilogue.
- << Boundary:BoundarySize/binary, "--\r\n", Stream2/bits >> ->
+ << Boundary:BoundarySize/binary, "--", Stream2/bits >> ->
{done, Stream2};
<< Boundary:BoundarySize/binary, Stream2/bits >> ->
%% We have all the headers only if there is a \r\n\r\n
@@ -144,7 +166,7 @@ skip_preamble(Stream, Boundary) ->
<< _:Start2/binary, Stream2/bits >> = Stream,
case Stream2 of
%% Last boundary. Return the epilogue.
- << "--\r\n", Stream3/bits >> ->
+ << "--", Stream3/bits >> ->
{done, Stream3};
_ ->
case binary:match(Stream, <<"\r\n\r\n">>) of
@@ -298,6 +320,26 @@ parse_interleaved_test() ->
{done, <<>>} = parse_headers(Rest4, ?TEST2_BOUNDARY),
ok.
+parse_epilogue_test() ->
+ H1 = [{<<"content-type">>, <<"text/plain">>}],
+ Body1 = <<"This is the body of the message.">>,
+ Epilogue = <<"\r\nThis is the epilogue. Here it includes leading CRLF">>,
+ {ok, H1, Rest} = parse_headers(?TEST3_MIME, ?TEST3_BOUNDARY),
+ {done, Body1, Rest2} = parse_body(Rest, ?TEST3_BOUNDARY),
+ done = parse_body(Rest2, ?TEST3_BOUNDARY),
+ {done, Epilogue} = parse_headers(Rest2, ?TEST3_BOUNDARY),
+ ok.
+
+parse_epilogue_crlf_test() ->
+ H1 = [{<<"content-type">>, <<"text/plain">>}],
+ Body1 = <<"This is the body of the message.">>,
+ Epilogue = <<"\r\n">>,
+ {ok, H1, Rest} = parse_headers(?TEST4_MIME, ?TEST4_BOUNDARY),
+ {done, Body1, Rest2} = parse_body(Rest, ?TEST4_BOUNDARY),
+ done = parse_body(Rest2, ?TEST4_BOUNDARY),
+ {done, Epilogue} = parse_headers(Rest2, ?TEST4_BOUNDARY),
+ ok.
+
parse_partial_test() ->
{ok, <<0:8000, "abcdef">>, <<"\rghij">>}
= parse_body(<<0:8000, "abcdef\rghij">>, <<"boundary">>),
@@ -376,7 +418,7 @@ headers_to_iolist([{N, V}|Tail], Acc) ->
-spec close(binary()) -> iodata().
close(Boundary) ->
- [<<"\r\n--">>, Boundary, <<"--\r\n">>].
+ [<<"\r\n--">>, Boundary, <<"--">>].
-ifdef(TEST).
build_test() ->