Browse Source

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

Mikkel Jensen 10 years ago
parent
commit
f87a4712a1
1 changed files with 47 additions and 5 deletions
  1. 47 5
      src/cow_multipart.erl

+ 47 - 5
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() ->