diff options
-rw-r--r-- | src/erlang-oauth/oauth_uri.erl | 66 | ||||
-rwxr-xr-x | test/etap/190-oauth.t | 31 | ||||
-rw-r--r-- | test/etap/Makefile.am | 1 |
3 files changed, 70 insertions, 28 deletions
diff --git a/src/erlang-oauth/oauth_uri.erl b/src/erlang-oauth/oauth_uri.erl index 3bdc9076..5023f983 100644 --- a/src/erlang-oauth/oauth_uri.erl +++ b/src/erlang-oauth/oauth_uri.erl @@ -6,14 +6,6 @@ -import(lists, [concat/1]). --define(is_uppercase_alpha(C), C >= $A, C =< $Z). --define(is_lowercase_alpha(C), C >= $a, C =< $z). --define(is_alpha(C), ?is_uppercase_alpha(C); ?is_lowercase_alpha(C)). --define(is_digit(C), C >= $0, C =< $9). --define(is_alphanumeric(C), ?is_alpha(C); ?is_digit(C)). --define(is_unreserved(C), ?is_alphanumeric(C); C =:= $-; C =:= $_; C =:= $.; C =:= $~). --define(is_hex(C), ?is_digit(C); C >= $A, C =< $F). - normalize(URI) -> case http_uri:parse(URI) of @@ -66,23 +58,41 @@ intersperse(_, [X]) -> [X]; intersperse(Sep, [X|Xs]) -> [X, Sep|intersperse(Sep, Xs)]. -decode(Chars) -> - decode(Chars, []). - -decode([], Decoded) -> - lists:reverse(Decoded); -decode([$%,A,B|Etc], Decoded) when ?is_hex(A), ?is_hex(B) -> - decode(Etc, [erlang:list_to_integer([A,B], 16)|Decoded]); -decode([C|Etc], Decoded) when ?is_unreserved(C) -> - decode(Etc, [C|Decoded]). - -encode(Chars) -> - encode(Chars, []). - -encode([], Encoded) -> - lists:flatten(lists:reverse(Encoded)); -encode([C|Etc], Encoded) when ?is_unreserved(C) -> - encode(Etc, [C|Encoded]); -encode([C|Etc], Encoded) -> - Value = io_lib:format("%~2.2.0s", [erlang:integer_to_list(C, 16)]), - encode(Etc, [Value|Encoded]). +-define(is_alphanum(C), C >= $A, C =< $Z; C >= $a, C =< $z; C >= $0, C =< $9). + +encode(Term) when is_integer(Term) -> + integer_to_list(Term); +encode(Term) when is_atom(Term) -> + encode(atom_to_list(Term)); +encode(Term) when is_list(Term) -> + encode(lists:reverse(Term, []), []). + +encode([X | T], Acc) when ?is_alphanum(X); X =:= $-; X =:= $_; X =:= $.; X =:= $~ -> + encode(T, [X | Acc]); +encode([X | T], Acc) -> + NewAcc = [$%, dec2hex(X bsr 4), dec2hex(X band 16#0f) | Acc], + encode(T, NewAcc); +encode([], Acc) -> + Acc. + +decode(Str) when is_list(Str) -> + decode(Str, []). + +decode([$%, A, B | T], Acc) -> + decode(T, [(hex2dec(A) bsl 4) + hex2dec(B) | Acc]); +decode([X | T], Acc) -> + decode(T, [X | Acc]); +decode([], Acc) -> + lists:reverse(Acc, []). + +-compile({inline, [{dec2hex, 1}, {hex2dec, 1}]}). + +dec2hex(N) when N >= 10 andalso N =< 15 -> + N + $A - 10; +dec2hex(N) when N >= 0 andalso N =< 9 -> + N + $0. + +hex2dec(C) when C >= $A andalso C =< $F -> + C - $A + 10; +hex2dec(C) when C >= $0 andalso C =< $9 -> + C - $0. diff --git a/test/etap/190-oauth.t b/test/etap/190-oauth.t new file mode 100755 index 00000000..09922049 --- /dev/null +++ b/test/etap/190-oauth.t @@ -0,0 +1,31 @@ +#!/usr/bin/env escript +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +main(_) -> + test_util:init_code_path(), + etap:plan(1), + case (catch test()) of + ok -> + etap:end_tests(); + Other -> + etap:diag(io_lib:format("Test died abnormally: ~p", [Other])), + etap:bail(Other) + end, + ok. + +test() -> + etap:is( + oauth_uri:params_from_string("realm=http://localhost:5984"), + [{"realm","http://localhost:5984"}], + "decode should handle non-percent encoded input."), + ok. diff --git a/test/etap/Makefile.am b/test/etap/Makefile.am index 9ba3fcfa..1b14b9e1 100644 --- a/test/etap/Makefile.am +++ b/test/etap/Makefile.am @@ -85,4 +85,5 @@ EXTRA_DIST = \ 173-os-daemon-cfg-register.t \ 180-http-proxy.ini \ 180-http-proxy.t \ + 190-oauth.t \ 200-view-group-no-db-leaks.t |