diff --git a/src/geef_pkt.erl b/src/geef_pkt.erl index c01b038..e4baed0 100644 --- a/src/geef_pkt.erl +++ b/src/geef_pkt.erl @@ -1,6 +1,6 @@ -module(geef_pkt). --export([line/1, parse/1]). +-export([line/1, parse/1, parse_request/1]). -include("geef_records.hrl"). @@ -14,10 +14,8 @@ line(Text) -> [Prefix, Text, "\n"]. -spec parse(iolist()) -> {{want | have, geef_oid()}, binary()}. -parse(In0) -> - In = iolist_to_binary(In0), - <> = In, - Len = binary_to_integer(BLen, 16), +parse(In) -> + {Len, Rest} = unpack(In), case Len of 0 -> flush; @@ -25,6 +23,27 @@ parse(In0) -> parse_pkt(Rest, Len - 4) 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), + <> = In, + Len = binary_to_integer(BLen, 16), + {Len, Rest}. + parse_pkt(In, Len) when size(In) < Len -> {error, ebufs}; parse_pkt(In, Len0) -> diff --git a/src/geef_records.hrl b/src/geef_records.hrl index 4dced6e..5a488ec 100644 --- a/src/geef_records.hrl +++ b/src/geef_records.hrl @@ -10,7 +10,10 @@ flags, flags_extended, path :: iolist()}). +-record(geef_request, {service :: atom, path :: binary(), host :: binary()}). + -type geef_ref() :: #geef_ref{}. -type geef_oid() :: #geef_oid{}. -type geef_object() :: #geef_object{}. -type geef_index_entry() :: #geef_index_entry{}. +-type geef_request() :: #geef_request{}. diff --git a/test/pkt_test.erl b/test/pkt_test.erl index 5c3c9e2..aea1ac8 100644 --- a/test/pkt_test.erl +++ b/test/pkt_test.erl @@ -10,3 +10,9 @@ have_test() -> Expected = {{want, geef_oid:parse("e17ca7f2d877acbf8b9a9a1cb4c243ca72e86463")}, <<>>}, Actual = geef_pkt:parse("0032want e17ca7f2d877acbf8b9a9a1cb4c243ca72e86463\n"), ?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).