Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id ED1D8EA35 for ; Mon, 11 Feb 2013 13:51:21 +0000 (UTC) Received: (qmail 65216 invoked by uid 500); 11 Feb 2013 13:51:20 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 64956 invoked by uid 500); 11 Feb 2013 13:51:20 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 63065 invoked by uid 99); 11 Feb 2013 13:51:17 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 11 Feb 2013 13:51:16 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 932F23C83E; Mon, 11 Feb 2013 13:51:16 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jhs@apache.org To: commits@couchdb.apache.org X-Mailer: ASF-Git Admin Mailer Subject: [13/19] git commit: Barely-working proxy to node-inspector Message-Id: <20130211135116.932F23C83E@tyr.zones.apache.org> Date: Mon, 11 Feb 2013 13:51:16 +0000 (UTC) Barely-working proxy to node-inspector Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/df3cf5e2 Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/df3cf5e2 Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/df3cf5e2 Branch: refs/heads/nodejs_couchdb Commit: df3cf5e2638cf01c2cd0fc9eeb04dc3e53dd1830 Parents: e2e7d90 Author: Jason Smith (work) Authored: Thu Feb 7 12:51:44 2013 +0000 Committer: Jason Smith (work) Committed: Thu Feb 7 12:51:44 2013 +0000 ---------------------------------------------------------------------- share/www/verify_install.html | 2 + src/couchdb/couch_httpd_debug.erl | 94 +++++++++++------------------ src/couchdb/couch_httpd_proxy.erl | 56 ++++++++++++++++++ src/ibrowse/ibrowse_http_client.erl | 7 ++ 4 files changed, 101 insertions(+), 58 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb/blob/df3cf5e2/share/www/verify_install.html ---------------------------------------------------------------------- diff --git a/share/www/verify_install.html b/share/www/verify_install.html index 7e3a7a7..ce85c03 100644 --- a/share/www/verify_install.html +++ b/share/www/verify_install.html @@ -75,6 +75,8 @@ specific language governing permissions and limitations under the License. // temporary view var resp = db.query(function(doc) { + if(doc.a) + debugger if(doc.a) { emit(doc.a, doc.a); } http://git-wip-us.apache.org/repos/asf/couchdb/blob/df3cf5e2/src/couchdb/couch_httpd_debug.erl ---------------------------------------------------------------------- diff --git a/src/couchdb/couch_httpd_debug.erl b/src/couchdb/couch_httpd_debug.erl index f574eff..6faf966 100644 --- a/src/couchdb/couch_httpd_debug.erl +++ b/src/couchdb/couch_httpd_debug.erl @@ -27,15 +27,18 @@ handle_debug_req(#httpd{method='GET', path_parts=[_Debug]}=Req) -> ok handle_debug_req(#httpd{method='GET', path_parts=[_Debug, Pid | _Rest]=Path}=Req) -> ok , ok = couch_httpd:verify_is_server_admin(Req) - , io:format("Must look up: ~p for: ~p\n", [Pid, Path]) + %, io:format("Must look up: ~p for: ~p\n", [Pid, Path]) , Procs = couch_query_servers:debug_ports("javascript") , case lists:keyfind(Pid, 1, Procs) of {Pid, Port} -> ok , InspectorPort = Port + 1 %, proxy_to_inspector(Req, InspectorPort) - , R = couch_httpd:send_json(Req, 200, {[ {ok,true}, {todo,<<"To do">>} ]}) - , io:format("send_json returns: ~p\n", [R]) - , R + %, R = couch_httpd:send_json(Req, 200, {[ {ok,true}, {todo,<<"To do">>} ]}) + %, io:format("send_json returns: ~p\n", [R]) + %, R + , Url = io_lib:format("http://127.0.0.1:~w/_debug/", [InspectorPort]) + %, io:format("Proxy: ~p\n", [Url]) + , couch_httpd_proxy:handle_proxy_req(Req, ?l2b(Url)) ; false -> ok , io:format("No such pid: ~p\n", [Pid]) , couch_httpd:send_json(Req, 404, {[ {error,pid_not_found}, {pid,Pid} ]}) @@ -46,61 +49,36 @@ handle_debug_req(Req) -> ok , send_method_not_allowed(Req, "GET") . -relay(#httpd{mochi_req=MochiReq}=Req, InspectorSocket) -> ok - , ReqBytes = request_to_iolist(Req) - , Client = MochiReq:get(socket) - , gen_tcp:send(InspectorSocket, ReqBytes) - , relay(Client, InspectorSocket, 0, 0) - . - -relay(Client, Remote, BytesIn, BytesOut) -> ok - %, io:format("Relay in=~w out=~w\n", [BytesIn, BytesOut]) - , inet:setopts(Client, [{packet,0}, {active,once}]) - , inet:setopts(Remote, [{packet,0}, {active,once}]) - , receive - {_Type, Client, Data} -> ok - %, io:format(" ~w bytes from client\n", [size(Data)]) - , gen_tcp:send(Remote, Data) - , relay(Client, Remote, BytesIn + size(Data), BytesOut) - ; {_Type, Remote, Data} -> ok - %, io:format(" ~w bytes from inspector\n", [size(Data)]) - , gen_tcp:send(Client, Data) - , relay(Client, Remote, BytesIn, BytesOut + size(Data)) - ; {tcp_closed, _} -> ok - , io:format("Relay finished in=~w out=~w\n", [BytesIn, BytesOut]) - , gen_tcp:close(Client) - , gen_tcp:close(Remote) - , {ok, BytesIn, BytesOut} - , ok - ; Else -> ok - , ?LOG_ERROR("Relay error: ~p", [Else]) - end - %, couch_httpd:send_json(Req, 200, {[ {ok,true}, {todo,<<"To do">>} ]}) - . - -proxy_to_inspector(Req, Port) -> ok - , io:format("Connect to port ~w\n", [Port]) - , case gen_tcp:connect("127.0.0.1", Port, [binary, {packet,0}, {delay_send,true}]) - of {ok, InspectorSocket} -> ok - , io:format("Connected to inspector on :~w\n", [Port]) - , relay(Req, InspectorSocket) - ; {error, Error} -> ok - , Resp = {[ {error,inspector_proxy}, {result, Error} ]} - , couch_httpd:send_json(Req, 502, Resp) - end - . +%relay(#httpd{mochi_req=MochiReq}=Req, InspectorSocket) -> ok +% , ReqBytes = request_to_iolist(Req) +% , Client = MochiReq:get(socket) +% , gen_tcp:send(InspectorSocket, ReqBytes) +% , relay(Client, InspectorSocket, 0, 0) +% . + +%proxy_to_inspector(Req, Port) -> ok +% , io:format("Connect to port ~w\n", [Port]) +% , case gen_tcp:connect("127.0.0.1", Port, [binary, {packet,0}, {delay_send,true}]) +% of {ok, InspectorSocket} -> ok +% , io:format("Connected to inspector on :~w\n", [Port]) +% , relay(Req, InspectorSocket) +% ; {error, Error} -> ok +% , Resp = {[ {error,inspector_proxy}, {result, Error} ]} +% , couch_httpd:send_json(Req, 502, Resp) +% end +% . -request_to_iolist(#httpd{method=Method, mochi_req=MochiReq}=Req) -> ok - , Path = MochiReq:get(raw_path) - , Version = case MochiReq:get(version) - of {1,1} -> "1.1" - ; _ -> "1.0" - end - , Action = io_lib:format("~s ~s HTTP/~s", [Method, Path, Version]) - , MochiHeaders = mochiweb_headers:to_list(MochiReq:get(headers)) - , Headers = [ [couch_util:to_binary(Key), ": ", Val, "\r\n"] || {Key, Val} <- MochiHeaders] - , [Action, "\r\n", Headers, "\r\n"] - . +%request_to_iolist(#httpd{method=Method, mochi_req=MochiReq}=Req) -> ok +% , Path = MochiReq:get(raw_path) +% , Version = case MochiReq:get(version) +% of {1,1} -> "1.1" +% ; _ -> "1.0" +% end +% , Action = io_lib:format("~s ~s HTTP/~s", [Method, Path, Version]) +% , MochiHeaders = mochiweb_headers:to_list(MochiReq:get(headers)) +% , Headers = [ [couch_util:to_binary(Key), ": ", Val, "\r\n"] || {Key, Val} <- MochiHeaders] +% , [Action, "\r\n", Headers, "\r\n"] +% . %% Login handler with Browser ID. %handle_id_req(#httpd{method='POST'}=Req) -> ok http://git-wip-us.apache.org/repos/asf/couchdb/blob/df3cf5e2/src/couchdb/couch_httpd_proxy.erl ---------------------------------------------------------------------- diff --git a/src/couchdb/couch_httpd_proxy.erl b/src/couchdb/couch_httpd_proxy.erl index dec3f55..4acbc9c 100644 --- a/src/couchdb/couch_httpd_proxy.erl +++ b/src/couchdb/couch_httpd_proxy.erl @@ -254,6 +254,11 @@ stream_response(Req, ProxyDest, ReqId) -> % doesn't get confused. ibrowse:stream_next(ReqId), stream_response(Req, ProxyDest, ReqId); + {ibrowse_async_headers, ReqId, "101", Headers} -> + % 101 Switching Protocols + {Source, Dest} = get_urls(Req, ProxyDest), + FixedHeaders = fix_headers(Source, Dest, Headers, []), + relay(ReqId, Req, FixedHeaders); {ibrowse_async_headers, ReqId, Status, Headers} -> {Source, Dest} = get_urls(Req, ProxyDest), FixedHeaders = fix_headers(Source, Dest, Headers, []), @@ -286,6 +291,57 @@ stream_response(Req, ProxyDest, ReqId) -> end end. +relay(ReqId, #httpd{mochi_req=MochiReq}=Req, FixedHeaders) -> + %io:format("Relay: ~p\nReq=~p\nH=~p\n", [ReqId, Req, FixedHeaders]), + case ets:lookup(ibrowse_stream, {req_id_pid, ReqId}) of + [] -> + io:format("Unknown req id ~p\n", [ReqId]); + [{_, Pid}] -> + io:format("Sending message to ibrowse: ~w\n", [Pid]), + catch Pid ! {take_stream, self()}, + receive + {permission, Remote, Data} -> + io:format("Got control of socket: ~p\n", [Remote]), + Client = MochiReq:get(socket), + HeadersIo = [ [Key, ": ", Val, "\r\n"] || {Key, Val} <- FixedHeaders], + Response = iolist_to_binary([ "HTTP/1.1 101 Switching Protocols\r\n", HeadersIo, "\r\n", Data ]), + io:format("Need to send response:\n~p\n", [iolist_to_binary(Response)]), + gen_tcp:send(Client, Response), + relay(Client, Remote, 0, size(Response), Pid) + after 1000 -> + io:format("Error, no permission\n") + end + end, + ok. + +relay(Client, Remote, FromClient, FromRemote, Owner) -> ok + , io:format("Relay in=~w out=~w\n", [FromClient, FromRemote]) + , inet:setopts(Client, [{packet,0}, {active,once}, {nodelay,true} ]) + , inet:setopts(Remote, [{packet,0}, {active,once}, {nodelay,true} ]) + , receive + {_Type, Client, Data} -> ok + %, io:format("Client: ~p\n", [Data]) + , gen_tcp:send(Remote, Data) + , relay(Client, Remote, FromClient + size(Data), FromRemote, Owner) + ; {_Type, Remote, Data} -> ok + %, io:format("Remote ~w bytes: ~p\n", [size(Data), Data]) + , gen_tcp:send(Client, Data) + , relay(Client, Remote, FromClient, FromRemote + size(Data), Owner) + ; {tcp_closed, S} -> ok + , io:format("Closed socket: ~p\n", [S]) + , io:format("Relay finished in=~w out=~w\n", [FromClient, FromRemote]) + , gen_tcp:controlling_process(Remote, Owner) + , catch Owner ! {stream_close, bad_reqid} + %, gen_tcp:close(Client) + %, gen_tcp:close(Remote) + %, {ok, FromClient, FromRemote} + , {ok, true} + ; Else -> ok + , ?LOG_ERROR("Relay error: ~p", [Else]) + end + %, couch_httpd:send_json(Req, 200, {[ {ok,true}, {todo,<<"To do">>} ]}) + . + stream_chunked_response(Req, ReqId, Resp) -> receive http://git-wip-us.apache.org/repos/asf/couchdb/blob/df3cf5e2/src/ibrowse/ibrowse_http_client.erl ---------------------------------------------------------------------- diff --git a/src/ibrowse/ibrowse_http_client.erl b/src/ibrowse/ibrowse_http_client.erl index c01385a..5acf52f 100644 --- a/src/ibrowse/ibrowse_http_client.erl +++ b/src/ibrowse/ibrowse_http_client.erl @@ -244,6 +244,13 @@ handle_info({trace, Bool}, State) -> put(my_trace_flag, Bool), {noreply, State}; +handle_info({take_stream, Pid}, #state{socket=Socket, reply_buffer=Body}=State) -> + io:format("Send socket ~p to ~p\n", [Socket, Pid]), + io:format(" rep=~p: ~p\n", [State#state.rep_buf_size, State#state.reply_buffer]), + gen_tcp:controlling_process(Socket, Pid), + catch Pid ! {permission, Socket, Body}, + {noreply, State}; + handle_info(Info, State) -> io:format("Unknown message recvd for ~1000.p:~1000.p -> ~p~n", [State#state.host, State#state.port, Info]),