Explorar o código

Merge pull request #13761 from zmstone/0903-fix-http-header-order

fix: http headers merge action on connector
zmstone hai 1 ano
pai
achega
7bdadea7e5

+ 1 - 1
apps/emqx_bridge_http/src/emqx_bridge_http.app.src

@@ -1,6 +1,6 @@
 {application, emqx_bridge_http, [
     {description, "EMQX HTTP Bridge and Connector Application"},
-    {vsn, "0.3.4"},
+    {vsn, "0.3.5"},
     {registered, []},
     {applications, [kernel, stdlib, emqx_resource, ehttpc]},
     {env, [

+ 10 - 18
apps/emqx_bridge_http/src/emqx_bridge_http_connector.erl

@@ -753,11 +753,11 @@ process_request_and_action(Request, ActionState, Msg) ->
             _ -> join_paths(PathPrefix, PathSuffix)
         end,
 
-    HeadersTemplate1 = maps:get(headers, Request),
-    HeadersTemplate2 = maps:get(headers, ActionState),
-    Headers = merge_proplist(
-        render_headers(HeadersTemplate1, RenderTmplFunc, Msg),
-        render_headers(HeadersTemplate2, RenderTmplFunc, Msg)
+    ActionHaders = maps:get(headers, ActionState),
+    BaseHeaders = maps:get(headers, Request),
+    Headers = merge_headers(
+        render_headers(ActionHaders, RenderTmplFunc, Msg),
+        render_headers(BaseHeaders, RenderTmplFunc, Msg)
     ),
     BodyTemplate = maps:get(body, ActionState),
     Body = render_request_body(BodyTemplate, RenderTmplFunc, Msg),
@@ -769,19 +769,11 @@ process_request_and_action(Request, ActionState, Msg) ->
         request_timeout => maps:get(request_timeout, ActionState)
     }.
 
-merge_proplist(Proplist1, Proplist2) ->
-    lists:foldl(
-        fun({K, V}, Acc) ->
-            case lists:keyfind(K, 1, Acc) of
-                false ->
-                    [{K, V} | Acc];
-                {K, _} = {K, V1} ->
-                    [{K, V1} | Acc]
-            end
-        end,
-        Proplist2,
-        Proplist1
-    ).
+merge_headers([], Result) ->
+    Result;
+merge_headers([{K, V} | Rest], Result) ->
+    R = lists:keydelete(K, 1, Result),
+    merge_headers(Rest, [{K, V} | R]).
 
 process_request(
     #{

+ 31 - 6
apps/emqx_bridge_http/test/emqx_bridge_http_v2_SUITE.erl

@@ -132,9 +132,14 @@ t_update_with_sensitive_data(Config) ->
             AuthHeader = <<"Bearer some_token">>,
             ConnectorCfg1 = emqx_utils_maps:deep_merge(
                 ConnectorCfg0,
-                #{<<"headers">> => #{<<"authorization">> => AuthHeader}}
+                #{
+                    <<"headers">> => #{
+                        <<"authorization">> => AuthHeader,
+                        <<"x-test-header">> => <<"from-connector">>
+                    }
+                }
             ),
-            ActionCfg = make_action_config(Config),
+            ActionCfg = make_action_config(Config, #{<<"x-test-header">> => <<"from-action">>}),
             CreateConfig = [
                 {bridge_kind, action},
                 {action_type, ?BRIDGE_TYPE},
@@ -156,7 +161,14 @@ t_update_with_sensitive_data(Config) ->
                 }
             ),
             emqx:publish(emqx_message:make(<<"t/http">>, <<"1">>)),
-            ?assertReceive({http, #{<<"authorization">> := AuthHeader}, _}),
+            ?assertReceive(
+                {http,
+                    #{
+                        <<"authorization">> := AuthHeader,
+                        <<"x-test-header">> := <<"from-action">>
+                    },
+                    _}
+            ),
 
             %% Now update the connector and see if the header stays deobfuscated.  We send the old
             %% auth header as an obfuscated value to simulate the behavior of the frontend.
@@ -165,6 +177,8 @@ t_update_with_sensitive_data(Config) ->
                 #{
                     <<"headers">> => #{
                         <<"authorization">> => Obfuscated,
+                        <<"x-test-header">> => <<"from-connector-new">>,
+                        <<"x-test-header-2">> => <<"from-connector-new">>,
                         <<"other_header">> => <<"new">>
                     }
                 }
@@ -177,8 +191,16 @@ t_update_with_sensitive_data(Config) ->
 
             emqx:publish(emqx_message:make(<<"t/http">>, <<"2">>)),
             %% Should not be obfuscated.
-            ?assertReceive({http, #{<<"authorization">> := AuthHeader}, _}, 2_000),
-
+            ?assertReceive(
+                {http,
+                    #{
+                        <<"authorization">> := AuthHeader,
+                        <<"x-test-header">> := <<"from-action">>,
+                        <<"x-test-header-2">> := <<"from-connector-new">>
+                    },
+                    _},
+                2_000
+            ),
             ok
         end,
         []
@@ -204,6 +226,9 @@ make_connector_config(Config) ->
     }.
 
 make_action_config(Config) ->
+    make_action_config(Config, _Headers = #{}).
+
+make_action_config(Config, Headers) ->
     Path = ?config(path, Config),
     #{
         <<"enable">> => true,
@@ -211,7 +236,7 @@ make_action_config(Config) ->
         <<"parameters">> => #{
             <<"path">> => Path,
             <<"method">> => <<"post">>,
-            <<"headers">> => #{},
+            <<"headers">> => Headers,
             <<"body">> => <<"${.}">>
         },
         <<"resource_opts">> => #{