在Erlang中解析二进制文件

时间:2011-03-25 10:52:34

标签: http parsing binary erlang

如果我有以下二进制文件:<<"GET http://www.google.com HTTP/1.1">>,我该如何拆分它以便我只能检索主机(http://www.google.com)?

我开始使用类似的东西:

get_host(<<$G, Rest/binary>>) -> get_host(Rest);
get_host(<<$E, Rest/binary>>) -> get_host(Rest);
get_host(<<$T, Rest/binary>>) -> get_host(Rest);

但我不确定如何从这里开始。我正在考虑逆转Rest并从二进制文件的末尾重新开始。

3 个答案:

答案 0 :(得分:10)

您似乎正在尝试为HTTP 1.1实现最小解析器。这是one solution,它遵循HTTP 1.1的规范并解析http请求的第一行。在不知道您的具体情况的情况下,我会建议在简化的“拆分二进制”或类似之前使用通用HTTP解析器。

1> erlang:decode_packet(http,<<"GET http://www.google.com HTTP/1.1\n">>,[]).  
{ok,{http_request,'GET',
              {absoluteURI,http,"www.google.com",undefined,"/"},
              {1,1}},
<<>>}

答案 1 :(得分:3)

我建议erlang:decode_packet为此,但为了说明如何完成,这里有一对函数去除前导"GET ",然后将所有内容返回到第一个空格(但崩溃如果没有空间)。

get_host(<<"GET ", Rest/binary>>) ->
    get_host2(Rest, <<>>).

get_host2(<<" ", _/binary>>, Acc) ->
    Acc;
get_host2(<<C, Rest/binary>>, Acc) ->
    get_host2(Rest, <<Acc/binary, C>>).

基本上,我将不是空格的每个字节放入我的“累加器”中,当我找到空格时,我返回累加器。这是一个常见的技巧,更常见于列表。 (对于列表,您需要将新项目放在列表的并最后反转列表,以避免O(N)算法变为O(N²),但这不是二进制文件需要。)

答案 2 :(得分:0)

简单的答案(但可能不是你真正想要的)

B = <<"GET http://www.google.com HTTP/1.1">> .
{_,H}=split_binary(B,4). 
split_binary(H,21).