Browse Source

Merge pull request #97 from stuart/master

Allow missing Content-Length for 303 response.
pull/108/head
Chandrashekhar Mullaparthi 11 years ago
parent
commit
d824491d37
3 changed files with 70 additions and 2 deletions
  1. +19
    -0
      src/ibrowse_http_client.erl
  2. +39
    -2
      test/ibrowse_test.erl
  3. +12
    -0
      test/ibrowse_test_server.erl

+ 19
- 0
src/ibrowse_http_client.erl View File

@ -1121,6 +1121,25 @@ parse_response(Data, #state{reply_buffer = Acc, reqs = Reqs,
ConnClose =:= "close" -> ConnClose =:= "close" ->
send_async_headers(ReqId, StreamTo, Give_raw_headers, State_1), send_async_headers(ReqId, StreamTo, Give_raw_headers, State_1),
State_1#state{reply_buffer = Data_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 -> undefined ->
fail_pipelined_requests(State_1, fail_pipelined_requests(State_1,
{error, {content_length_undefined, {error, {content_length_undefined,

+ 39
- 2
test/ibrowse_test.erl View File

@ -27,7 +27,11 @@
test_head_transfer_encoding/0, test_head_transfer_encoding/0,
test_head_transfer_encoding/1, test_head_transfer_encoding/1,
test_head_response_with_body/0, 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) -> test_stream_once(Url, Method, Options) ->
@ -233,7 +237,9 @@ dump_errors(Key, Iod) ->
{local_test_fun, test_20122010, []}, {local_test_fun, test_20122010, []},
{local_test_fun, test_pipeline_head_timeout, []}, {local_test_fun, test_pipeline_head_timeout, []},
{local_test_fun, test_head_transfer_encoding, []}, {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() -> unit_tests() ->
@ -476,6 +482,37 @@ test_head_response_with_body(Url) ->
{test_failed, Res} {test_failed, Res}
end. 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 %% Test what happens when the request at the head of a pipeline times out
%%------------------------------------------------------------------------------ %%------------------------------------------------------------------------------

+ 12
- 0
test/ibrowse_test_server.erl View File

@ -159,6 +159,18 @@ process_request(Sock, Sock_type,
uri = {abs_path, "/ibrowse_head_test"}}) -> 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">>, 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); 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) -> process_request(Sock, Sock_type, Req) ->
do_trace("Recvd req: ~p~n", [Req]), do_trace("Recvd req: ~p~n", [Req]),
Resp = <<"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n">>, Resp = <<"HTTP/1.1 200 OK\r\nContent-Length: 0\r\n\r\n">>,

Loading…
Cancel
Save