Browse Source

fix(ws): websocket header get expects bin-string

Zaiming (Stone) Shi 3 years ago
parent
commit
a7e948b0f4
3 changed files with 16 additions and 7 deletions
  1. 6 0
      CHANGES-5.0.md
  2. 8 6
      apps/emqx/src/emqx_ws_connection.erl
  3. 2 1
      apps/emqx/test/emqx_channel_SUITE.erl

+ 6 - 0
CHANGES-5.0.md

@@ -1,3 +1,9 @@
+# 5.0.3
+
+## Bug fixes
+
+* Websocket listener failed to read headers `X-Forwared-For` and `X-Forwarded-Port` [8415](https://github.com/emqx/emqx/pull/8415)
+
 # 5.0.2
 # 5.0.2
 
 
 Announcemnet: EMQX team has decided to stop supporting relup for opensouce edition.
 Announcemnet: EMQX team has decided to stop supporting relup for opensouce edition.

+ 8 - 6
apps/emqx/src/emqx_ws_connection.erl

@@ -981,9 +981,8 @@ trigger(Event) -> erlang:send(self(), Event).
 
 
 get_peer(Req, #{listener := {Type, Listener}}) ->
 get_peer(Req, #{listener := {Type, Listener}}) ->
     {PeerAddr, PeerPort} = cowboy_req:peer(Req),
     {PeerAddr, PeerPort} = cowboy_req:peer(Req),
-    AddrHeader = cowboy_req:header(
-        get_ws_opts(Type, Listener, proxy_address_header), Req, <<>>
-    ),
+    AddrHeaderName = get_ws_header_opts(Type, Listener, proxy_address_header),
+    AddrHeader = cowboy_req:header(AddrHeaderName, Req, <<>>),
     ClientAddr =
     ClientAddr =
         case string:tokens(binary_to_list(AddrHeader), ", ") of
         case string:tokens(binary_to_list(AddrHeader), ", ") of
             [] ->
             [] ->
@@ -998,9 +997,8 @@ get_peer(Req, #{listener := {Type, Listener}}) ->
             _ ->
             _ ->
                 PeerAddr
                 PeerAddr
         end,
         end,
-    PortHeader = cowboy_req:header(
-        get_ws_opts(Type, Listener, proxy_port_header), Req, <<>>
-    ),
+    PortHeaderName = get_ws_header_opts(Type, Listener, proxy_port_header),
+    PortHeader = cowboy_req:header(PortHeaderName, Req, <<>>),
     ClientPort =
     ClientPort =
         case string:tokens(binary_to_list(PortHeader), ", ") of
         case string:tokens(binary_to_list(PortHeader), ", ") of
             [] ->
             [] ->
@@ -1042,6 +1040,10 @@ set_field(Name, Value, State) ->
     Pos = emqx_misc:index_of(Name, record_info(fields, state)),
     Pos = emqx_misc:index_of(Name, record_info(fields, state)),
     setelement(Pos + 1, State, Value).
     setelement(Pos + 1, State, Value).
 
 
+%% ensure lowercase letters in headers
+get_ws_header_opts(Type, Listener, Key) ->
+    iolist_to_binary(string:lowercase(get_ws_opts(Type, Listener, Key))).
+
 get_ws_opts(Type, Listener, Key) ->
 get_ws_opts(Type, Listener, Key) ->
     emqx_config:get_listener_conf(Type, Listener, [websocket, Key]).
     emqx_config:get_listener_conf(Type, Listener, [websocket, Key]).
 
 

+ 2 - 1
apps/emqx/test/emqx_channel_SUITE.erl

@@ -156,7 +156,8 @@ listener_mqtt_ws_conf() ->
                 max_frame_size => infinity,
                 max_frame_size => infinity,
                 mqtt_path => "/mqtt",
                 mqtt_path => "/mqtt",
                 mqtt_piggyback => multiple,
                 mqtt_piggyback => multiple,
-                proxy_address_header => "x-forwarded-for",
+                % should allow uppercase in config
+                proxy_address_header => "X-Forwarded-For",
                 proxy_port_header => "x-forwarded-port",
                 proxy_port_header => "x-forwarded-port",
                 supported_subprotocols =>
                 supported_subprotocols =>
                     ["mqtt", "mqtt-v3", "mqtt-v3.1.1", "mqtt-v5"]
                     ["mqtt", "mqtt-v3", "mqtt-v3.1.1", "mqtt-v5"]