Browse Source

Add cowboy:set_env/3

Loïc Hoguin 12 years ago
parent
commit
b2ffff9bec
5 changed files with 63 additions and 4 deletions
  1. 3 0
      guide/middlewares.md
  2. 14 0
      guide/routing.md
  3. 4 3
      guide/toc.md
  4. 14 0
      src/cowboy.erl
  5. 28 1
      test/http_SUITE.erl

+ 3 - 0
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
 The middlewares that come with Cowboy may define or require other
 environment values to perform.
 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
 Routing middleware
 ------------------
 ------------------
 
 

+ 14 - 0
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
 Note that this function will return `{error, badarg}` if the structure
 given is incorrect.
 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.

+ 4 - 3
guide/toc.md

@@ -8,10 +8,11 @@ Cowboy User Guide
    *  Getting started
    *  Getting started
  *  [Routing](routing.md)
  *  [Routing](routing.md)
    *  Purpose
    *  Purpose
-   *  Dispatch list
-   *  Match rules
-   *  Bindings
+   *  Structure
+   *  Match syntax
    *  Constraints
    *  Constraints
+   *  Compilation
+   *  Live update
  *  [Handlers](handlers.md)
  *  [Handlers](handlers.md)
    *  Purpose
    *  Purpose
    *  Protocol upgrades
    *  Protocol upgrades

+ 14 - 0
src/cowboy.erl

@@ -18,6 +18,7 @@
 -export([start_http/4]).
 -export([start_http/4]).
 -export([start_https/4]).
 -export([start_https/4]).
 -export([stop_listener/1]).
 -export([stop_listener/1]).
+-export([set_env/3]).
 
 
 %% @doc Start an HTTP listener.
 %% @doc Start an HTTP listener.
 -spec start_http(any(), non_neg_integer(), any(), any()) -> {ok, pid()}.
 -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.
 -spec stop_listener(any()) -> ok.
 stop_listener(Ref) ->
 stop_listener(Ref) ->
 	ranch: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).

+ 28 - 1
test/http_SUITE.erl

@@ -61,6 +61,7 @@
 -export([rest_patch/1]).
 -export([rest_patch/1]).
 -export([rest_resource_etags/1]).
 -export([rest_resource_etags/1]).
 -export([rest_resource_etags_if_none_match/1]).
 -export([rest_resource_etags_if_none_match/1]).
+-export([set_env_dispatch/1]).
 -export([set_resp_body/1]).
 -export([set_resp_body/1]).
 -export([set_resp_header/1]).
 -export([set_resp_header/1]).
 -export([set_resp_overwrite/1]).
 -export([set_resp_overwrite/1]).
@@ -90,7 +91,8 @@ all() ->
 		{group, https_compress},
 		{group, https_compress},
 		{group, onrequest},
 		{group, onrequest},
 		{group, onresponse},
 		{group, onresponse},
-		{group, onresponse_capitalize}
+		{group, onresponse_capitalize},
+		{group, set_env}
 	].
 	].
 
 
 groups() ->
 groups() ->
@@ -159,6 +161,9 @@ groups() ->
 		]},
 		]},
 		{onresponse_capitalize, [], [
 		{onresponse_capitalize, [], [
 			onresponse_capitalize
 			onresponse_capitalize
+		]},
+		{set_env, [], [
+			set_env_dispatch
 		]}
 		]}
 	].
 	].
 
 
@@ -273,6 +278,17 @@ init_per_group(onresponse_capitalize, Config) ->
 	]),
 	]),
 	{ok, Client} = cowboy_client:init([]),
 	{ok, Client} = cowboy_client:init([]),
 	[{scheme, <<"http">>}, {port, Port}, {opts, []},
 	[{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].
 		{transport, Transport}, {client, Client}|Config].
 
 
 end_per_group(Group, Config) when Group =:= https; Group =:= https_compress ->
 end_per_group(Group, Config) when Group =:= https; Group =:= https_compress ->
@@ -923,6 +939,17 @@ rest_resource_etags_if_none_match(Config) ->
 		{Ret, Type}
 		{Ret, Type}
 	end || {Status, ETag, Type} <- Tests].
 	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) ->
 set_resp_body(Config) ->
 	Client = ?config(client, Config),
 	Client = ?config(client, Config),
 	{ok, Client2} = cowboy_client:request(<<"GET">>,
 	{ok, Client2} = cowboy_client:request(<<"GET">>,