diff options
Diffstat (limited to 'lib/inets/src')
-rw-r--r-- | lib/inets/src/ftp/ftp.erl | 142 | ||||
-rw-r--r-- | lib/inets/src/http_client/httpc_handler.erl | 72 | ||||
-rw-r--r-- | lib/inets/src/http_client/httpc_internal.hrl | 6 | ||||
-rw-r--r-- | lib/inets/src/http_client/httpc_manager.erl | 46 | ||||
-rw-r--r-- | lib/inets/src/http_server/httpd_example.erl | 4 | ||||
-rw-r--r-- | lib/inets/src/inets_app/inets.app.src | 4 | ||||
-rw-r--r-- | lib/inets/src/inets_app/inets.appup.src | 16 |
7 files changed, 202 insertions, 88 deletions
diff --git a/lib/inets/src/ftp/ftp.erl b/lib/inets/src/ftp/ftp.erl index 520db1b457..5674599ac5 100644 --- a/lib/inets/src/ftp/ftp.erl +++ b/lib/inets/src/ftp/ftp.erl @@ -192,7 +192,12 @@ do_open(Pid, OpenOptions, TLSOpts) -> 'ok' | {'error', Reason :: 'euser' | common_reason()}. user(Pid, User, Pass) -> - call(Pid, {user, User, Pass}, atom). + case {is_name_sane(User), is_name_sane(Pass)} of + {true, true} -> + call(Pid, {user, User, Pass}, atom); + _ -> + {error, euser} + end. -spec user(Pid :: pid(), User :: string(), @@ -201,7 +206,12 @@ user(Pid, User, Pass) -> 'ok' | {'error', Reason :: 'euser' | common_reason()}. user(Pid, User, Pass, Acc) -> - call(Pid, {user, User, Pass, Acc}, atom). + case {is_name_sane(User), is_name_sane(Pass), is_name_sane(Acc)} of + {true, true, true} -> + call(Pid, {user, User, Pass, Acc}, atom); + _ -> + {error, euser} + end. %%-------------------------------------------------------------------------- @@ -216,7 +226,12 @@ user(Pid, User, Pass, Acc) -> 'ok' | {'error', Reason :: 'eacct' | common_reason()}. account(Pid, Acc) -> - call(Pid, {account, Acc}, atom). + case is_name_sane(Acc) of + true -> + call(Pid, {account, Acc}, atom); + _ -> + {error, eacct} + end. %%-------------------------------------------------------------------------- @@ -262,7 +277,12 @@ lpwd(Pid) -> 'ok' | {'error', Reason :: restriction_reason() | common_reason()}. cd(Pid, Dir) -> - call(Pid, {cd, Dir}, atom). + case is_name_sane(Dir) of + true -> + call(Pid, {cd, Dir}, atom); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -305,7 +325,12 @@ ls(Pid) -> {'error', Reason :: restriction_reason() | common_reason()}. ls(Pid, Dir) -> - call(Pid, {dir, long, Dir}, string). + case is_name_sane(Dir) of + true -> + call(Pid, {dir, long, Dir}, string); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -333,7 +358,12 @@ nlist(Pid) -> {'error', Reason :: restriction_reason() | common_reason()}. nlist(Pid, Dir) -> - call(Pid, {dir, short, Dir}, string). + case is_name_sane(Dir) of + true -> + call(Pid, {dir, short, Dir}, string); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -349,7 +379,12 @@ nlist(Pid, Dir) -> 'ok' | {'error', Reason :: restriction_reason() | common_reason()}. rename(Pid, Old, New) -> - call(Pid, {rename, Old, New}, string). + case {is_name_sane(Old), is_name_sane(New)} of + {true, true} -> + call(Pid, {rename, Old, New}, string); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -365,7 +400,12 @@ rename(Pid, Old, New) -> 'ok' | {'error', Reason :: restriction_reason() | common_reason()}. delete(Pid, File) -> - call(Pid, {delete, File}, string). + case is_name_sane(File) of + true -> + call(Pid, {delete, File}, string); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -380,7 +420,12 @@ delete(Pid, File) -> 'ok' | {'error', Reason :: restriction_reason() | common_reason()}. mkdir(Pid, Dir) -> - call(Pid, {mkdir, Dir}, atom). + case is_name_sane(Dir) of + true -> + call(Pid, {mkdir, Dir}, atom); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -395,7 +440,12 @@ mkdir(Pid, Dir) -> 'ok' | {'error', Reason :: restriction_reason() | common_reason()}. rmdir(Pid, Dir) -> - call(Pid, {rmdir, Dir}, atom). + case is_name_sane(Dir) of + true -> + call(Pid, {rmdir, Dir}, atom); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -437,7 +487,12 @@ recv(Pid, RemotFileName) -> 'ok' | {'error', Reason :: term()}. recv(Pid, RemotFileName, LocalFileName) -> - call(Pid, {recv, RemotFileName, LocalFileName}, atom). + case is_name_sane(RemotFileName) of + true -> + call(Pid, {recv, RemotFileName, LocalFileName}, atom); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -456,7 +511,12 @@ recv(Pid, RemotFileName, LocalFileName) -> {'error', Reason :: restriction_reason() | common_reason()}. recv_bin(Pid, RemoteFile) -> - call(Pid, {recv_bin, RemoteFile}, bin). + case is_name_sane(RemoteFile) of + true -> + call(Pid, {recv_bin, RemoteFile}, bin); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -473,7 +533,12 @@ recv_bin(Pid, RemoteFile) -> 'ok' | {'error', Reason :: restriction_reason() | common_reason()}. recv_chunk_start(Pid, RemoteFile) -> - call(Pid, {recv_chunk_start, RemoteFile}, atom). + case is_name_sane(RemoteFile) of + true -> + call(Pid, {recv_chunk_start, RemoteFile}, atom); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -521,7 +586,12 @@ send(Pid, LocalFileName) -> shortage_reason()}. send(Pid, LocalFileName, RemotFileName) -> - call(Pid, {send, LocalFileName, RemotFileName}, atom). + case is_name_sane(RemotFileName) of + true -> + call(Pid, {send, LocalFileName, RemotFileName}, atom); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -541,7 +611,12 @@ send(Pid, LocalFileName, RemotFileName) -> shortage_reason()}. send_bin(Pid, Bin, RemoteFile) when is_binary(Bin) -> - call(Pid, {send_bin, Bin, RemoteFile}, atom); + case is_name_sane(RemoteFile) of + true -> + call(Pid, {send_bin, Bin, RemoteFile}, atom); + _ -> + {error, efnamena} + end; send_bin(_Pid, _Bin, _RemoteFile) -> {error, enotbinary}. @@ -559,7 +634,12 @@ send_bin(_Pid, _Bin, _RemoteFile) -> 'ok' | {'error', Reason :: restriction_reason() | common_reason()}. send_chunk_start(Pid, RemoteFile) -> - call(Pid, {send_chunk_start, RemoteFile}, atom). + case is_name_sane(RemoteFile) of + true -> + call(Pid, {send_chunk_start, RemoteFile}, atom); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -575,7 +655,12 @@ send_chunk_start(Pid, RemoteFile) -> 'ok' | {'error', Reason :: term()}. append_chunk_start(Pid, RemoteFile) -> - call(Pid, {append_chunk_start, RemoteFile}, atom). + case is_name_sane(RemoteFile) of + true -> + call(Pid, {append_chunk_start, RemoteFile}, atom); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -683,7 +768,12 @@ append(Pid, LocalFileName) -> 'ok' | {'error', Reason :: term()}. append(Pid, LocalFileName, RemotFileName) -> - call(Pid, {append, LocalFileName, RemotFileName}, atom). + case is_name_sane(RemotFileName) of + true -> + call(Pid, {append, LocalFileName, RemotFileName}, atom); + _ -> + {error, efnamena} + end. %%-------------------------------------------------------------------------- @@ -705,7 +795,12 @@ append(Pid, LocalFileName, RemotFileName) -> shortage_reason()}. append_bin(Pid, Bin, RemoteFile) when is_binary(Bin) -> - call(Pid, {append_bin, Bin, RemoteFile}, atom); + case is_name_sane(RemoteFile) of + true -> + call(Pid, {append_bin, Bin, RemoteFile}, atom); + _ -> + {error, efnamena} + end; append_bin(_Pid, _Bin, _RemoteFile) -> {error, enotbinary}. @@ -2302,6 +2397,15 @@ send_bin(State, Bin) -> mk_cmd(Fmt, Args) -> [io_lib:format(Fmt, Args)| [?CR, ?LF]]. % Deep list ok. +is_name_sane([]) -> + true; +is_name_sane([?CR| _]) -> + false; +is_name_sane([?LF| _]) -> + false; +is_name_sane([_| Rest]) -> + is_name_sane(Rest). + pwd_result(Lines) -> {_, [?DOUBLE_QUOTE | Rest]} = lists:splitwith(fun(?DOUBLE_QUOTE) -> false; (_) -> true end, Lines), diff --git a/lib/inets/src/http_client/httpc_handler.erl b/lib/inets/src/http_client/httpc_handler.erl index 80c8b2439e..88e08be789 100644 --- a/lib/inets/src/http_client/httpc_handler.erl +++ b/lib/inets/src/http_client/httpc_handler.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2013. All Rights Reserved. +%% Copyright Ericsson AB 2002-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -55,8 +55,8 @@ headers, % #http_response_h{} body, % binary() mfa, % {Module, Function, Args} - pipeline = queue:new(), % queue() - keep_alive = queue:new(), % queue() + pipeline = queue:new(), % queue:queue() + keep_alive = queue:new(), % queue:queue() status, % undefined | new | pipeline | keep_alive | close | {ssl_tunnel, Request} canceled = [], % [RequestId] max_header_size = nolimit, % nolimit | integer() @@ -1119,15 +1119,8 @@ handle_http_body(Body, #state{headers = Headers, handle_response(State#state{headers = NewHeaders, body = NewBody}) end; - Encoding when is_list(Encoding) -> - ?hcrt("handle_http_body - encoding", [{encoding, Encoding}]), - NewState = answer_request(Request, - httpc_response:error(Request, - unknown_encoding), - State), - {stop, normal, NewState}; - _ -> - ?hcrt("handle_http_body - other", []), + Enc when Enc =:= "identity"; Enc =:= undefined -> + ?hcrt("handle_http_body - identity", []), Length = list_to_integer(Headers#http_response_h.'content-length'), case ((Length =< MaxBodySize) orelse (MaxBodySize =:= nolimit)) of @@ -1149,12 +1142,19 @@ handle_http_body(Body, #state{headers = Headers, body_too_big), State), {stop, normal, NewState} - end + end; + Encoding when is_list(Encoding) -> + ?hcrt("handle_http_body - other", [{encoding, Encoding}]), + NewState = answer_request(Request, + httpc_response:error(Request, + unknown_encoding), + State), + {stop, normal, NewState} end. handle_response(#state{status = new} = State) -> ?hcrd("handle response - status = new", []), - handle_response(check_persistent(State)); + handle_response(try_to_enable_pipeline_or_keep_alive(State)); handle_response(#state{request = Request, status = Status, @@ -1429,22 +1429,39 @@ is_keep_alive_enabled_server(_,_) -> is_keep_alive_connection(Headers, #session{client_close = ClientClose}) -> (not ((ClientClose) orelse httpc_response:is_server_closing(Headers))). -check_persistent( - #state{session = #session{type = Type} = Session, +try_to_enable_pipeline_or_keep_alive( + #state{session = Session, + request = #request{method = Method}, status_line = {Version, _, _}, headers = Headers, - profile_name = ProfileName} = State) -> + profile_name = ProfileName} = State) -> + ?hcrd("try to enable pipeline or keep-alive", + [{version, Version}, + {headers, Headers}, + {session, Session}]), case is_keep_alive_enabled_server(Version, Headers) andalso - is_keep_alive_connection(Headers, Session) of + is_keep_alive_connection(Headers, Session) of true -> - mark_persistent(ProfileName, Session), - State#state{status = Type}; + case (is_pipeline_enabled_client(Session) andalso + httpc_request:is_idempotent(Method)) of + true -> + insert_session(Session, ProfileName), + State#state{status = pipeline}; + false -> + insert_session(Session, ProfileName), + %% Make sure type is keep_alive in session + %% as it in this case might be pipeline + NewSession = Session#session{type = keep_alive}, + State#state{status = keep_alive, + session = NewSession} + end; false -> State#state{status = close} end. answer_request(#request{id = RequestId, from = From} = Request, Msg, - #state{timers = Timers, + #state{session = Session, + timers = Timers, profile_name = ProfileName} = State) -> ?hcrt("answer request", [{request, Request}, {msg, Msg}]), httpc_response:send(From, Msg), @@ -1454,14 +1471,19 @@ answer_request(#request{id = RequestId, from = From} = Request, Msg, Timer = {RequestId, TimerRef}, cancel_timer(TimerRef, {timeout, Request#request.id}), httpc_manager:request_done(RequestId, ProfileName), + NewSession = maybe_make_session_available(ProfileName, Session), Timers2 = Timers#timers{request_timers = lists:delete(Timer, RequestTimers)}, State#state{request = Request#request{from = answer_sent}, + session = NewSession, timers = Timers2}. -mark_persistent(ProfileName, Session) -> - update_session(ProfileName, Session, #session.persistent, true), - Session#session{persistent = true}. +maybe_make_session_available(ProfileName, + #session{available = false} = Session) -> + update_session(ProfileName, Session, #session.available, true), + Session#session{available = true}; +maybe_make_session_available(_ProfileName, Session) -> + Session. cancel_timers(#timers{request_timers = ReqTmrs, queue_timer = QTmr}) -> cancel_timer(QTmr, timeout_queue), @@ -1829,7 +1851,7 @@ update_session(ProfileName, #session{id = SessionId} = Session, Pos, Value) -> [ProfileName, SessionId, Pos, Value, (catch httpc_manager:which_session_info(ProfileName)), Session, - (catch httpc_manager:lookup_session(ProfileName, SessionId)), + (catch httpc_manager:lookup_session(SessionId, ProfileName)), T, E]), exit({failed_updating_session, [{profile, ProfileName}, diff --git a/lib/inets/src/http_client/httpc_internal.hrl b/lib/inets/src/http_client/httpc_internal.hrl index d5b3dd2a2a..add5d11dfa 100644 --- a/lib/inets/src/http_client/httpc_internal.hrl +++ b/lib/inets/src/http_client/httpc_internal.hrl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2005-2013. All Rights Reserved. +%% Copyright Ericsson AB 2005-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -143,8 +143,8 @@ %% true | false %% This will be true, when a response has been received for - %% the first request and the server has not closed the connection - persistent = false + %% the first request. See type above. + available = false }). diff --git a/lib/inets/src/http_client/httpc_manager.erl b/lib/inets/src/http_client/httpc_manager.erl index a3ed371e61..48a9c32454 100644 --- a/lib/inets/src/http_client/httpc_manager.erl +++ b/lib/inets/src/http_client/httpc_manager.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 2002-2013. All Rights Reserved. +%% Copyright Ericsson AB 2002-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -451,7 +451,7 @@ do_init(ProfileName, CookiesDir) -> %%-------------------------------------------------------------------- handle_call({request, Request}, _, State) -> ?hcri("request", [{request, Request}]), - case (catch handle_request(Request, State, false)) of + case (catch handle_request(Request, State)) of {reply, Msg, NewState} -> {reply, Msg, NewState}; Error -> @@ -511,7 +511,7 @@ handle_cast({retry_or_redirect_request, {Time, Request}}, {noreply, State}; handle_cast({retry_or_redirect_request, Request}, State) -> - case (catch handle_request(Request, State, true)) of + case (catch handle_request(Request, State)) of {reply, {ok, _}, NewState} -> {noreply, NewState}; Error -> @@ -724,7 +724,7 @@ get_handler_info(Tab) -> handle_request(#request{settings = #http_options{version = "HTTP/0.9"}} = Request, - State, _) -> + State) -> %% Act as an HTTP/0.9 client that does not know anything %% about persistent connections @@ -737,7 +737,7 @@ handle_request(#request{settings = handle_request(#request{settings = #http_options{version = "HTTP/1.0"}} = Request, - State, _) -> + State) -> %% Act as an HTTP/1.0 client that does not %% use persistent connections @@ -748,13 +748,13 @@ handle_request(#request{settings = start_handler(NewRequest#request{headers = NewHeaders}, State), {reply, {ok, NewRequest#request.id}, State}; -handle_request(Request, State = #state{options = Options}, Retry) -> +handle_request(Request, State = #state{options = Options}) -> NewRequest = handle_cookies(generate_request_id(Request), State), SessionType = session_type(Options), case select_session(Request#request.method, Request#request.address, - Request#request.scheme, SessionType, State, Retry) of + Request#request.scheme, SessionType, State) of {ok, HandlerPid} -> pipeline_or_keep_alive(NewRequest, HandlerPid, State); no_connection -> @@ -778,7 +778,6 @@ start_handler(#request{id = Id, #state{profile_name = ProfileName, handler_db = HandlerDb, options = Options}) -> - ClientClose = httpc_request:is_client_closing(Request#request.headers), {ok, Pid} = case is_inets_manager() of true -> @@ -789,18 +788,13 @@ start_handler(#request{id = Id, end, HandlerInfo = {Id, Pid, From}, ets:insert(HandlerDb, HandlerInfo), - insert_session(#session{id = {Request#request.address, Pid}, - scheme = Request#request.scheme, - client_close = ClientClose, - type = session_type(Options) - }, ProfileName), erlang:monitor(process, Pid). select_session(Method, HostPort, Scheme, SessionType, #state{options = #options{max_pipeline_length = MaxPipe, max_keep_alive_length = MaxKeepAlive}, - session_db = SessionDb}, Retry) -> + session_db = SessionDb}) -> ?hcrd("select session", [{session_type, SessionType}, {max_pipeline_length, MaxPipe}, {max_keep_alive_length, MaxKeepAlive}]), @@ -813,23 +807,13 @@ select_session(Method, HostPort, Scheme, SessionType, %% client_close, scheme and type specified. %% The fields id (part of: HandlerPid) and queue_length %% specified. - Pattern = case (Retry andalso SessionType == pipeline) of - true -> - #session{id = {HostPort, '$1'}, - client_close = false, - scheme = Scheme, - queue_length = '$2', - type = SessionType, - persistent = true, - _ = '_'}; - false -> - #session{id = {HostPort, '$1'}, - client_close = false, - scheme = Scheme, - queue_length = '$2', - type = SessionType, - _ = '_'} - end, + Pattern = #session{id = {HostPort, '$1'}, + client_close = false, + scheme = Scheme, + queue_length = '$2', + type = SessionType, + available = true, + _ = '_'}, %% {'_', {HostPort, '$1'}, false, Scheme, '_', '$2', SessionTyp}, Candidates = ets:match(SessionDb, Pattern), ?hcrd("select session", [{host_port, HostPort}, diff --git a/lib/inets/src/http_server/httpd_example.erl b/lib/inets/src/http_server/httpd_example.erl index 16a080f8e2..6fc07f033c 100644 --- a/lib/inets/src/http_server/httpd_example.erl +++ b/lib/inets/src/http_server/httpd_example.erl @@ -1,7 +1,7 @@ %% %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1997-2009. All Rights Reserved. +%% Copyright Ericsson AB 1997-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -66,7 +66,7 @@ get_bin(_Env,_Input) -> <INPUT TYPE=\"text\" NAME=\"input2\"> <INPUT TYPE=\"submit\"><BR> </FORM>" ++ "\n"), - footer()]. + list_to_binary(footer())]. post(_Env,[]) -> [header(), diff --git a/lib/inets/src/inets_app/inets.app.src b/lib/inets/src/inets_app/inets.app.src index a6dd364c2d..9eae962d03 100644 --- a/lib/inets/src/inets_app/inets.app.src +++ b/lib/inets/src/inets_app/inets.app.src @@ -110,4 +110,6 @@ {registered,[inets_sup, httpc_manager]}, %% If the "new" ssl is used then 'crypto' must be started before inets. {applications,[kernel,stdlib]}, - {mod,{inets_app,[]}}]}. + {mod,{inets_app,[]}}, + {runtime_dependencies, ["stdlib-2.0","ssl-5.3.4","runtime_tools-1.8.14", + "mnesia-4.12","kernel-3.0","erts-6.0"]}]}. diff --git a/lib/inets/src/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src index c63dcafa6c..dd081962cc 100644 --- a/lib/inets/src/inets_app/inets.appup.src +++ b/lib/inets/src/inets_app/inets.appup.src @@ -1,7 +1,7 @@ -%% This is an -*- erlang -*- file. +%% -*- erlang -*- %% %CopyrightBegin% %% -%% Copyright Ericsson AB 1999-2013. All Rights Reserved. +%% Copyright Ericsson AB 1999-2014. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in @@ -15,11 +15,13 @@ %% under the License. %% %% %CopyrightEnd% - {"%VSN%", [ - {<<"5\\.*">>, [{restart_application, inets}]} - ], + {"5.9.8", [{load_module, ftp, soft_purge, soft_purge, []}]}, + {<<"5\\..*">>,[{restart_application, inets}]} + ], [ - {<<"5\\.*">>, [{restart_application, inets}]} -]}. + {"5.9.8", [{load_module, ftp, soft_purge, soft_purge, []}]}, + {<<"5\\..*">>,[{restart_application, inets}]} + ] +}. |