diff --git a/apps/consul_proxy/src/consul_proxy_middleware_hijack.erl b/apps/consul_proxy/src/consul_proxy_middleware_hijack.erl index a4b12642043c76579d57a94baf959530b2b10222..fe3c710f2383b8f7efcef7cb19b09b9bb67fd385 100644 --- a/apps/consul_proxy/src/consul_proxy_middleware_hijack.erl +++ b/apps/consul_proxy/src/consul_proxy_middleware_hijack.erl @@ -37,7 +37,8 @@ socket = undefined, transport = undefined, timeout = 3000, - client_state = undefined + client_state = undefined, + username = undefined }). @@ -56,11 +57,16 @@ execute(Req, Env) -> case gen_server:call(?SERVER, {request, Req}) of {ignored, Req1} -> {ok, Req1, Env}; - {hijacked, Req1} -> + {hijacked, <<"snoop">>, Req1} -> + {ok, Req1, Env}; + {hijacked, <<"hijack">>, Req1} -> receive #{<<"status">> := Status, <<"headers">> := Headers, <<"body">> := Body} -> {ok, Req2} = cowboyku_req:reply(Status, maps:to_list(Headers), Body, Req1), {halt, Req2}; + #{<<"error">> := Reason} -> + {ok, Req2} = cowboyku_req:reply(500, [], Reason, Req1), + {halt, Req2}; _ -> {ok, Req1, Env} end @@ -119,19 +125,24 @@ handle_call({socket_recv, Terms = #{<<"action">> := <<"login">>}, SocketState}, case pbkdf2:pbkdf2(sha512, Password, Salt, ?PBKDF2_ITERATIONS, ?PBKDF2_DERIVED_LENGTH) of {ok, Hash} -> send(SocketState, #{<<"action">> => <<"authorized">>, <<"username">> => Username}), - {reply, SocketState#socket_state{client_state = authorized, timeout = 60000}, State}; + {reply, SocketState#socket_state{ + client_state = authorized, + timeout = 60000, + username = Username + }, State}; _ -> {reply, SocketState#socket_state{client_state = unauthorized}, State} end end; handle_call({socket_recv, Terms = #{<<"action">> := <<"bind">>}, SocketState}, _From, State) -> - #{<<"host">> := Host, <<"path">> := Path} = Terms, + #{<<"host">> := Host, <<"path">> := Path, <<"mode">> := Mode} = Terms, #socket_state{socket = Socket, transport = Transport} = SocketState, case re:compile(Path) of {ok, MP} -> - ets:insert(State#state.domain_tab, {Host, MP, Socket, Transport}), + ets:insert(State#state.domain_tab, {Host, Mode, MP, Socket, Transport}), send(SocketState, Terms), + lager:notice("~s/~s ~s by ~s on ~p", [Host, Path, Mode, SocketState#socket_state.username, Socket]), {reply, SocketState#socket_state{client_state = bound}, State}; {error, {Description, Position}} -> Message = io_lib:format("Bad path regexp '~s', ~s at position ~p", [Path, Description, Position]), @@ -163,7 +174,7 @@ handle_cast({socket_open, Socket, Transport}, State) -> {noreply, State}; handle_cast({socket_close, Socket, Reason}, State = #state{domain_tab = Tab}) -> - ets:match_delete(Tab, {'_', '_', Socket, '_'}), + ets:match_delete(Tab, {'_', '_', '_', Socket, '_'}), lager:notice("Socket closed(~p): ~p", [Reason, Socket]), unlink(Socket), {noreply, State}; @@ -216,7 +227,7 @@ parse_users([User | Users], Parsed) -> hijack([], Req, _From) -> {ignored, Req}; -hijack([{_, RE, Socket, Transport} | Patterns], Req, From) -> +hijack([{_Host, Mode, RE, Socket, Transport} | Patterns], Req, From) -> {Path, Req1} = cowboyku_req:path(Req), case re:run(Path, RE) of nomatch -> @@ -225,7 +236,7 @@ hijack([{_, RE, Socket, Transport} | Patterns], Req, From) -> B64Pid = base64:encode(term_to_binary(From)), {Map, Req2} = request_to_map(Req1), Transport:send(Socket, msgpack:pack(Map#{<<"from">> => B64Pid})), - {hijacked, Req2} + {hijacked, Mode, Req2} end. send(#socket_state{socket = Socket, transport = Transport}, Data) -> @@ -235,8 +246,7 @@ send(Socket, Transport, Data) -> Transport:send(Socket, msgpack:pack(Data)). request_to_map(Req) -> - {Id, Req0} = cowboyku_req:meta(request_id, Req), - {Qs, Req1} = cowboyku_req:qs(Req0), + {Qs, Req1} = cowboyku_req:qs(Req), FullPath = case Qs of <<>> -> Req1#http_req.path; @@ -246,7 +256,6 @@ request_to_map(Req) -> end, {ok, Body, Req2} = cowboyku_req:body(infinity, Req1), Map = #{ - <<"id">> => Id, <<"host">> => Req2#http_req.host, <<"method">> => Req2#http_req.method, <<"path">> => FullPath,