Skip to content

Commit

Permalink
dispatch on method name and massive cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
mojombo committed May 25, 2008
1 parent d8da04f commit a55fb27
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 26 deletions.
3 changes: 1 addition & 2 deletions elibs/gandalf.erl
Expand Up @@ -4,5 +4,4 @@

start() ->
application:load(gandalf),
application:start(gandalf),
io:format("started gandalf~n").
application:start(gandalf).
1 change: 0 additions & 1 deletion elibs/gandalf_app.erl
Expand Up @@ -3,7 +3,6 @@
-export([start/2, stop/1]).

start(_Type, StartArgs) ->
io:format("app start ~p~n", [StartArgs]),
gandalf_sup:start_link(StartArgs).

stop(_State) ->
Expand Down
1 change: 0 additions & 1 deletion elibs/gandalf_sup.erl
Expand Up @@ -15,7 +15,6 @@ start_link(Args) ->
supervisor:start_link({local, ?MODULE}, ?MODULE, Args).

init([]) ->
io:format("sup init~n"),
{ok, {{one_for_one, 100, 300},
[{server,
{server, start_link, []},
Expand Down
57 changes: 35 additions & 22 deletions elibs/server.erl
Expand Up @@ -2,11 +2,9 @@
-export([start_link/0, init/1]).

start_link() ->
io:format("server start link~n"),
proc_lib:start_link(?MODULE, init, [self()]).

init(Parent) ->
io:format("server start~n"),
LSock = try_listen(10),
proc_lib:init_ack(Parent, {ok, self()}),
loop(LSock).
Expand All @@ -32,32 +30,40 @@ loop(LSock) ->

handle_method(Sock) ->
% get the requested method
{ok, Binary} = gen_tcp:recv(Sock, 0),
io:format("=> ~p~n", [Binary]),
{ok, MethodSpec} = gen_tcp:recv(Sock, 0),
Method = extract_method_name(MethodSpec),

% dispatch
case Method of
{ok, "git-upload-pack"} ->
handle_upload_pack(Sock);
invalid ->
gen_tcp:send(Sock, "Invalid method declaration. Upgrade to the latest git.\n"),
ok = gen_tcp:close(Sock)
end.

handle_upload_pack(Sock) ->
% make the port
Command = "git upload-pack /Users/tom/dev/sandbox/git/god.git",
Command = "git upload-pack /Users/tom/dev/sandbox/git/m/o/j/mojombo/god.git",
Port = open_port({spawn, Command}, []),

% send the output back to client
Data = gather_out(Port),
io:format("<= ~p~n", [Data]),
gen_tcp:send(Sock, Data),

% get the request data from client
io:format("getting more data~n"),
{ok, Binary2} = gen_tcp:recv(Sock, 0),
io:format("=> ~p~n~n", [Binary2]),
% the initial output from git-upload-pack lists the SHA1s of each head.
% data completion is denoted by "0000" on it's own line.
% this is sent back immediately to the client.
Index = gather_out(Port),
gen_tcp:send(Sock, Index),

% send to port
port_command(Port, Binary2),
io:format("Sent pack request to port~n"),
% once the client receives the index data, it will demand that specific
% revisions be packaged and sent back. this demand will be forwarded to
% git-upload-pack.
{ok, Demand} = gen_tcp:recv(Sock, 0),
port_command(Port, Demand),

% send the pack
% in response to the demand, git-upload-pack will stream out the requested
% pack information. data completion is denoted by "0000".
stream_out(Port, Sock),

% close connection
gen_tcp:send(Sock, "ok\n"),
ok = gen_tcp:close(Sock).

gather_out(Port) ->
Expand All @@ -66,7 +72,7 @@ gather_out(Port) ->
gather_out(Port, DataSoFar) ->
{data, Data} = readline(Port),
TotalData = DataSoFar ++ Data,
case regexp:match(TotalData, "\n0000$") of
case regexp:first_match(TotalData, "\n0000$") of
{match, _Start, _Length} ->
TotalData;
_Else ->
Expand All @@ -76,8 +82,7 @@ gather_out(Port, DataSoFar) ->
stream_out(Port, Sock) ->
{data, Data} = readline(Port),
gen_tcp:send(Sock, Data),
io:format("<= ~p~n", [Data]),
case regexp:match(Data, "0000$") of
case regexp:first_match(Data, "0000$") of
{match, _Start, _Length} ->
done;
_Else ->
Expand All @@ -94,4 +99,12 @@ readline(Port) ->
after 5000 ->
io:format("timed out waiting for port~n"),
{error, timeout}
end.

extract_method_name(MethodSpec) ->
case regexp:match(MethodSpec, "....[a-z\-]+ ") of
{match, Start, Length} ->
{ok, string:substr(MethodSpec, Start + 4, Length - 5)};
_Else ->
invalid
end.

0 comments on commit a55fb27

Please sign in to comment.