From b2ffff9bec7f9d137ab5abdc3b77203914b5ae63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Hoguin?= Date: Wed, 20 Feb 2013 12:14:21 +0100 Subject: Add cowboy:set_env/3 --- guide/middlewares.md | 3 +++ guide/routing.md | 14 ++++++++++++++ guide/toc.md | 7 ++++--- src/cowboy.erl | 14 ++++++++++++++ test/http_SUITE.erl | 29 ++++++++++++++++++++++++++++- 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 ]} ]. @@ -272,6 +277,17 @@ init_per_group(onresponse_capitalize, Config) -> {timeout, 500} ]), {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]. @@ -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">>, -- cgit v1.2.3