Parse protocol requests

This commit is contained in:
Carlos Martín Nieto
2013-05-28 09:18:58 +02:00
parent 03f43d3265
commit ecb7cdfc23
3 changed files with 33 additions and 5 deletions

View File

@@ -1,6 +1,6 @@
-module(geef_pkt). -module(geef_pkt).
-export([line/1, parse/1]). -export([line/1, parse/1, parse_request/1]).
-include("geef_records.hrl"). -include("geef_records.hrl").
@@ -14,10 +14,8 @@ line(Text) ->
[Prefix, Text, "\n"]. [Prefix, Text, "\n"].
-spec parse(iolist()) -> {{want | have, geef_oid()}, binary()}. -spec parse(iolist()) -> {{want | have, geef_oid()}, binary()}.
parse(In0) -> parse(In) ->
In = iolist_to_binary(In0), {Len, Rest} = unpack(In),
<<BLen:4/binary, Rest/binary>> = In,
Len = binary_to_integer(BLen, 16),
case Len of case Len of
0 -> 0 ->
flush; flush;
@@ -25,6 +23,27 @@ parse(In0) ->
parse_pkt(Rest, Len - 4) parse_pkt(Rest, Len - 4)
end. end.
-spec parse_request(iolist()) -> geef_request().
parse_request(In) ->
{_, Line} = unpack(In),
%% Split it into request, host, rest (should be empty)
[S, H, _] = binary:split(Line, <<0>>, [global]),
case S of
<<"git-upload-pack ", Path/binary>> ->
Service = upload_pack;
<<"git-receive-pack ", Path/binary>> ->
Service = receive_pack
end,
<<"host=", Host/binary>> = H,
#geef_request{service=Service, path=Path, host=Host}.
-spec unpack(iolist()) -> {non_neg_integer(), binary()}.
unpack(In0) ->
In = iolist_to_binary(In0),
<<BLen:4/binary, Rest/binary>> = In,
Len = binary_to_integer(BLen, 16),
{Len, Rest}.
parse_pkt(In, Len) when size(In) < Len -> parse_pkt(In, Len) when size(In) < Len ->
{error, ebufs}; {error, ebufs};
parse_pkt(In, Len0) -> parse_pkt(In, Len0) ->

View File

@@ -10,7 +10,10 @@
flags, flags_extended, flags, flags_extended,
path :: iolist()}). path :: iolist()}).
-record(geef_request, {service :: atom, path :: binary(), host :: binary()}).
-type geef_ref() :: #geef_ref{}. -type geef_ref() :: #geef_ref{}.
-type geef_oid() :: #geef_oid{}. -type geef_oid() :: #geef_oid{}.
-type geef_object() :: #geef_object{}. -type geef_object() :: #geef_object{}.
-type geef_index_entry() :: #geef_index_entry{}. -type geef_index_entry() :: #geef_index_entry{}.
-type geef_request() :: #geef_request{}.

View File

@@ -10,3 +10,9 @@ have_test() ->
Expected = {{want, geef_oid:parse("e17ca7f2d877acbf8b9a9a1cb4c243ca72e86463")}, <<>>}, Expected = {{want, geef_oid:parse("e17ca7f2d877acbf8b9a9a1cb4c243ca72e86463")}, <<>>},
Actual = geef_pkt:parse("0032want e17ca7f2d877acbf8b9a9a1cb4c243ca72e86463\n"), Actual = geef_pkt:parse("0032want e17ca7f2d877acbf8b9a9a1cb4c243ca72e86463\n"),
?assertEqual(Expected, Actual). ?assertEqual(Expected, Actual).
request_test() ->
Line = <<"0039git-upload-pack /schacon/gitbook.git\0host=example.com\0">>,
Expected = #geef_request{service=upload_pack, path= <<"/schacon/gitbook.git">>, host= <<"example.com">>},
Actual = geef_pkt:parse_request(Line),
?assertEqual(Expected, Actual).