From 4aaadc75abce9a6d662b807df92989505cba4a49 Mon Sep 17 00:00:00 2001 From: Filipe David Borba Manana Date: Thu, 20 Jan 2011 15:28:55 +0000 Subject: Merge revision 1061340 from trunk Upgrade ibrowse to version 2.1.3 This version fixes several bugs and adds a few minor improvements. For a list and description of the changes relative to the previous version, see the README file at: https://github.com/cmullaparthi/ibrowse git-svn-id: https://svn.apache.org/repos/asf/couchdb/branches/1.1.x@1061341 13f79535-47bb-0310-9956-ffa450edef68 --- src/ibrowse/Makefile.am | 2 +- src/ibrowse/ibrowse.app.in | 2 +- src/ibrowse/ibrowse.erl | 18 +++++----- src/ibrowse/ibrowse_http_client.erl | 65 ++++++++++++++++++++----------------- src/ibrowse/ibrowse_test.erl | 40 ++++++++++------------- 5 files changed, 64 insertions(+), 63 deletions(-) (limited to 'src/ibrowse') diff --git a/src/ibrowse/Makefile.am b/src/ibrowse/Makefile.am index 4cebe5d1..bfd52ba2 100644 --- a/src/ibrowse/Makefile.am +++ b/src/ibrowse/Makefile.am @@ -10,7 +10,7 @@ ## License for the specific language governing permissions and limitations under ## the License. -ibrowseebindir = $(localerlanglibdir)/ibrowse-2.1.2/ebin +ibrowseebindir = $(localerlanglibdir)/ibrowse-2.1.3/ebin ibrowse_file_collection = \ ibrowse.app.in \ diff --git a/src/ibrowse/ibrowse.app.in b/src/ibrowse/ibrowse.app.in index c8e42271..875620dd 100644 --- a/src/ibrowse/ibrowse.app.in +++ b/src/ibrowse/ibrowse.app.in @@ -1,6 +1,6 @@ {application, ibrowse, [{description, "HTTP client application"}, - {vsn, "2.1.2"}, + {vsn, "2.1.3"}, {modules, [ ibrowse, ibrowse_http_client, ibrowse_app, diff --git a/src/ibrowse/ibrowse.erl b/src/ibrowse/ibrowse.erl index e1051504..f70f92f1 100644 --- a/src/ibrowse/ibrowse.erl +++ b/src/ibrowse/ibrowse.erl @@ -6,8 +6,8 @@ %%% Created : 11 Oct 2003 by Chandrashekhar Mullaparthi %%%------------------------------------------------------------------- %% @author Chandrashekhar Mullaparthi -%% @copyright 2005-2010 Chandrashekhar Mullaparthi -%% @version 2.1.2 +%% @copyright 2005-2011 Chandrashekhar Mullaparthi +%% @version 2.1.3 %% @doc The ibrowse application implements an HTTP 1.1 client in erlang. This %% module implements the API of the HTTP client. There is one named %% process called 'ibrowse' which assists in load balancing and maintaining configuration. There is one load balancing process per unique webserver. There is @@ -683,16 +683,16 @@ init(_) -> State = #state{}, put(my_trace_flag, State#state.trace), put(ibrowse_trace_token, "ibrowse"), - ets:new(ibrowse_lb, [named_table, public, {keypos, 2}]), - ets:new(ibrowse_conf, [named_table, protected, {keypos, 2}]), - ets:new(ibrowse_stream, [named_table, public]), + ibrowse_lb = ets:new(ibrowse_lb, [named_table, public, {keypos, 2}]), + ibrowse_conf = ets:new(ibrowse_conf, [named_table, protected, {keypos, 2}]), + ibrowse_stream = ets:new(ibrowse_stream, [named_table, public]), import_config(), {ok, #state{}}. import_config() -> case code:priv_dir(ibrowse) of - {error, _} = Err -> - Err; + {error, _} -> + ok; PrivDir -> Filename = filename:join(PrivDir, "ibrowse.conf"), import_config(Filename) @@ -723,8 +723,8 @@ import_config(Filename) -> io:format("Skipping unrecognised term: ~p~n", [X]) end, lists:foreach(Fun, Terms); - Err -> - Err + _Err -> + ok end. %% @doc Internal export diff --git a/src/ibrowse/ibrowse_http_client.erl b/src/ibrowse/ibrowse_http_client.erl index 5dce321c..7d606e61 100644 --- a/src/ibrowse/ibrowse_http_client.erl +++ b/src/ibrowse/ibrowse_http_client.erl @@ -188,7 +188,7 @@ handle_info({stream_next, Req_id}, #state{socket = Socket, cur_req = #request{req_id = Req_id}} = State) -> %% io:format("Client process set {active, once}~n", []), do_setopts(Socket, [{active, once}], State), - {noreply, State}; + {noreply, set_inac_timer(State)}; handle_info({stream_next, _Req_id}, State) -> _Cur_req_id = case State#state.cur_req of @@ -216,12 +216,14 @@ handle_info({ssl_closed, _Sock}, State) -> handle_sock_closed(State), {stop, normal, State}; -handle_info({tcp_error, _Sock}, State) -> - do_trace("Error on connection to ~1000.p:~1000.p~n", [State#state.host, State#state.port]), +handle_info({tcp_error, _Sock, Reason}, State) -> + do_trace("Error on connection to ~1000.p:~1000.p -> ~1000.p~n", + [State#state.host, State#state.port, Reason]), handle_sock_closed(State), {stop, normal, State}; -handle_info({ssl_error, _Sock}, State) -> - do_trace("Error on SSL connection to ~1000.p:~1000.p~n", [State#state.host, State#state.port]), +handle_info({ssl_error, _Sock, Reason}, State) -> + do_trace("Error on SSL connection to ~1000.p:~1000.p -> ~1000.p~n", + [State#state.host, State#state.port, Reason]), handle_sock_closed(State), {stop, normal, State}; @@ -334,8 +336,13 @@ handle_sock_data(Data, #state{status = get_body, active_once(State_1) end, State_2 = State_1#state{interim_reply_sent = false}, - State_3 = set_inac_timer(State_2), - {noreply, State_3}; + case Ccs of + true -> + cancel_timer(State_2#state.inactivity_timer_ref, {eat_message, timeout}), + {noreply, State_2#state{inactivity_timer_ref = undefined}}; + _ -> + {noreply, set_inac_timer(State_2)} + end; State_1 -> active_once(State_1), State_2 = set_inac_timer(State_1), @@ -461,7 +468,7 @@ handle_sock_closed(#state{reply_buffer = Buf, reqs = Reqs, http_status_code = SC undefined -> Buf; _ -> - file:close(Fd), + ok = file:close(Fd), {file, TmpFilename} end, Reply = case get_value(give_raw_headers, Options, false) of @@ -470,11 +477,11 @@ handle_sock_closed(#state{reply_buffer = Buf, reqs = Reqs, http_status_code = SC false -> {ok, SC, Headers, Buf} end, - do_reply(State, From, StreamTo, ReqId, Resp_format, Reply), - do_error_reply(State#state{reqs = Reqs_1}, connection_closed), - State; + State_1 = do_reply(State, From, StreamTo, ReqId, Resp_format, Reply), + ok = do_error_reply(State_1#state{reqs = Reqs_1}, connection_closed), + State_1; _ -> - do_error_reply(State, connection_closed), + ok = do_error_reply(State, connection_closed), State end. @@ -482,17 +489,19 @@ do_connect(Host, Port, Options, #state{is_ssl = true, use_proxy = false, ssl_options = SSLOptions}, Timeout) -> - Caller_socket_options = get_value(socket_options, Options, []), - Other_sock_options = filter_sock_options(SSLOptions ++ Caller_socket_options), - ssl:connect(Host, Port, - [binary, {nodelay, true}, {active, false} | Other_sock_options], - Timeout); + ssl:connect(Host, Port, get_sock_options(Options, SSLOptions), Timeout); do_connect(Host, Port, Options, _State, Timeout) -> + gen_tcp:connect(Host, Port, get_sock_options(Options, []), Timeout). + +get_sock_options(Options, SSLOptions) -> Caller_socket_options = get_value(socket_options, Options, []), - Other_sock_options = filter_sock_options(Caller_socket_options), - gen_tcp:connect(Host, to_integer(Port), - [binary, {nodelay, true}, {active, false} | Other_sock_options], - Timeout). + Other_sock_options = filter_sock_options(SSLOptions ++ Caller_socket_options), + case lists:keysearch(nodelay, 1, Other_sock_options) of + false -> + [{nodelay, true}, binary, {active, false} | Other_sock_options]; + {value, _} -> + [binary, {active, false} | Other_sock_options] + end. %% We don't want the caller to specify certain options filter_sock_options(Opts) -> @@ -547,7 +556,7 @@ do_send_body1(Source, Resp, State, TE) -> maybe_chunked_encode(Data, false) -> Data; maybe_chunked_encode(Data, true) -> - [?dec2hex(size(to_binary(Data))), "\r\n", Data, "\r\n"]. + [?dec2hex(iolist_size(Data)), "\r\n", Data, "\r\n"]. do_close(#state{socket = undefined}) -> ok; do_close(#state{socket = Sock, @@ -1269,7 +1278,7 @@ handle_response(#request{from=From, stream_to=StreamTo, req_id=ReqId, reply_buffer = RepBuf, recvd_headers = RespHeaders}=State) when SaveResponseToFile /= false -> Body = RepBuf, - file:close(Fd), + ok = file:close(Fd), ResponseBody = case TmpFilename of undefined -> Body; @@ -1656,8 +1665,8 @@ fail_pipelined_requests(#state{reqs = Reqs, cur_req = CurReq} = State, Reply) -> {_, Reqs_1} = queue:out(Reqs), #request{from=From, stream_to=StreamTo, req_id=ReqId, response_format = Resp_format} = CurReq, - do_reply(State, From, StreamTo, ReqId, Resp_format, Reply), - do_error_reply(State#state{reqs = Reqs_1}, previous_request_failed). + State_1 = do_reply(State, From, StreamTo, ReqId, Resp_format, Reply), + do_error_reply(State_1#state{reqs = Reqs_1}, previous_request_failed). split_list_at(List, N) -> split_list_at(List, N, []). @@ -1701,7 +1710,8 @@ to_ascii($9) -> 9; to_ascii($0) -> 0. cancel_timer(undefined) -> ok; -cancel_timer(Ref) -> erlang:cancel_timer(Ref). +cancel_timer(Ref) -> _ = erlang:cancel_timer(Ref), + ok. cancel_timer(Ref, {eat_message, Msg}) -> cancel_timer(Ref), @@ -1814,8 +1824,5 @@ trace_request_body(Body) -> ok end. -to_integer(X) when is_list(X) -> list_to_integer(X); -to_integer(X) when is_integer(X) -> X. - to_binary(X) when is_list(X) -> list_to_binary(X); to_binary(X) when is_binary(X) -> X. diff --git a/src/ibrowse/ibrowse_test.erl b/src/ibrowse/ibrowse_test.erl index b8e0a4a5..ff3b5304 100644 --- a/src/ibrowse/ibrowse_test.erl +++ b/src/ibrowse/ibrowse_test.erl @@ -11,8 +11,6 @@ unit_tests/0, unit_tests/1, unit_tests_1/2, - drv_ue_test/0, - drv_ue_test/1, ue_test/0, ue_test/1, verify_chunked_streaming/0, @@ -21,7 +19,8 @@ i_do_async_req_list/4, test_stream_once/3, test_stream_once/4, - test_20122010/0 + test_20122010/0, + test_20122010/1 ]). test_stream_once(Url, Method, Options) -> @@ -413,20 +412,6 @@ execute_req(Url, Method, Options) -> io:format("~p~n", [Err]) end. -drv_ue_test() -> - drv_ue_test(lists:duplicate(1024, 127)). -drv_ue_test(Data) -> - [{port, Port}| _] = ets:lookup(ibrowse_table, port), -% erl_ddll:unload_driver("ibrowse_drv"), -% timer:sleep(1000), -% erl_ddll:load_driver("../priv", "ibrowse_drv"), -% Port = open_port({spawn, "ibrowse_drv"}, []), - {Time, Res} = timer:tc(ibrowse_lib, drv_ue, [Data, Port]), - io:format("Time -> ~p~n", [Time]), - io:format("Data Length -> ~p~n", [length(Data)]), - io:format("Res Length -> ~p~n", [length(Res)]). -% io:format("Result -> ~s~n", [Res]). - ue_test() -> ue_test(lists:duplicate(1024, $?)). ue_test(Data) -> @@ -445,11 +430,14 @@ log_msg(Fmt, Args) -> %%------------------------------------------------------------------------------ test_20122010() -> - {ok, Pid} = ibrowse:spawn_worker_process("http://localhost:8181"), + test_20122010("http://localhost:8181"). + +test_20122010(Url) -> + {ok, Pid} = ibrowse:spawn_worker_process(Url), Expected_resp = <<"1-2-3-4-5-6-7-8-9-10-11-12-13-14-15-16-17-18-19-20-21-22-23-24-25-26-27-28-29-30-31-32-33-34-35-36-37-38-39-40-41-42-43-44-45-46-47-48-49-50-51-52-53-54-55-56-57-58-59-60-61-62-63-64-65-66-67-68-69-70-71-72-73-74-75-76-77-78-79-80-81-82-83-84-85-86-87-88-89-90-91-92-93-94-95-96-97-98-99-100">>, Test_parent = self(), Fun = fun() -> - do_test_20122010(Pid, Expected_resp, Test_parent) + do_test_20122010(Url, Pid, Expected_resp, Test_parent) end, Pids = [erlang:spawn_monitor(Fun) || _ <- lists:seq(1,10)], wait_for_workers(Pids). @@ -458,18 +446,24 @@ wait_for_workers([{Pid, _Ref} | Pids]) -> receive {Pid, success} -> wait_for_workers(Pids) - after 5000 -> + after 60000 -> test_failed end; wait_for_workers([]) -> success. -do_test_20122010(Pid, Expected_resp, Test_parent) -> +do_test_20122010(Url, Pid, Expected_resp, Test_parent) -> + do_test_20122010(10, Url, Pid, Expected_resp, Test_parent). + +do_test_20122010(0, _Url, _Pid, _Expected_resp, Test_parent) -> + Test_parent ! {self(), success}; +do_test_20122010(Rem_count, Url, Pid, Expected_resp, Test_parent) -> {ibrowse_req_id, Req_id} = ibrowse:send_req_direct( Pid, - "http://localhost:8181/ibrowse_stream_once_chunk_pipeline_test", + Url ++ "/ibrowse_stream_once_chunk_pipeline_test", [], get, [], [{stream_to, {self(), once}}, + {inactivity_timeout, 10000}, {include_ibrowse_req_id, true}]), do_trace("~p -- sent request ~1000.p~n", [self(), Req_id]), Req_id_str = lists:flatten(io_lib:format("~1000.p",[Req_id])), @@ -491,7 +485,7 @@ do_test_20122010(Pid, Expected_resp, Test_parent) -> ok = ibrowse:stream_next(Req_id), case do_test_20122010_1(Expected_resp, Req_id, []) of true -> - Test_parent ! {self(), success}; + do_test_20122010(Rem_count - 1, Url, Pid, Expected_resp, Test_parent); false -> Test_parent ! {self(), failed} end. -- cgit v1.2.3