emqx_authn_http_test_server.erl 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. %%--------------------------------------------------------------------
  2. %% Copyright (c) 2020-2022 EMQ Technologies Co., Ltd. All Rights Reserved.
  3. %%
  4. %% Licensed under the Apache License, Version 2.0 (the "License");
  5. %% you may not use this file except in compliance with the License.
  6. %% You may obtain a copy of the License at
  7. %%
  8. %% http://www.apache.org/licenses/LICENSE-2.0
  9. %%
  10. %% Unless required by applicable law or agreed to in writing, software
  11. %% distributed under the License is distributed on an "AS IS" BASIS,
  12. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. %% See the License for the specific language governing permissions and
  14. %% limitations under the License.
  15. %%--------------------------------------------------------------------
  16. -module(emqx_authn_http_test_server).
  17. -behaviour(supervisor).
  18. -behaviour(cowboy_handler).
  19. % cowboy_server callbacks
  20. -export([init/2]).
  21. % supervisor callbacks
  22. -export([init/1]).
  23. % API
  24. -export([start_link/2,
  25. start_link/3,
  26. stop/0,
  27. set_handler/1
  28. ]).
  29. %%------------------------------------------------------------------------------
  30. %% API
  31. %%------------------------------------------------------------------------------
  32. start_link(Port, Path) ->
  33. start_link(Port, Path, false).
  34. start_link(Port, Path, SSLOpts) ->
  35. supervisor:start_link({local, ?MODULE}, ?MODULE, [Port, Path, SSLOpts]).
  36. stop() ->
  37. gen_server:stop(?MODULE).
  38. set_handler(F) when is_function(F, 2) ->
  39. true = ets:insert(?MODULE, {handler, F}),
  40. ok.
  41. %%------------------------------------------------------------------------------
  42. %% supervisor API
  43. %%------------------------------------------------------------------------------
  44. init([Port, Path, SSLOpts]) ->
  45. Dispatch = cowboy_router:compile(
  46. [
  47. {'_', [{Path, ?MODULE, []}]}
  48. ]),
  49. ProtoOpts = #{env => #{dispatch => Dispatch}},
  50. Tab = ets:new(?MODULE, [set, named_table, public]),
  51. ets:insert(Tab, {handler, fun default_handler/2}),
  52. {Transport, TransOpts, CowboyModule} = transport_settings(Port, SSLOpts),
  53. ChildSpec = ranch:child_spec(?MODULE, Transport, TransOpts, CowboyModule, ProtoOpts),
  54. {ok, {#{}, [ChildSpec]}}.
  55. %%------------------------------------------------------------------------------
  56. %% cowboy_server API
  57. %%------------------------------------------------------------------------------
  58. init(Req, State) ->
  59. [{handler, Handler}] = ets:lookup(?MODULE, handler),
  60. Handler(Req, State).
  61. %%------------------------------------------------------------------------------
  62. %% Internal functions
  63. %%------------------------------------------------------------------------------
  64. transport_settings(Port, false) ->
  65. TransOpts = #{socket_opts => [{port, Port}],
  66. connection_type => supervisor},
  67. {ranch_tcp, TransOpts, cowboy_clear};
  68. transport_settings(Port, SSLOpts) ->
  69. TransOpts = #{socket_opts => [{port, Port},
  70. {next_protocols_advertised, [<<"h2">>, <<"http/1.1">>]},
  71. {alpn_preferred_protocols, [<<"h2">>, <<"http/1.1">>]}
  72. | SSLOpts],
  73. connection_type => supervisor},
  74. {ranch_ssl, TransOpts, cowboy_tls}.
  75. default_handler(Req0, State) ->
  76. Req = cowboy_req:reply(
  77. 400,
  78. #{<<"content-type">> => <<"text/plain">>},
  79. <<"">>,
  80. Req0),
  81. {ok, Req, State}.