orber_iiop_inproxy.erl
来自「OTP是开放电信平台的简称」· ERL 代码 · 共 399 行 · 第 1/2 页
ERL
399 行
Timeout = orber_env:iiop_ssl_accept_timeout(), case catch orber_socket:post_accept(Type, Socket, Timeout) of ok -> {noreply, State}; _Failed -> orber_socket:close(Type, Socket), {stop, normal, State} end;handle_cast(stop, State) -> {stop, normal, State};handle_cast(_, State) -> {noreply, State, State#state.timeout}.%%-----------------------------------------------------------------%% Func: handle_info/2%%-----------------------------------------------------------------%% Normal invocationhandle_info({tcp, Socket, Bytes}, State) -> handle_msg(normal, Socket, Bytes, State);handle_info({ssl, Socket, Bytes}, State) -> handle_msg(ssl, Socket, Bytes, State);%% Errors, closed connectionhandle_info({tcp_closed, _Socket}, State) -> {stop, normal, State};handle_info({tcp_error, _Socket, _Reason}, State) -> {stop, normal, State};handle_info({ssl_closed, _Socket}, State) -> {stop, normal, State};handle_info({ssl_error, _Socket, _Reason}, State) -> {stop, normal, State};%% Servant termination.handle_info({'EXIT', Pid, normal}, State) -> ets:delete(State#state.db, Pid), {noreply, decrease_counter(State), State#state.timeout};handle_info({message_error, _Pid, ReqId}, State) -> ets:delete(State#state.db, ReqId), {noreply, State, State#state.timeout};handle_info(timeout, State) -> case ets:info(State#state.db, size) of 0 -> %% No pending requests, close the connection. {stop, normal, State}; _Amount -> %% Still pending request, cannot close the connection. {noreply, State, State#state.timeout} end;handle_info({reconfigure, Options}, State) -> {noreply, update_state(State, Options), State#state.timeout};handle_info(_X,State) -> {noreply, State, State#state.timeout}.handle_msg(Type, Socket, Bytes, #state{stype = Type, socket = Socket, giop_env = Env} = State) -> case catch cdr_decode:dec_giop_message_header(Bytes) of %% Only when using IIOP-1.2 may the client send this message. %% Introduced in CORBA-2.6 #giop_message{message_type = ?GIOP_MSG_CLOSE_CONNECTION, giop_version = {1,2}} -> {stop, normal, State}; #giop_message{message_type = ?GIOP_MSG_CLOSE_CONNECTION} -> {noreply, State, State#state.timeout}; #giop_message{message_type = ?GIOP_MSG_CANCEL_REQUEST} = GIOPHdr -> ReqId = cdr_decode:peek_request_id(GIOPHdr#giop_message.byte_order, GIOPHdr#giop_message.message), case ets:lookup(State#state.db, ReqId) of [{RId, PPid}] -> ets:delete(State#state.db, RId), PPid ! {self(), cancel_request_header}; [] -> send_msg_error(Type, Socket, Bytes, Env#giop_env{version = GIOPHdr#giop_message.giop_version}, "No such request id") end, {noreply, State, State#state.timeout}; %% A fragment; we must have received a Request or LocateRequest %% with fragment-flag set to true. %% We need to decode the header to get the request-id. #giop_message{message_type = ?GIOP_MSG_FRAGMENT, giop_version = {1,2}} = GIOPHdr -> ReqId = cdr_decode:peek_request_id(GIOPHdr#giop_message.byte_order, GIOPHdr#giop_message.message), case ets:lookup(State#state.db, ReqId) of [{_RId, PPid}] when GIOPHdr#giop_message.fragments == true -> PPid ! {self(), GIOPHdr}; [{RId, PPid}] -> ets:delete(State#state.db, RId), PPid ! {self(), GIOPHdr}; [] -> send_msg_error(Type, Socket, Bytes, Env#giop_env{version = GIOPHdr#giop_message.giop_version}, "No such fragment id") end, {noreply, State, State#state.timeout}; %% Must be a Request or LocateRequest which have been fragmented. %% We need to decode the header to get the request-id. #giop_message{fragments = true, giop_version = {1,2}} = GIOPHdr -> ReqId = cdr_decode:peek_request_id(GIOPHdr#giop_message.byte_order, GIOPHdr#giop_message.message), Pid = orber_iiop_inrequest: start_fragment_collector(GIOPHdr, Bytes, Type, Socket, ReqId, self(), State#state.max_fragments, Env#giop_env{version = {1,2}, request_id = ReqId}), ets:insert(State#state.db, {Pid, ReqId}), ets:insert(State#state.db, {ReqId, Pid}), {noreply, increase_counter(State), State#state.timeout}; GIOPHdr when record(GIOPHdr, giop_message) -> Pid = orber_iiop_inrequest:start(GIOPHdr, Bytes, Type, Socket, Env#giop_env{version = GIOPHdr#giop_message.giop_version}), ets:insert(State#state.db, {Pid, undefined}), {noreply, increase_counter(State), State#state.timeout}; {'EXIT', message_error} -> send_msg_error(Type, Socket, Bytes, Env#giop_env{version = orber_env:giop_version()}, "Unable to decode the GIOP-header"), {noreply, State, State#state.timeout} end;handle_msg(Type, _, Bytes, State) -> orber:dbg("[~p] orber_iiop_inproxy:handle_msg(~p);~n" "Received a message from a socket of a different type.~n" "Should be ~p but was ~p.", [?LINE, Bytes, State#state.stype, Type], ?DEBUG_LEVEL), {noreply, State, State#state.timeout}.send_msg_error(Type, Socket, Data, Env, Msg) -> orber:dbg("[~p] orber_iiop_inproxy:handle_msg(~p); ~p.", [?LINE, Data, Msg], ?DEBUG_LEVEL), Reply = cdr_encode:enc_message_error(Env), orber_socket:write(Type, Socket, Reply).increase_counter(#state{max_requests = infinity} = State) -> State;increase_counter(#state{max_requests = Max, request_counter = Counter} = State) when Max > Counter -> orber_socket:setopts(State#state.stype, State#state.socket, [{active, once}]), State#state{request_counter = Counter + 1};increase_counter(State) -> State#state{request_counter = State#state.request_counter + 1}.decrease_counter(#state{max_requests = infinity} = State) -> State;decrease_counter(#state{max_requests = Max, request_counter = Counter} = State) when Max =< Counter -> orber_socket:setopts(State#state.stype, State#state.socket, [{active, once}]), State#state{request_counter = Counter - 1};decrease_counter(State) -> State#state{request_counter = State#state.request_counter - 1}.update_state(#state{giop_env = Env} = State, [{interceptors, false}|Options]) -> update_state(State#state{giop_env = Env#giop_env{interceptors = false}}, Options);update_state(#state{giop_env = #giop_env{interceptors = false, host = [SH], iiop_port = SP} = Env, peer = {PH, PP}, stype = normal} = State, [{interceptors, {native, LPIs}}|Options]) -> %% No Interceptor(s). Add the same Ref used by the built in interceptors. update_state(State#state{giop_env = Env#giop_env{interceptors = {native, {PH, PP, SH, SP}, LPIs}}}, Options);update_state(#state{giop_env = #giop_env{interceptors = false, host = [SH], iiop_ssl_port = SP} = Env, peer = {PH, PP}, stype = ssl} = State, [{interceptors, {native, LPIs}}|Options]) -> %% No Interceptor(s). Add the same Ref used by the built in interceptors. update_state(State#state{giop_env = Env#giop_env{interceptors = {native, {PH, PP, SH, SP}, LPIs}}}, Options);update_state(#state{giop_env = #giop_env{interceptors = {native, Ref, _}} = Env} = State, [{interceptors, {native, LPIs}}|Options]) -> %% Interceptor(s) already in use. We must use the same Ref as before. update_state(State#state{giop_env = Env#giop_env{interceptors = {native, Ref, LPIs}}}, Options);update_state(State, [H|T]) -> orber:dbg("[~p] orber_iiop_inproxy:update_state(~p, ~p)~n" "Couldn't change the state.", [?LINE, H, State], ?DEBUG_LEVEL), update_state(State, T);update_state(State, []) -> State.%%-----------------------------------------------------------------%% Func: code_change/3%%-----------------------------------------------------------------code_change(_OldVsn, State, _Extra) -> {ok, State}.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?