http_server.erl 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. %%--------------------------------------------------------------------
  2. %% A Simple HTTP Server based cowboy
  3. %%
  4. %% It will deliver the http-request params to initialer process
  5. %%--------------------------------------------------------------------
  6. %%
  7. %% Author:wwhai
  8. %%
  9. -module(http_server).
  10. -behaviour(gen_server).
  11. -export([start_link/3]).
  12. -export([stop/1]).
  13. -export([code_change/3, handle_call/3, handle_cast/2, handle_info/2, init/1, init/2, terminate/2]).
  14. -record(state, {parent :: pid()}).
  15. %%--------------------------------------------------------------------
  16. %% APIs
  17. %%--------------------------------------------------------------------
  18. start_link(Parent, BasePort, Opts) ->
  19. stop_http(),
  20. stop_https(),
  21. timer:sleep(100),
  22. gen_server:start_link(?MODULE, {Parent, BasePort, Opts}, []).
  23. init({Parent, BasePort, Opts}) ->
  24. ok = start_http(Parent, [{port, BasePort} | Opts]),
  25. ok = start_https(Parent, [{port, BasePort + 1} | Opts]),
  26. Parent ! {self(), ready},
  27. {ok, #state{parent = Parent}}.
  28. handle_call(_Request, _From, State) ->
  29. {reply, ignored, State}.
  30. handle_cast(_Msg, State) ->
  31. {noreply, State}.
  32. handle_info(_Info, State) ->
  33. {noreply, State}.
  34. terminate(_Reason, _State) ->
  35. stop_http(),
  36. stop_https().
  37. code_change(_OldVsn, State, _Extra) ->
  38. {ok, State}.
  39. stop(Pid) ->
  40. ok = gen_server:stop(Pid).
  41. %%--------------------------------------------------------------------
  42. %% Callbacks
  43. %%--------------------------------------------------------------------
  44. start_http(Parent, Opts) ->
  45. {ok, _Pid1} = cowboy:start_clear(http, Opts, #{
  46. env => #{dispatch => compile_router(Parent)}
  47. }),
  48. Port = proplists:get_value(port, Opts),
  49. io:format(standard_error, "[TEST LOG] Start http server on ~p successfully!~n", [Port]).
  50. start_https(Parent, Opts) ->
  51. Path = emqx_ct_helpers:deps_path(emqx_web_hook, "test/emqx_web_hook_SUITE_data/"),
  52. SslOpts = [{keyfile, Path ++ "/server-key.pem"},
  53. {cacertfile, Path ++ "/ca.pem"},
  54. {certfile, Path ++ "/server-cert.pem"}],
  55. {ok, _Pid2} = cowboy:start_tls(https, Opts ++ SslOpts,
  56. #{env => #{dispatch => compile_router(Parent)}}),
  57. Port = proplists:get_value(port, Opts),
  58. io:format(standard_error, "[TEST LOG] Start https server on ~p successfully!~n", [Port]).
  59. stop_http() ->
  60. cowboy:stop_listener(http),
  61. io:format("[TEST LOG] Stopped http server").
  62. stop_https() ->
  63. cowboy:stop_listener(https),
  64. io:format("[TEST LOG] Stopped https server").
  65. compile_router(Parent) ->
  66. {ok, _} = application:ensure_all_started(cowboy),
  67. cowboy_router:compile([
  68. {'_', [{"/", ?MODULE, #{parent => Parent}}]}
  69. ]).
  70. init(Req, #{parent := Parent} = State) ->
  71. Method = cowboy_req:method(Req),
  72. Headers = cowboy_req:headers(Req),
  73. [Params] = case Method of
  74. <<"GET">> -> cowboy_req:parse_qs(Req);
  75. <<"POST">> ->
  76. {ok, PostVals, _} = cowboy_req:read_urlencoded_body(Req),
  77. PostVals
  78. end,
  79. Parent ! {?MODULE, Params, Headers},
  80. {ok, reply(Req, ok), State}.
  81. reply(Req, ok) ->
  82. cowboy_req:reply(200, #{<<"content-type">> => <<"text/plain">>}, <<"ok">>, Req);
  83. reply(Req, error) ->
  84. cowboy_req:reply(404, #{<<"content-type">> => <<"text/plain">>}, <<"deny">>, Req).