如果我有以下二进制文件:<<"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
并从二进制文件的末尾重新开始。
答案 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).