Created
November 2, 2011 16:21
-
-
Save puzza007/1334088 to your computer and use it in GitHub Desktop.
This file contains hidden or 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