cowboy.erl (3867B)
1 %% Copyright (c) 2011-2017, Loïc Hoguin <essen@ninenines.eu> 2 %% 3 %% Permission to use, copy, modify, and/or distribute this software for any 4 %% purpose with or without fee is hereby granted, provided that the above 5 %% copyright notice and this permission notice appear in all copies. 6 %% 7 %% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8 %% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9 %% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 10 %% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11 %% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 12 %% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 13 %% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 15 -module(cowboy). 16 17 -export([start_clear/3]). 18 -export([start_tls/3]). 19 -export([stop_listener/1]). 20 -export([set_env/3]). 21 22 %% Internal. 23 -export([log/2]). 24 -export([log/4]). 25 26 -type opts() :: cowboy_http:opts() | cowboy_http2:opts(). 27 -export_type([opts/0]). 28 29 -type fields() :: [atom() 30 | {atom(), cowboy_constraints:constraint() | [cowboy_constraints:constraint()]} 31 | {atom(), cowboy_constraints:constraint() | [cowboy_constraints:constraint()], any()}]. 32 -export_type([fields/0]). 33 34 -type http_headers() :: #{binary() => iodata()}. 35 -export_type([http_headers/0]). 36 37 -type http_status() :: non_neg_integer() | binary(). 38 -export_type([http_status/0]). 39 40 -type http_version() :: 'HTTP/2' | 'HTTP/1.1' | 'HTTP/1.0'. 41 -export_type([http_version/0]). 42 43 -spec start_clear(ranch:ref(), ranch:opts(), opts()) 44 -> {ok, pid()} | {error, any()}. 45 start_clear(Ref, TransOpts0, ProtoOpts0) -> 46 TransOpts1 = ranch:normalize_opts(TransOpts0), 47 {TransOpts, ConnectionType} = ensure_connection_type(TransOpts1), 48 ProtoOpts = ProtoOpts0#{connection_type => ConnectionType}, 49 ranch:start_listener(Ref, ranch_tcp, TransOpts, cowboy_clear, ProtoOpts). 50 51 -spec start_tls(ranch:ref(), ranch:opts(), opts()) 52 -> {ok, pid()} | {error, any()}. 53 start_tls(Ref, TransOpts0, ProtoOpts0) -> 54 TransOpts1 = ranch:normalize_opts(TransOpts0), 55 SocketOpts = maps:get(socket_opts, TransOpts1, []), 56 TransOpts2 = TransOpts1#{socket_opts => [ 57 {next_protocols_advertised, [<<"h2">>, <<"http/1.1">>]}, 58 {alpn_preferred_protocols, [<<"h2">>, <<"http/1.1">>]} 59 |SocketOpts]}, 60 {TransOpts, ConnectionType} = ensure_connection_type(TransOpts2), 61 ProtoOpts = ProtoOpts0#{connection_type => ConnectionType}, 62 ranch:start_listener(Ref, ranch_ssl, TransOpts, cowboy_tls, ProtoOpts). 63 64 ensure_connection_type(TransOpts=#{connection_type := ConnectionType}) -> 65 {TransOpts, ConnectionType}; 66 ensure_connection_type(TransOpts) -> 67 {TransOpts#{connection_type => supervisor}, supervisor}. 68 69 -spec stop_listener(ranch:ref()) -> ok | {error, not_found}. 70 stop_listener(Ref) -> 71 ranch:stop_listener(Ref). 72 73 -spec set_env(ranch:ref(), atom(), any()) -> ok. 74 set_env(Ref, Name, Value) -> 75 Opts = ranch:get_protocol_options(Ref), 76 Env = maps:get(env, Opts, #{}), 77 Opts2 = maps:put(env, maps:put(Name, Value, Env), Opts), 78 ok = ranch:set_protocol_options(Ref, Opts2). 79 80 %% Internal. 81 82 -spec log({log, logger:level(), io:format(), list()}, opts()) -> ok. 83 log({log, Level, Format, Args}, Opts) -> 84 log(Level, Format, Args, Opts). 85 86 -spec log(logger:level(), io:format(), list(), opts()) -> ok. 87 log(Level, Format, Args, #{logger := Logger}) 88 when Logger =/= error_logger -> 89 _ = Logger:Level(Format, Args), 90 ok; 91 %% We use error_logger by default. Because error_logger does 92 %% not have all the levels we accept we have to do some 93 %% mapping to error_logger functions. 94 log(Level, Format, Args, _) -> 95 Function = case Level of 96 emergency -> error_msg; 97 alert -> error_msg; 98 critical -> error_msg; 99 error -> error_msg; 100 warning -> warning_msg; 101 notice -> warning_msg; 102 info -> info_msg; 103 debug -> info_msg 104 end, 105 error_logger:Function(Format, Args).