aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--guide/middlewares.md3
-rw-r--r--guide/routing.md14
-rw-r--r--guide/toc.md7
-rw-r--r--src/cowboy.erl14
-rw-r--r--test/http_SUITE.erl29
5 files changed, 63 insertions, 4 deletions
diff --git a/guide/middlewares.md b/guide/middlewares.md
index 0ab6dc2..b5f055c 100644
--- a/guide/middlewares.md
+++ b/guide/middlewares.md
@@ -58,6 +58,9 @@ will not process any subsequent requests on this connection.
The middlewares that come with Cowboy may define or require other
environment values to perform.
+You can update the environment by calling the `cowboy:set_env/3`
+convenience function, adding or replacing a value in the environment.
+
Routing middleware
------------------
diff --git a/guide/routing.md b/guide/routing.md
index ebf34de..3f71654 100644
--- a/guide/routing.md
+++ b/guide/routing.md
@@ -242,3 +242,17 @@ cowboy:start_http(my_http_listener, 100,
Note that this function will return `{error, badarg}` if the structure
given is incorrect.
+
+Live update
+-----------
+
+You can use the `cowboy:set_env/3` function for updating the dispatch
+list used by routing. This will apply to all new connections accepted
+by the listener.
+
+``` erlang
+cowboy:set_env(my_http_listener, dispatch,
+ cowboy_router:compile(Dispatch)).
+```
+
+Note that you need to compile the routes before updating.
diff --git a/guide/toc.md b/guide/toc.md
index 2f8fa36..2f0d914 100644
--- a/guide/toc.md
+++ b/guide/toc.md
@@ -8,10 +8,11 @@ Cowboy User Guide
* Getting started
* [Routing](routing.md)
* Purpose
- * Dispatch list
- * Match rules
- * Bindings
+ * Structure
+ * Match syntax
* Constraints
+ * Compilation
+ * Live update
* [Handlers](handlers.md)
* Purpose
* Protocol upgrades
diff --git a/src/cowboy.erl b/src/cowboy.erl
index 79dbb71..257172d 100644
--- a/src/cowboy.erl
+++ b/src/cowboy.erl
@@ -18,6 +18,7 @@
-export([start_http/4]).
-export([start_https/4]).
-export([stop_listener/1]).
+-export([set_env/3]).
%% @doc Start an HTTP listener.
-spec start_http(any(), non_neg_integer(), any(), any()) -> {ok, pid()}.
@@ -37,3 +38,16 @@ start_https(Ref, NbAcceptors, TransOpts, ProtoOpts)
-spec stop_listener(any()) -> ok.
stop_listener(Ref) ->
ranch:stop_listener(Ref).
+
+%% @doc Convenience function for setting an environment value.
+%%
+%% Allows you to update live an environment value used by middlewares.
+%% This function is primarily intended to simplify updating the dispatch
+%% list used for routing.
+-spec set_env(any(), atom(), any()) -> ok.
+set_env(Ref, Name, Value) ->
+ Opts = ranch:get_protocol_options(Ref),
+ {_, Env} = lists:keyfind(env, 1, Opts),
+ Env2 = [{Name, Value}|lists:keydelete(Name, 1, Env)],
+ Opts2 = lists:keyreplace(env, 1, Opts, {env, Env2}),
+ ok = ranch:set_protocol_options(Ref, Opts2).
diff --git a/test/http_SUITE.erl b/test/http_SUITE.erl
index 209be7e..8e53dc7 100644
--- a/test/http_SUITE.erl
+++ b/test/http_SUITE.erl
@@ -61,6 +61,7 @@
-export([rest_patch/1]).
-export([rest_resource_etags/1]).
-export([rest_resource_etags_if_none_match/1]).
+-export([set_env_dispatch/1]).
-export([set_resp_body/1]).
-export([set_resp_header/1]).
-export([set_resp_overwrite/1]).
@@ -90,7 +91,8 @@ all() ->
{group, https_compress},
{group, onrequest},
{group, onresponse},
- {group, onresponse_capitalize}
+ {group, onresponse_capitalize},
+ {group, set_env}
].
groups() ->
@@ -159,6 +161,9 @@ groups() ->
]},
{onresponse_capitalize, [], [
onresponse_capitalize
+ ]},
+ {set_env, [], [
+ set_env_dispatch
]}
].
@@ -273,6 +278,17 @@ init_per_group(onresponse_capitalize, Config) ->
]),
{ok, Client} = cowboy_client:init([]),
[{scheme, <<"http">>}, {port, Port}, {opts, []},
+ {transport, Transport}, {client, Client}|Config];
+init_per_group(set_env, Config) ->
+ Port = 33087,
+ Transport = ranch_tcp,
+ {ok, _} = cowboy:start_http(set_env, 100, [{port, Port}], [
+ {env, [{dispatch, []}]},
+ {max_keepalive, 50},
+ {timeout, 500}
+ ]),
+ {ok, Client} = cowboy_client:init([]),
+ [{scheme, <<"http">>}, {port, Port}, {opts, []},
{transport, Transport}, {client, Client}|Config].
end_per_group(Group, Config) when Group =:= https; Group =:= https_compress ->
@@ -923,6 +939,17 @@ rest_resource_etags_if_none_match(Config) ->
{Ret, Type}
end || {Status, ETag, Type} <- Tests].
+set_env_dispatch(Config) ->
+ Client = ?config(client, Config),
+ {ok, Client2} = cowboy_client:request(<<"GET">>,
+ build_url("/", Config), Client),
+ {ok, 400, _, _} = cowboy_client:response(Client2),
+ ok = cowboy:set_env(set_env, dispatch,
+ cowboy_router:compile([{'_', [{"/", http_handler, []}]}])),
+ {ok, Client3} = cowboy_client:request(<<"GET">>,
+ build_url("/", Config), Client),
+ {ok, 200, _, _} = cowboy_client:response(Client3).
+
set_resp_body(Config) ->
Client = ?config(client, Config),
{ok, Client2} = cowboy_client:request(<<"GET">>,