You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by be...@apache.org on 2011/02/26 11:24:37 UTC
svn commit: r1074816 - in /couchdb/trunk: etc/couchdb/default.ini.tpl.in
src/couchdb/couch_httpd.erl src/couchdb/couch_httpd_vhost.erl
Author: benoitc
Date: Sat Feb 26 10:24:36 2011
New Revision: 1074816
URL: http://svn.apache.org/viewvc?rev=1074816&view=rev
Log:
fix COUCHDB-855 . now the gen_server is only used to store vhosts settings. It also reload them when they change.
Modified:
couchdb/trunk/etc/couchdb/default.ini.tpl.in
couchdb/trunk/src/couchdb/couch_httpd.erl
couchdb/trunk/src/couchdb/couch_httpd_vhost.erl
Modified: couchdb/trunk/etc/couchdb/default.ini.tpl.in
URL: http://svn.apache.org/viewvc/couchdb/trunk/etc/couchdb/default.ini.tpl.in?rev=1074816&r1=1074815&r2=1074816&view=diff
==============================================================================
--- couchdb/trunk/etc/couchdb/default.ini.tpl.in (original)
+++ couchdb/trunk/etc/couchdb/default.ini.tpl.in Sat Feb 26 10:24:36 2011
@@ -54,13 +54,13 @@ os_process_limit = 25
view_manager={couch_view, start_link, []}
external_manager={couch_external_manager, start_link, []}
query_servers={couch_query_servers, start_link, []}
+vhosts={couch_httpd_vhost, start_link, []}
httpd={couch_httpd, start_link, []}
stats_aggregator={couch_stats_aggregator, start, []}
stats_collector={couch_stats_collector, start, []}
uuids={couch_uuids, start, []}
auth_cache={couch_auth_cache, start_link, []}
rep_db_changes_listener={couch_rep_db_listener, start_link, []}
-vhosts={couch_httpd_vhost, start_link, []}
os_daemons={couch_os_daemons, start_link, []}
[httpd_global_handlers]
Modified: couchdb/trunk/src/couchdb/couch_httpd.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd.erl?rev=1074816&r1=1074815&r2=1074816&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd.erl Sat Feb 26 10:24:36 2011
@@ -85,6 +85,10 @@ start_link(Name, Options) ->
couch_config:get("httpd", "server_options", "[]")),
{ok, SocketOptions} = couch_util:parse_term(
couch_config:get("httpd", "socket_options", "[]")),
+
+ % install vhosts rules
+ couch_httpd_vhost:install(),
+
Loop = fun(Req)->
case SocketOptions of
[] ->
@@ -133,8 +137,6 @@ config_change("httpd_global_handlers", _
?MODULE:stop();
config_change("httpd_db_handlers", _) ->
?MODULE:stop();
-config_change("vhosts", _) ->
- ?MODULE:stop();
config_change("ssl", _) ->
?MODULE:stop().
@@ -171,7 +173,8 @@ make_fun_spec_strs(SpecStr) ->
handle_request(MochiReq, DefaultFun, UrlHandlers, DbUrlHandlers,
DesignUrlHandlers) ->
- MochiReq1 = couch_httpd_vhost:match_vhost(MochiReq),
+ MochiReq1 = couch_httpd_vhost:dispatch_host(MochiReq),
+
handle_request_int(MochiReq1, DefaultFun,
UrlHandlers, DbUrlHandlers, DesignUrlHandlers).
Modified: couchdb/trunk/src/couchdb/couch_httpd_vhost.erl
URL: http://svn.apache.org/viewvc/couchdb/trunk/src/couchdb/couch_httpd_vhost.erl?rev=1074816&r1=1074815&r2=1074816&view=diff
==============================================================================
--- couchdb/trunk/src/couchdb/couch_httpd_vhost.erl (original)
+++ couchdb/trunk/src/couchdb/couch_httpd_vhost.erl Sat Feb 26 10:24:36 2011
@@ -10,27 +10,24 @@
% License for the specific language governing permissions and limitations under
% the License.
-
-
-module(couch_httpd_vhost).
-behaviour(gen_server).
--export([start_link/0, init/1, handle_call/3, handle_info/2, handle_cast/2]).
--export([code_change/3, terminate/2]).
--export([match_vhost/1, urlsplit_netloc/2]).
--export([redirect_to_vhost/2]).
+-export([start_link/0, config_change/2, install/0, dispatch_host/1]).
+-export([urlsplit_netloc/2, redirect_to_vhost/2]).
+
+
+-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-include("couch_db.hrl").
-define(SEPARATOR, $\/).
-define(MATCH_ALL, {bind, '*'}).
--record(vhosts, {
- vhost_globals,
- vhosts = [],
- vhost_fun
-}).
-
+-record(vhosts_state, {
+ vhosts,
+ vhost_globals,
+ vhosts_fun}).
%% doc the vhost manager.
%% This gen_server keep state of vhosts added to the ini and try to
@@ -80,74 +77,22 @@
%% The function take 2 args : the mochiweb request object and the target
%%% path.
-start_link() ->
+start_link() ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
-%% @doc Try to find a rule matching current Host heade. some rule is
-%% found it rewrite the Mochiweb Request else it return current Request.
-match_vhost(MochiReq) ->
- {ok, MochiReq1} = gen_server:call(couch_httpd_vhost, {match_vhost,
- MochiReq}),
-
- MochiReq1.
-
-
-%% --------------------
-%% gen_server functions
-%% --------------------
-
-init(_) ->
- process_flag(trap_exit, true),
-
- % init state
- VHosts = make_vhosts(),
- VHostGlobals = re:split(
- couch_config:get("httpd", "vhost_global_handlers", ""),
- ", ?",
- [{return, list}]
- ),
-
- % Set vhost fun
- DefaultVHostFun = "{couch_httpd_vhost, redirect_to_vhost}",
- VHostFun = couch_httpd:make_arity_2_fun(
- couch_config:get("httpd", "redirect_vhost_handler", DefaultVHostFun)
- ),
-
-
- Self = self(),
- % register for changes in vhosts section
- ok = couch_config:register(
- fun("vhosts") ->
- ok = gen_server:call(Self, vhosts_changed, infinity)
- end
- ),
-
- % register for changes in vhost_global_handlers key
- ok = couch_config:register(
- fun("httpd", "vhost_global_handlers") ->
- ok = gen_server:call(Self, vhosts_global_changed, infinity)
- end
- ),
-
- ok = couch_config:register(
- fun("httpd", "redirect_vhost_handler") ->
- ok = gen_server:call(Self, fun_changed, infinity)
- end
- ),
-
- {ok, #vhosts{
- vhost_globals = VHostGlobals,
- vhosts = VHosts,
- vhost_fun = VHostFun}
- }.
+install() ->
+ gen_server:call(?MODULE, install).
+get_state() ->
+ gen_server:call(?MODULE, get_state).
-handle_call({match_vhost, MochiReq}, _From, State) ->
- #vhosts{
+%% @doc Try to find a rule matching current Host heade. some rule is
+%% found it rewrite the Mochiweb Request else it return current Request.
+dispatch_host(MochiReq) ->
+ #vhosts_state{
vhost_globals = VHostGlobals,
vhosts = VHosts,
- vhost_fun = Fun
- } = State,
+ vhosts_fun=Fun} = get_state(),
{"/" ++ VPath, Query, Fragment} = mochiweb_util:urlsplit_path(MochiReq:get(raw_path)),
VPathParts = string:tokens(VPath, "/"),
@@ -180,45 +125,9 @@ handle_call({match_vhost, MochiReq}, _Fr
Fun(MochiReq1, VhostTarget)
end
end,
- {reply, {ok, FinalMochiReq}, State};
+ FinalMochiReq.
-% update vhosts
-handle_call(vhosts_changed, _From, State) ->
- {reply, ok, State#vhosts{vhosts= make_vhosts()}};
-
-
-% update vhosts_globals
-handle_call(vhosts_global_changed, _From, State) ->
- VHostGlobals = re:split(
- couch_config:get("httpd", "vhost_global_handlers", ""),
- ", ?",
- [{return, list}]
- ),
- {reply, ok, State#vhosts{vhost_globals=VHostGlobals}};
-% change fun
-handle_call(fun_changed, _From, State) ->
- DefaultVHostFun = "{couch_httpd_vhosts, redirect_to_vhost}",
- VHostFun = couch_httpd:make_arity_2_fun(
- couch_config:get("httpd", "redirect_vhost_handler", DefaultVHostFun)
- ),
- {reply, ok, State#vhosts{vhost_fun=VHostFun}}.
-
-handle_cast(_Msg, State) ->
- {noreply, State}.
-
-handle_info(_Msg, State) ->
- {noreply, State}.
-
-terminate(_Reason, _State) ->
- ok.
-
-code_change(_OldVsn, State, _Extra) ->
- {ok, State}.
-
-
-
% default redirect vhost handler
-
redirect_to_vhost(MochiReq, VhostTarget) ->
Path = MochiReq:get(raw_path),
Target = VhostTarget ++ Path,
@@ -236,7 +145,6 @@ redirect_to_vhost(MochiReq, VhostTarget)
Headers),
% cleanup, It force mochiweb to reparse raw uri.
MochiReq1:cleanup(),
-
MochiReq1.
%% if so, then it will not be rewritten, but will run as a normal couchdb request.
@@ -400,3 +308,59 @@ urlsplit_netloc([C | Rest], Acc) ->
make_path(Parts) ->
"/" ++ string:join(Parts,[?SEPARATOR]).
+
+init(_) ->
+ ok = couch_config:register(fun ?MODULE:config_change/2),
+
+ %% load configuration
+ {VHostGlobals, VHosts, Fun} = load_conf(),
+ State = #vhosts_state{
+ vhost_globals=VHostGlobals,
+ vhosts=VHosts,
+ vhosts_fun=Fun},
+ {ok, State}.
+
+handle_call(install, _From, _State) ->
+ {VHostGlobals, VHosts, Fun} = load_conf(),
+ {reply, ok, #vhosts_state{
+ vhost_globals=VHostGlobals,
+ vhosts=VHosts,
+ vhosts_fun=Fun}};
+handle_call(get_state, _From, State) ->
+ {reply, State, State};
+handle_call(_Msg, _From, State) ->
+ {noreply, State}.
+
+handle_cast(_Msg, State) ->
+ {noreply, State}.
+
+handle_info(_Info, State) ->
+ {noreply, State}.
+
+terminate(_Reason, _State) ->
+ ok.
+
+code_change(_OldVsn, State, _Extra) ->
+ {ok, State}.
+
+config_change("httpd", "vhost_global_handlers") ->
+ ?MODULE:install();
+config_change("httpd", "redirect_vhost_handler") ->
+ ?MODULE:install();
+config_change("vhosts", _) ->
+ ?MODULE:install().
+
+load_conf() ->
+ %% get vhost globals
+ VHostGlobals = re:split(couch_config:get("httpd",
+ "vhost_global_handlers",""), "\\s*,\\s*",[{return, list}]),
+
+ %% build vhosts matching rules
+ VHosts = make_vhosts(),
+
+ %% build vhosts handler fun
+ DefaultVHostFun = "{couch_httpd_vhost, redirect_to_vhost}",
+ Fun = couch_httpd:make_arity_2_fun(couch_config:get("httpd",
+ "redirect_vhost_handler", DefaultVHostFun)),
+
+ {VHostGlobals, VHosts, Fun}.