From 75e3d5416cf9cbf60d5b894add3a5ba5420cbadc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 28 May 2013 17:57:45 +0200 Subject: [PATCH] Better handling of flush, short lines --- src/geef_pkt.erl | 52 ++++++++++++++++++++++++++++------------------- test/pkt_test.erl | 10 ++++++++- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/src/geef_pkt.erl b/src/geef_pkt.erl index e4baed0..79350fa 100644 --- a/src/geef_pkt.erl +++ b/src/geef_pkt.erl @@ -15,38 +15,48 @@ line(Text) -> -spec parse(iolist()) -> {{want | have, geef_oid()}, binary()}. parse(In) -> - {Len, Rest} = unpack(In), - case Len of - 0 -> - flush; - _ -> - parse_pkt(Rest, Len - 4) + case unpack(In) of + {error, ebufs} -> + {error, ebufs}; + {0, Rest} -> + {flush, Rest}; + {Len, Rest} -> + parse_pkt(Rest, Len) 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}. + case unpack(In) of + {error, ebufs} -> + {error, ebufs}; + {_, Line} -> + %% 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, + {ok, #geef_request{service=Service, path=Path, host=Host}} + end. --spec unpack(iolist()) -> {non_neg_integer(), binary()}. +-spec unpack(iolist()) -> {error, ebufs} | {non_neg_integer(), binary()}. unpack(In0) -> In = iolist_to_binary(In0), <> = In, Len = binary_to_integer(BLen, 16), - {Len, Rest}. + if Len == 0 -> + {0, Rest}; + Len - 4 > size(Rest) -> + {error, ebufs}; + true -> + {Len - 4, Rest} + end. -parse_pkt(In, Len) when size(In) < Len -> - {error, ebufs}; parse_pkt(In, Len0) -> + io:format("~p, ~p~n", [In, Len0]), Len1 = Len0 - 5, % "want " | "have " case In of <<"want ", Sha:?SHA_LEN/binary, Rest0/binary>> -> diff --git a/test/pkt_test.erl b/test/pkt_test.erl index aea1ac8..2f1f781 100644 --- a/test/pkt_test.erl +++ b/test/pkt_test.erl @@ -4,7 +4,9 @@ -include("src/geef_records.hrl"). flush_test() -> - geef_pkt:parse("0000"). + Expected = {flush, <<>>}, + Actual = geef_pkt:parse("0000"), + ?assertEqual(Expected, Actual). have_test() -> Expected = {{want, geef_oid:parse("e17ca7f2d877acbf8b9a9a1cb4c243ca72e86463")}, <<>>}, @@ -14,5 +16,11 @@ have_test() -> 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">>}, + {ok, Actual} = geef_pkt:parse_request(Line), + ?assertEqual(Expected, Actual). + +short_test() -> + Line = <<"0039git-upload">>, + Expected = {error, ebufs}, Actual = geef_pkt:parse_request(Line), ?assertEqual(Expected, Actual).