Skip to content

Commit

Permalink
Merge pull request cmullaparthi#97 from stuart/master
Browse files Browse the repository at this point in the history
Allow missing Content-Length for 303 response.
  • Loading branch information
cmullaparthi committed Dec 18, 2013
2 parents fb97c66 + 26ce366 commit d824491
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 2 deletions.
19 changes: 19 additions & 0 deletions src/ibrowse_http_client.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,25 @@ parse_response(Data, #state{reply_buffer = Acc, reqs = Reqs,
ConnClose =:= "close" ->
send_async_headers(ReqId, StreamTo, Give_raw_headers, State_1),
State_1#state{reply_buffer = Data_1};
undefined when StatCode =:= "303" ->
%% Some servers send 303 requests without a body.
%% RFC2616 says that they SHOULD, but they dont.
case ibrowse:get_config_value(allow_303_with_no_body, false) of
false ->
fail_pipelined_requests(State_1,
{error, {content_length_undefined,
{stat_code, StatCode}, Headers}}),
{error, content_length_undefined};
true ->
{_, Reqs_1} = queue:out(Reqs),
send_async_headers(ReqId, StreamTo, Give_raw_headers, State_1),
State_1_1 = do_reply(State_1, From, StreamTo, ReqId, Resp_format,
{ok, StatCode, Headers_1, []}),
cancel_timer(T_ref, {eat_message, {req_timedout, From}}),
State_2 = reset_state(State_1_1),
State_3 = set_cur_request(State_2#state{reqs = Reqs_1}),
parse_response(Data_1, State_3)
end;
undefined ->
fail_pipelined_requests(State_1,
{error, {content_length_undefined,
Expand Down
41 changes: 39 additions & 2 deletions test/ibrowse_test.erl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@
test_head_transfer_encoding/0,
test_head_transfer_encoding/1,
test_head_response_with_body/0,
test_head_response_with_body/1
test_head_response_with_body/1,
test_303_response_with_no_body/0,
test_303_response_with_no_body/1,
test_303_response_with_a_body/0,
test_303_response_with_a_body/1
]).

test_stream_once(Url, Method, Options) ->
Expand Down Expand Up @@ -233,7 +237,9 @@ dump_errors(Key, Iod) ->
{local_test_fun, test_20122010, []},
{local_test_fun, test_pipeline_head_timeout, []},
{local_test_fun, test_head_transfer_encoding, []},
{local_test_fun, test_head_response_with_body, []}
{local_test_fun, test_head_response_with_body, []},
{local_test_fun, test_303_response_with_a_body, []}

]).

unit_tests() ->
Expand Down Expand Up @@ -476,6 +482,37 @@ test_head_response_with_body(Url) ->
{test_failed, Res}
end.

%%------------------------------------------------------------------------------
%% Test what happens when a 303 response has no body
%% Github issue #97
%% ------------------------------------------------------------------------------
test_303_response_with_no_body() ->
clear_msg_q(),
test_303_response_with_no_body("http://localhost:8181/ibrowse_303_no_body_test").

test_303_response_with_no_body(Url) ->
ibrowse:add_config([{allow_303_with_no_body, true}]),
case ibrowse:send_req(Url, [], post) of
{ok, "303", _, _} ->
success;
Res ->
{test_failed, Res}
end.

%% Make sure we don't break requests that do have a body.
test_303_response_with_a_body() ->
clear_msg_q(),
test_303_response_with_no_body("http://localhost:8181/ibrowse_303_with_body_test").

test_303_response_with_a_body(Url) ->
ibrowse:add_config([{allow_303_with_no_body, true}]),
case ibrowse:send_req(Url, [], post) of
{ok, "303", _, "abcde"} ->
success;
Res ->
{test_failed, Res}
end.

%%------------------------------------------------------------------------------
%% Test what happens when the request at the head of a pipeline times out
%%------------------------------------------------------------------------------
Expand Down
12 changes: 12 additions & 0 deletions test/ibrowse_test_server.erl
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,18 @@ process_request(Sock, Sock_type,
uri = {abs_path, "/ibrowse_head_test"}}) ->
Resp = <<"HTTP/1.1 200 OK\r\nServer: Apache-Coyote/1.1\r\nTransfer-Encoding: chunked\r\nDate: Wed, 04 Apr 2012 16:53:49 GMT\r\nConnection: close\r\n\r\n">>,
do_send(Sock, Sock_type, Resp);
process_request(Sock, Sock_type,
#request{method='POST',
headers = _Headers,
uri = {abs_path, "/ibrowse_303_no_body_test"}}) ->
Resp = <<"HTTP/1.1 303 See Other\r\nLocation: http://example.org\r\n">>,
do_send(Sock, Sock_type, Resp);
process_request(Sock, Sock_type,
#request{method='POST',
headers = _Headers,
uri = {abs_path, "/ibrowse_303_with_body_test"}}) ->
Resp = <<"HTTP/1.1 303 See Other\r\nLocation: http://example.org\r\nContent-Length: 5\r\n\r\nabcde">>,
do_send(Sock, Sock_type, Resp);
process_request(Sock, Sock_type, Req) ->
do_trace("Recvd req: ~p~n", [Req]),
Resp = <<"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n">>,
Expand Down

0 comments on commit d824491

Please sign in to comment.