Merge pull request #4283 from zmstone/add-emqx-http-lib
refactor(http-lib): Add emqx_http_lib
This commit is contained in:
commit
42098b497f
|
@ -250,8 +250,4 @@ uri(Parts) when is_list(Parts) ->
|
||||||
NParts = [b2l(E) || E <- Parts],
|
NParts = [b2l(E) || E <- Parts],
|
||||||
?HOST ++ filename:join([?BASE_PATH, ?API_VERSION, "acl"| NParts]).
|
?HOST ++ filename:join([?BASE_PATH, ?API_VERSION, "acl"| NParts]).
|
||||||
|
|
||||||
%% @private
|
b2l(B) -> binary_to_list(emqx_http_lib:uri_encode(iolist_to_binary(B))).
|
||||||
b2l(B) when is_binary(B) ->
|
|
||||||
http_uri:encode(binary_to_list(B));
|
|
||||||
b2l(L) when is_list(L) ->
|
|
||||||
http_uri:encode(L).
|
|
||||||
|
|
|
@ -241,7 +241,7 @@ handle_received_publish(Topic, MaxAge, Format, Payload) ->
|
||||||
handle_received_create(TopicPrefix, MaxAge, Payload) ->
|
handle_received_create(TopicPrefix, MaxAge, Payload) ->
|
||||||
case core_link:decode(Payload) of
|
case core_link:decode(Payload) of
|
||||||
[{rootless, [Topic], [{ct, CT}]}] when is_binary(Topic), Topic =/= <<>> ->
|
[{rootless, [Topic], [{ct, CT}]}] when is_binary(Topic), Topic =/= <<>> ->
|
||||||
TrueTopic = percent_decode(Topic),
|
TrueTopic = emqx_http_lib:uri_decode(Topic),
|
||||||
?LOG(debug, "decoded link-format payload, the Topic=~p, CT=~p~n", [TrueTopic, CT]),
|
?LOG(debug, "decoded link-format payload, the Topic=~p, CT=~p~n", [TrueTopic, CT]),
|
||||||
LocPath = concatenate_location_path([<<"ps">>, TopicPrefix, TrueTopic]),
|
LocPath = concatenate_location_path([<<"ps">>, TopicPrefix, TrueTopic]),
|
||||||
FullTopic = binary:part(LocPath, 4, byte_size(LocPath)-4),
|
FullTopic = binary:part(LocPath, 4, byte_size(LocPath)-4),
|
||||||
|
@ -259,14 +259,6 @@ handle_received_create(TopicPrefix, MaxAge, Payload) ->
|
||||||
{error, bad_request}
|
{error, bad_request}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%% @private Copy from http_uri.erl which has been deprecated since OTP-23
|
|
||||||
percent_decode(<<$%, Hex:2/binary, Rest/bits>>) ->
|
|
||||||
<<(binary_to_integer(Hex, 16)), (percent_decode(Rest))/binary>>;
|
|
||||||
percent_decode(<<First:1/binary, Rest/bits>>) ->
|
|
||||||
<<First/binary, (percent_decode(Rest))/binary>>;
|
|
||||||
percent_decode(<<>>) ->
|
|
||||||
<<>>.
|
|
||||||
|
|
||||||
%% When topic is timeout, server should return nocontent here,
|
%% When topic is timeout, server should return nocontent here,
|
||||||
%% but gen_coap only receive return value of #coap_content from coap_get, so temporarily we can't give the Code 2.07 {ok, nocontent} out.TBC!!!
|
%% but gen_coap only receive return value of #coap_content from coap_get, so temporarily we can't give the Code 2.07 {ok, nocontent} out.TBC!!!
|
||||||
return_resource(Topic, Payload, MaxAge, TimeStamp, Content) ->
|
return_resource(Topic, Payload, MaxAge, TimeStamp, Content) ->
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% 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.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_http_lib).
|
||||||
|
|
||||||
|
-export([uri_encode/1, uri_decode/1]).
|
||||||
|
|
||||||
|
%% @doc Decode percent-encoded URI.
|
||||||
|
%% This is copied from http_uri.erl which has been deprecated since OTP-23
|
||||||
|
%% The recommended replacement uri_string function is not quite equivalent
|
||||||
|
%% and not backward compatible.
|
||||||
|
-spec uri_decode(binary()) -> binary().
|
||||||
|
uri_decode(<<$%, Hex:2/binary, Rest/bits>>) ->
|
||||||
|
<<(binary_to_integer(Hex, 16)), (uri_decode(Rest))/binary>>;
|
||||||
|
uri_decode(<<First:1/binary, Rest/bits>>) ->
|
||||||
|
<<First/binary, (uri_decode(Rest))/binary>>;
|
||||||
|
uri_decode(<<>>) ->
|
||||||
|
<<>>.
|
||||||
|
|
||||||
|
%% @doc Encode URI.
|
||||||
|
-spec uri_encode(binary()) -> binary().
|
||||||
|
uri_encode(URI) when is_binary(URI) ->
|
||||||
|
<< <<(uri_encode_binary(Char))/binary>> || <<Char>> <= URI >>.
|
||||||
|
|
||||||
|
uri_encode_binary(Char) ->
|
||||||
|
case reserved(Char) of
|
||||||
|
true ->
|
||||||
|
<< $%, (integer_to_binary(Char, 16))/binary >>;
|
||||||
|
false ->
|
||||||
|
<<Char>>
|
||||||
|
end.
|
||||||
|
|
||||||
|
reserved($;) -> true;
|
||||||
|
reserved($:) -> true;
|
||||||
|
reserved($@) -> true;
|
||||||
|
reserved($&) -> true;
|
||||||
|
reserved($=) -> true;
|
||||||
|
reserved($+) -> true;
|
||||||
|
reserved($,) -> true;
|
||||||
|
reserved($/) -> true;
|
||||||
|
reserved($?) -> true;
|
||||||
|
reserved($#) -> true;
|
||||||
|
reserved($[) -> true;
|
||||||
|
reserved($]) -> true;
|
||||||
|
reserved($<) -> true;
|
||||||
|
reserved($>) -> true;
|
||||||
|
reserved($\") -> true;
|
||||||
|
reserved(${) -> true;
|
||||||
|
reserved($}) -> true;
|
||||||
|
reserved($|) -> true;
|
||||||
|
reserved($\\) -> true;
|
||||||
|
reserved($') -> true;
|
||||||
|
reserved($^) -> true;
|
||||||
|
reserved($%) -> true;
|
||||||
|
reserved($\s) -> true;
|
||||||
|
reserved(_) -> false.
|
|
@ -0,0 +1,46 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2021 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% 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.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_http_lib_tests).
|
||||||
|
|
||||||
|
-include_lib("proper/include/proper.hrl").
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
uri_encode_decode_test_() ->
|
||||||
|
Opts = [{numtests, 1000}, {to_file, user}],
|
||||||
|
{timeout, 10,
|
||||||
|
fun() -> ?assert(proper:quickcheck(prop_run(), Opts)) end}.
|
||||||
|
|
||||||
|
prop_run() ->
|
||||||
|
?FORALL(Generated, prop_uri(), test_prop_uri(iolist_to_binary(Generated))).
|
||||||
|
|
||||||
|
prop_uri() ->
|
||||||
|
proper_types:non_empty(proper_types:list(proper_types:union([prop_char(), prop_reserved()]))).
|
||||||
|
|
||||||
|
prop_char() -> proper_types:integer(32, 126).
|
||||||
|
|
||||||
|
prop_reserved() ->
|
||||||
|
proper_types:oneof([$;, $:, $@, $&, $=, $+, $,, $/, $?,
|
||||||
|
$#, $[, $], $<, $>, $\", ${, $}, $|,
|
||||||
|
$\\, $', $^, $%, $ ]).
|
||||||
|
|
||||||
|
test_prop_uri(URI) ->
|
||||||
|
Encoded = emqx_http_lib:uri_encode(URI),
|
||||||
|
Decoded1 = emqx_http_lib:uri_decode(Encoded),
|
||||||
|
?assertEqual(URI, Decoded1),
|
||||||
|
Decoded2 = uri_string:percent_decode(Encoded),
|
||||||
|
?assertEqual(URI, Decoded2),
|
||||||
|
true.
|
Loading…
Reference in New Issue