Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

SSL Multipart post bug fix/workaround and test case.

  • Loading branch information...
commit 302381cca9b3cc6e62df4b75c01cc77dd95c8676 1 parent faef983
Jean-Charles Campagne authored
View
10 src/yaws_server.erl
@@ -2567,12 +2567,20 @@ del_old_files(_GC, [{_FileAtom, spec, _Mtime1, Spec, _}]) ->
end, Spec).
+unwrap_clisock(CliSock) when is_port(CliSock) -> CliSock;
+unwrap_clisock(CliSock0) ->
+ case CliSock0 of
+ {sslsocket, _, _} -> CliSock0;
+ {ssl, CliSock} -> CliSock
+ end.
+
get_client_data(CliSock, Len, SSlBool) ->
get_client_data(CliSock, Len, [], SSlBool).
get_client_data(_CliSock, 0, Bs, _SSlBool) ->
list_to_binary(Bs);
-get_client_data(CliSock, Len, Bs, SSlBool) ->
+get_client_data(CliSock0, Len, Bs, SSlBool) ->
+ CliSock = unwrap_clisock(CliSock0),
case yaws:cli_recv(CliSock, Len, SSlBool) of
{ok, B} ->
get_client_data(CliSock, Len-size(B), [Bs,B], SSlBool);
View
11 test/conf/stdconf.conf
@@ -208,3 +208,14 @@ keepalive_timeout = 10000
depth = 0
</ssl>
</server>
+<server localhost>
+ port = 8444
+ listen = 0.0.0.0
+ docroot = %YTOP%/test/t2/www
+ auth_log = true
+ <ssl>
+ keyfile = %YTOP%/ssl/yaws-key.pem
+ certfile = %YTOP%/ssl/yaws-cert.pem
+ depth = 0
+ </ssl>
+</server>
View
22 test/t2/app_test.erl
@@ -31,6 +31,7 @@ start() ->
test_arg_rewrite(),
test_shaper(),
test_sslaccept_timeout(),
+ test_ssl_multipart_post(),
test_throw(),
test_too_many_headers(),
test_index_files(),
@@ -808,6 +809,27 @@ test_sslaccept_timeout() ->
gen_tcp:close(Sock),
ok.
+test_ssl_multipart_post() ->
+ io:format("ssl_multipart_post_test\n", []),
+ ok = application:start(crypto),
+ ok = application:start(public_key),
+ ok = application:start(ssl),
+ Boundary = "----------------------------3e9876546ecf\r\n",
+ {ok, Bin0} = file:read_file("../../www/1000.txt"),
+ Data = list_to_binary([Boundary, Bin0]),
+ Size = size(Data),
+ Headers = [
+ {'Content-Type', "multipart/form-data; Boundary=" ++ Boundary},
+ {'Content-Length', Size}
+ ],
+ Uri = "https://localhost:8444/test_upload_ssl.yaws",
+ Options = [{is_ssl, true}, {ssl_options, [{verify, 0}]}],
+ ?line {ok, "200", _, _} = Reply = ibrowse:send_req(Uri, Headers, post, Data, Options),
+ ok = application:stop(ssl),
+ ok = application:stop(public_key),
+ ok = application:stop(crypto),
+ ok.
+
test_throw() ->
io:format("throw test\n", []),
Uri = "http://localhost:8009/",
View
65 test/t2/www/test_upload_ssl.yaws
@@ -0,0 +1,65 @@
+<erl>
+%% inspired from upload.yaws, slightly simplified.
+
+-record(state, {acc,
+ last
+ }).
+
+out(A) ->
+ %% make sure it is post method
+ 'POST' = yaws_api:http_request_method(yaws_api:arg_req(A)),
+ case get_props(A) of
+ {error, Reason} ->
+ {ehtml, "error"};
+ {get_more, Cont, NewState} = GetMore ->
+ GetMore;
+ {ok, AllParts} ->
+ {ehtml, "ok"}
+ end.
+
+
+get_state(A) ->
+ case A#arg.state of
+ undefined -> #state{acc = [], last = false};
+ State0 -> State0
+ end.
+
+
+get_props(A) ->
+ Parse = yaws_api:parse_multipart_post(A),
+ State = get_state(A),
+ case Parse of
+ {cont, Cont, Res} ->
+ case add_file_chunk(A, Res, State) of
+ {done, Result} ->
+ error_logger:info_msg("Ok, got: ~p", [Result]),
+ {ok, Result};
+ {cont, NewState} ->
+ {get_more, Cont, NewState}
+ end;
+ {result, Res} ->
+ case add_file_chunk(A, Res, State#state{last = true}) of
+ {done, Result} -> {ok, Result};
+ {cont, _} -> {error, ooops}
+ end;
+ {error, Reason} = Error ->
+ io:format("Error : ~p", [Reason]),
+ Error
+ end.
+
+
+add_file_chunk(A, [H | Tail], #state{acc = Acc0} = State0) ->
+ Acc1 = [H | Acc0],
+ State1 = State0#state{acc = Acc1},
+ add_file_chunk(A, Tail, State1);
+add_file_chunk(A, [], #state{last = false} = State) ->
+ {cont, State};
+add_file_chunk(A, [], #state{last = true, acc = RAcc} = State) ->
+ Data = lists:reverse(RAcc),
+ {done, Data}.
+
+
+</erl>
+
+
+
Please sign in to comment.
Something went wrong with that request. Please try again.