Created
November 2, 2011 16:21
-
-
Save puzza007/1334088 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(badger). | |
-export([encoding/1]). | |
-spec encoding(binary()) -> gzip | compress | deflate | identity. | |
encoding(AcceptEncoding) -> | |
EncodingList = encoding_list(AcceptEncoding), | |
{Enc, _} = | |
lists:foldl(fun({E, Q}, {MaxEnc, MaxQval}) -> | |
E1 = encoding_map(E), | |
if Q > MaxQval andalso E1 =/= unknown -> | |
{E1, Q}; | |
true -> | |
{MaxEnc, MaxQval} | |
end | |
end, | |
{identity, 0}, | |
EncodingList), | |
Enc. | |
-spec encoding_map(binary()) -> gzip | compress | deflate | identity | unknown. | |
encoding_map(<<"gzip">>) -> gzip; | |
encoding_map(<<"compress">>) -> compress; | |
encoding_map(<<"deflate">>) -> deflate; | |
encoding_map(<<"identity">>) -> identity; | |
encoding_map(_) -> unknown. | |
-spec encoding_list(binary()) -> [{binary(), non_neg_integer()}]. | |
encoding_list(AcceptEncoding) when is_binary(AcceptEncoding) -> | |
[parse_qval(X) || X <- binary:split(AcceptEncoding, <<",">>, [global])]. | |
-spec parse_qval(binary()) -> {binary(), non_neg_integer()}. | |
parse_qval(S) when is_binary(S) -> | |
S1 = binary:replace(S, <<" ">>, <<"">>, [global]), | |
parse_qval(<<>>, S1). | |
-spec parse_qval(binary(), binary()) -> {binary(), non_neg_integer()}. | |
parse_qval(<<>>, <<>>) -> | |
{<<"identity">>, 1000}; | |
parse_qval(A, <<";q=", Q/binary>>) -> | |
{A, parse_qvalue(Q)}; | |
parse_qval(A, <<"">>) -> | |
{A, 1000}; | |
parse_qval(A, <<C, T/binary>>) -> | |
parse_qval(<<A/binary, C>>, T). | |
-define(DIGIT(X), (X >= $0 andalso X =< $9)). | |
-spec parse_qvalue(binary()) -> non_neg_integer(). | |
parse_qvalue(<<"0">>) -> | |
0; | |
parse_qvalue(<<"0.">>) -> | |
0; | |
parse_qvalue(<<"1">>) -> | |
1000; | |
parse_qvalue(<<"1.">>) -> | |
1000; | |
parse_qvalue(<<"1.0">>) -> | |
1000; | |
parse_qvalue(<<"1.00">>) -> | |
1000; | |
parse_qvalue(<<"1.000">>) -> | |
1000; | |
parse_qvalue(<<"0.", D1, D2, D3>>) | |
when ?DIGIT(D1) andalso ?DIGIT(D2) andalso ?DIGIT(D3) -> | |
list_to_integer([D1, D2, D3]); | |
parse_qvalue(<<"0.", D1, D2>>) | |
when ?DIGIT(D1) andalso ?DIGIT(D2) -> | |
list_to_integer([D1, D2, $0]); | |
parse_qvalue(<<"0.", D1>>) | |
when ?DIGIT(D1) -> | |
list_to_integer([D1, $0, $0]); | |
parse_qvalue(_) -> | |
%% error | |
0. | |
-include_lib("eunit/include/eunit.hrl"). | |
encoding_list_test() -> | |
[{<<"identity">>, 1000}] = encoding_list(<<"">>), | |
[{<<"identity">>, 0}] = encoding_list(<<"identity;q=0">>), | |
[{<<"identity">>, 0}] = encoding_list(<<"identity ;q=0">>), | |
[{<<"identity">>, 0}] = encoding_list(<<" identity; q =0 ">>), | |
[{<<"identity">>, 0}] = encoding_list(<<"identity ; q = 0">>), | |
[{<<"identity">>, 0}] = | |
encoding_list(<<"identity ; q= 0.0">>), | |
[{<<"gzip">>, 1000}, {<<"deflate">>, 1000}, {<<"identity">>, 0}] = | |
encoding_list(<<"gzip,deflate,identity;q=0.0">>), | |
[{<<"deflate">>, 1000}, {<<"gzip">>, 1000}, {<<"identity">>, 0}] = | |
encoding_list(<<"deflate,gzip,identity;q=0.0">>), | |
[{<<"gzip">>, 1000}, {<<"deflate">>, 1000}, {<<"gzip">>, 1000}, | |
{<<"identity">>, 0}] = | |
encoding_list(<<"gzip,deflate,gzip,identity;q=0">>), | |
[{<<"gzip">>, 1000}, {<<"deflate">>, 1000}, {<<"identity">>, 0}] = | |
encoding_list(<<"gzip, deflate , identity; q=0.0">>), | |
[{<<"gzip">>, 1000}, {<<"deflate">>, 1000}, {<<"identity">>, 0}] = | |
encoding_list(<<"gzip; q=1, deflate;q=1.0, identity;q=0.0">>), | |
[{<<"gzip">>, 500}, {<<"deflate">>, 1000}, | |
{<<"identity">>, 0}] = | |
encoding_list(<<"gzip; q=0.5, deflate;q=1.0, identity;q=0">>), | |
[{<<"gzip">>, 500}, {<<"deflate">>, 1000}, | |
{<<"identity">>, 0}] = | |
encoding_list(<<"gzip; q=0.5, deflate , identity;q=0.0">>), | |
[{<<"gzip">>, 500}, {<<"deflate">>, 800}, | |
{<<"identity">>, 0}] = | |
encoding_list(<<"gzip; q=0.5, deflate;q=0.8, identity;q=0.0">>), | |
[{<<"gzip">>, 500}, {<<"deflate">>, 1000}, | |
{<<"identity">>, 1000}] = | |
encoding_list(<<"gzip; q=0.5,deflate,identity">>), | |
[{<<"gzip">>, 500}, {<<"deflate">>, 1000}, {<<"identity">>, 1000}, | |
{<<"identity">>, 1000}] = | |
encoding_list(<<"gzip; q=0.5,deflate,identity, identity ">>), | |
ok. | |
encoding_test() -> | |
identity = encoding(<<"">>), | |
identity = encoding(<<"BadEncoding">>), | |
identity = encoding(<<"identity;q=0">>), | |
identity = encoding(<<"BadEncoding;q=0">>), | |
identity = encoding(<<"identity ;q=0">>), | |
identity = encoding(<<"BadEncoding ;q=0">>), | |
identity = encoding(<<" identity; q =0 ">>), | |
identity = encoding(<<"identity ; q = 0">>), | |
identity = encoding(<<"identity ; q= 0.0">>), | |
gzip = encoding(<<"gzip,deflate,identity;q=0.0">>), | |
deflate = encoding(<<"deflate,gzip,identity;q=0.0">>), | |
gzip = encoding(<<"gzip,deflate,gzip,identity;q=0">>), | |
gzip = encoding(<<"gzip, deflate , identity; q=0.0">>), | |
gzip = encoding(<<"gzip; q=1, deflate;q=1.0, identity;q=0.0">>), | |
gzip = encoding(<<"BadEncoding, gzip; q=1, deflate;q=1.0, identity;q=0.0">>), | |
deflate = encoding(<<"gzip; q=0.5, deflate;q=1.0, identity;q=0">>), | |
deflate = encoding(<<"gzip; q=0.5, deflate , identity;q=0.0">>), | |
deflate = encoding(<<"gzip; q=0.5, deflate;q=0.8, identity;q=0.0">>), | |
deflate = encoding(<<"gzip; q=0.5,deflate,identity">>), | |
deflate = encoding(<<"gzip; q=0.5,deflate,identity, identity ">>), | |
deflate = encoding(<<"BadEncoding, gzip; q=0.5,deflate,identity, identity ">>), | |
ok. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment