From eee30441bcb10bc40f3a5d2978c4e8518fe970d4 Mon Sep 17 00:00:00 2001 From: ILYA Khlopotov Date: Thu, 29 Jan 2015 12:39:47 -0800 Subject: [PATCH 1/3] Update config_listener behaviuor COUCHDB-2561 --- src/couch_auth_cache.erl | 16 +++++++--------- src/couch_compaction_daemon.erl | 13 ++++++------- src/couch_external_manager.erl | 21 +++++++++------------ src/couch_external_server.erl | 15 +++++++-------- src/couch_httpd_vhost.erl | 13 ++++++------- src/couch_os_daemons.erl | 13 ++++++------- src/couch_proc_manager.erl | 23 +++++++++++------------ src/couch_server.erl | 11 +++++++++-- src/couch_sup.erl | 8 +++++++- src/couch_uuids.erl | 19 +++++++++++-------- 10 files changed, 79 insertions(+), 73 deletions(-) diff --git a/src/couch_auth_cache.erl b/src/couch_auth_cache.erl index e55ee171..e95d209c 100644 --- a/src/couch_auth_cache.erl +++ b/src/couch_auth_cache.erl @@ -12,7 +12,7 @@ -module(couch_auth_cache). -behaviour(gen_server). --vsn(1). +-vsn(2). -behaviour(config_listener). % public API @@ -23,7 +23,7 @@ -export([start_link/0, init/1, handle_call/3, handle_info/2, handle_cast/2]). -export([code_change/3, terminate/2]). --export([handle_config_change/5]). +-export([handle_config_change/5, handle_config_terminate/3]). -export([handle_db_event/3]). -include_lib("couch/include/couch_db.hrl"). @@ -231,16 +231,9 @@ handle_info(restart_event_listener, State) -> ?MODULE, handle_db_event, nil, [{dbname, AuthDbName}] ), {noreply, State#state{event_listener=NewListener}}; -handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) -> - erlang:send_after(5000, self(), restart_config_listener), - {noreply, State}; -handle_info(restart_config_listener, State) -> - ok = config:listen_for_changes(?MODULE, nil), - {noreply, State}; handle_info({'DOWN', Ref, _, _, _Reason}, #state{db_mon_ref = Ref} = State) -> {noreply, reinit_cache(State)}. - terminate(_Reason, #state{event_listener = Listener}) -> couch_event:stop_listener(Listener), exec_if_auth_db(fun(AuthDb) -> catch couch_db:close(AuthDb) end), @@ -261,6 +254,11 @@ handle_config_change("couch_httpd_auth", "authentication_db", _DbName, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, _, _) -> + spawn(fun() -> + timer:sleep(5000), + config:listen_for_changes(?MODULE, nil) + end). clear_cache(State) -> exec_if_auth_db(fun(AuthDb) -> catch couch_db:close(AuthDb) end), diff --git a/src/couch_compaction_daemon.erl b/src/couch_compaction_daemon.erl index 49c26f45..543db9f2 100644 --- a/src/couch_compaction_daemon.erl +++ b/src/couch_compaction_daemon.erl @@ -22,7 +22,7 @@ -export([code_change/3, terminate/2]). % config_listener api --export([handle_config_change/5]). +-export([handle_config_change/5, handle_config_terminate/3]). -include_lib("couch/include/couch_db.hrl"). -include_lib("kernel/include/file.hrl"). @@ -86,12 +86,6 @@ handle_call(Msg, _From, State) -> {stop, {unexpected_call, Msg}, State}. -handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) -> - erlang:send_after(5000, self(), restart_config_listener), - {noreply, State}; -handle_info(restart_config_listener, State) -> - ok = config:listen_for_changes(?MODULE, nil), - {noreply, State}; handle_info({'EXIT', Pid, Reason}, #state{loop_pid = Pid} = State) -> {stop, {compaction_loop_died, Reason}, State}. @@ -109,6 +103,11 @@ handle_config_change("compactions", DbName, Value, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, _, _) -> + spawn(fun() -> + timer:sleep(5000), + config:listen_for_changes(?MODULE, nil) + end). compact_loop(Parent) -> {ok, _} = couch_server:all_databases( diff --git a/src/couch_external_manager.erl b/src/couch_external_manager.erl index 51c6125f..a2eedbbc 100644 --- a/src/couch_external_manager.erl +++ b/src/couch_external_manager.erl @@ -12,14 +12,14 @@ -module(couch_external_manager). -behaviour(gen_server). --vsn(1). +-vsn(2). -behaviour(config_listener). -export([start_link/0, execute/2]). -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2]). % config_listener api --export([handle_config_change/5]). +-export([handle_config_change/5, handle_config_terminate/3]). -include_lib("couch/include/couch_db.hrl"). @@ -41,6 +41,12 @@ handle_config_change("external", UrlName, _, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, _, _) -> + spawn(fun() -> + timer:sleep(5000), + config:listen_for_changes(?MODULE, nil) + end). + % gen_server API init([]) -> @@ -101,16 +107,7 @@ handle_info({'EXIT', Pid, Reason}, Handlers) -> % Remove Pid from the handlers table so we don't try closing % it a second time in terminate/2. ets:match_delete(Handlers, {'_', Pid}), - {stop, normal, Handlers}; - -handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) -> - erlang:send_after(5000, self(), restart_config_listener), - {noreply, State}; - -handle_info(restart_config_listener, State) -> - ok = config:listen_for_changes(?MODULE, nil), - {noreply, State}. + {stop, normal, Handlers}. code_change(_OldVsn, State, _Extra) -> {ok, State}. - diff --git a/src/couch_external_server.erl b/src/couch_external_server.erl index d5560b05..339e36f6 100644 --- a/src/couch_external_server.erl +++ b/src/couch_external_server.erl @@ -12,14 +12,14 @@ -module(couch_external_server). -behaviour(gen_server). --vsn(1). +-vsn(2). -behaviour(config_listener). -export([start_link/2, stop/1, execute/2]). -export([init/1, terminate/2, handle_call/3, handle_cast/2, handle_info/2, code_change/3]). % config_listener api --export([handle_config_change/5]). +-export([handle_config_change/5, handle_config_terminate/3]). -include_lib("couch/include/couch_db.hrl"). @@ -54,12 +54,6 @@ terminate(_Reason, {_Name, _Command, Pid}) -> handle_call({execute, JsonReq}, _From, {Name, Command, Pid}) -> {reply, couch_os_process:prompt(Pid, JsonReq), {Name, Command, Pid}}. -handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) -> - erlang:send_after(5000, self(), restart_config_listener), - {noreply, State}; -handle_info(restart_config_listener, State) -> - ok = config:listen_for_changes(?MODULE, State), - {noreply, State}; handle_info({'EXIT', _Pid, normal}, State) -> {noreply, State}; handle_info({'EXIT', Pid, Reason}, {Name, Command, Pid}) -> @@ -84,3 +78,8 @@ handle_config_change("couchdb", "os_process_timeout", NewTimeout, _, Pid) -> handle_config_change(_, _, _, _, Pid) -> {ok, Pid}. +handle_config_terminate(_, _, _) -> + spawn(fun() -> + timer:sleep(5000), + config:listen_for_changes(?MODULE, nil) + end). diff --git a/src/couch_httpd_vhost.erl b/src/couch_httpd_vhost.erl index 0f012940..67cfd036 100644 --- a/src/couch_httpd_vhost.erl +++ b/src/couch_httpd_vhost.erl @@ -21,7 +21,7 @@ -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). % config_listener api --export([handle_config_change/5]). +-export([handle_config_change/5, handle_config_terminate/3]). -include_lib("couch/include/couch_db.hrl"). @@ -355,12 +355,6 @@ handle_call(_Msg, _From, State) -> handle_cast(_Msg, State) -> {noreply, State}. -handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) -> - erlang:send_after(5000, self(), restart_config_listener), - {noreply, State}; -handle_info(restart_config_listener, State) -> - ok = config:listen_for_changes(?MODULE, nil), - {noreply, State}; handle_info(_Info, State) -> {noreply, State}. @@ -380,6 +374,11 @@ handle_config_change("vhosts", _, _, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, _, _) -> + spawn(fun() -> + timer:sleep(5000), + config:listen_for_changes(?MODULE, nil) + end). load_conf() -> %% get vhost globals diff --git a/src/couch_os_daemons.erl b/src/couch_os_daemons.erl index 606d147f..60dbcc3a 100644 --- a/src/couch_os_daemons.erl +++ b/src/couch_os_daemons.erl @@ -19,7 +19,7 @@ -export([handle_call/3, handle_cast/2, handle_info/2]). % config_listener api --export([handle_config_change/5]). +-export([handle_config_change/5, handle_config_terminate/3]). -include_lib("couch/include/couch_db.hrl"). @@ -82,12 +82,6 @@ handle_cast(Msg, Table) -> couch_log:error("Unknown cast message to ~p: ~p", [?MODULE, Msg]), {stop, error, Table}. -handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) -> - erlang:send_after(5000, self(), restart_config_listener), - {noreply, State}; -handle_info(restart_config_listener, State) -> - ok = config:listen_for_changes(?MODULE, nil), - {noreply, State}; handle_info({'EXIT', Port, Reason}, Table) -> case ets:lookup(Table, Port) of [] -> @@ -201,6 +195,11 @@ handle_config_change(Section, Key, _, _, _) -> gen_server:cast(?MODULE, {config_change, Section, Key}), {ok, nil}. +handle_config_terminate(_, _, _) -> + spawn(fun() -> + timer:sleep(5000), + config:listen_for_changes(?MODULE, nil) + end). % Internal API diff --git a/src/couch_proc_manager.erl b/src/couch_proc_manager.erl index 5bb154ec..675b649e 100644 --- a/src/couch_proc_manager.erl +++ b/src/couch_proc_manager.erl @@ -13,7 +13,7 @@ -module(couch_proc_manager). -behaviour(gen_server). -behaviour(config_listener). --vsn(1). +-vsn(2). -export([ start_link/0, @@ -34,7 +34,8 @@ ]). -export([ - handle_config_change/5 + handle_config_change/5, + handle_config_terminate/3 ]). -include_lib("couch/include/couch_db.hrl"). @@ -262,16 +263,6 @@ handle_info({'DOWN', Ref, _, _, _Reason}, State0) -> {noreply, State0} end; -handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) -> - erlang:send_after(5000, self(), restart_config_listener), - {noreply, State}; - -handle_info(restart_config_listener, State) -> - ok = config:listen_for_changes(?MODULE, undefined), - % Reload our config in case it changed in the last - % five seconds. - handle_cast(reload, State); - handle_info(_Msg, State) -> {noreply, State}. @@ -279,6 +270,14 @@ handle_info(_Msg, State) -> code_change(_OldVsn, #state{}=State, _Extra) -> {ok, State}. +handle_config_terminate(_, _, _) -> + spawn(fun() -> + timer:sleep(5000), + config:listen_for_changes(?MODULE, undefined), + % Reload our config in case it changed in the last + % five seconds. + gen_server:cast(?MODULE, reload_config) + end). handle_config_change("query_server_config", _, _, _, _) -> gen_server:cast(?MODULE, reload_config), diff --git a/src/couch_server.erl b/src/couch_server.erl index 8f9696b8..598df6a0 100644 --- a/src/couch_server.erl +++ b/src/couch_server.erl @@ -13,7 +13,7 @@ -module(couch_server). -behaviour(gen_server). -behaviour(config_listener). --vsn(1). +-vsn(2). -export([open/2,create/2,delete/2,get_version/0,get_version/1,get_uuid/0]). -export([all_databases/0, all_databases/2]). @@ -23,7 +23,7 @@ -export([close_lru/0]). % config_listener api --export([handle_config_change/5]). +-export([handle_config_change/5, handle_config_terminate/3]). -include_lib("couch/include/couch_db.hrl"). @@ -249,6 +249,13 @@ handle_config_change("httpd_db_handlers", _, _, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, _, _) -> + spawn(fun() -> + timer:sleep(5000), + config:listen_for_changes(?MODULE, nil) + end). + + all_databases() -> {ok, DbList} = all_databases( diff --git a/src/couch_sup.erl b/src/couch_sup.erl index 467a1f5c..c941a601 100644 --- a/src/couch_sup.erl +++ b/src/couch_sup.erl @@ -18,7 +18,8 @@ -export([ start_link/0, init/1, - handle_config_change/5 + handle_config_change/5, + handle_config_terminate/3 ]). @@ -75,6 +76,11 @@ handle_config_change("couchdb", "util_driver_dir", _, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, _, _) -> + spawn(fun() -> + timer:sleep(5000), + config:listen_for_changes(?MODULE, undefined) + end). notify_starting() -> io:format("Apache CouchDB ~s is starting.~n", [ diff --git a/src/couch_uuids.erl b/src/couch_uuids.erl index 2cee58be..36fa0952 100644 --- a/src/couch_uuids.erl +++ b/src/couch_uuids.erl @@ -13,7 +13,7 @@ -include_lib("couch/include/couch_db.hrl"). -behaviour(gen_server). --vsn(1). +-vsn(2). -behaviour(config_listener). -export([start/0, stop/0]). @@ -23,7 +23,7 @@ -export([handle_call/3, handle_cast/2, handle_info/2]). % config_listener api --export([handle_config_change/5]). +-export([handle_config_change/5, handle_config_terminate/3]). start() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). @@ -77,12 +77,6 @@ handle_cast(stop, State) -> handle_cast(_Msg, State) -> {noreply, State}. -handle_info({gen_event_EXIT, {config_listener, ?MODULE}, _Reason}, State) -> - erlang:send_after(5000, self(), restart_config_listener), - {noreply, State}; -handle_info(restart_config_listener, State) -> - ok = config:listen_for_changes(?MODULE, nil), - {noreply, State}; handle_info(_Info, State) -> {noreply, State}. @@ -94,6 +88,15 @@ handle_config_change("uuids", _, _, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(Pid, _, _) -> + spawn(fun() -> + timer:sleep(5000), + config:listen_for_changes(?MODULE, undefined), + % Reload our config in case it changed in the last + % five seconds. + gen_server:cast(?MODULE, change) + end). + new_prefix() -> couch_util:to_hex((crypto:rand_bytes(13))). From f21e78ec69ceb376d52d4edfb1813877bcce1850 Mon Sep 17 00:00:00 2001 From: ILYA Khlopotov Date: Thu, 29 Jan 2015 12:41:26 -0800 Subject: [PATCH 2/3] config:get/3 is more strict now The config:get/3 supports only following types for default argument - atom `undefined` - string (list) - boolean - float - integer COUCDB-2561 --- src/couch_drv.erl | 4 ++-- src/couch_external_manager.erl | 4 ++-- src/couch_httpd.erl | 37 ++++++++++++++++-------------- src/couch_httpd_auth.erl | 12 +++++----- src/couch_httpd_misc_handlers.erl | 12 +++++----- src/couch_os_daemons.erl | 4 ++-- src/couch_server.erl | 4 ++-- src/couch_sup.erl | 4 ++-- test/couchdb_attachments_tests.erl | 11 ++++++--- 9 files changed, 50 insertions(+), 42 deletions(-) diff --git a/src/couch_drv.erl b/src/couch_drv.erl index 0379264d..f2ff2ac2 100644 --- a/src/couch_drv.erl +++ b/src/couch_drv.erl @@ -55,8 +55,8 @@ code_change(_OldVsn, State, _Extra) -> % private API util_driver_dir() -> - case config:get("couchdb", "util_driver_dir", null) of - null -> + case config:get("couchdb", "util_driver_dir", undefined) of + undefined -> couch_util:priv_dir(); LibDir0 -> LibDir0 diff --git a/src/couch_external_manager.erl b/src/couch_external_manager.erl index a2eedbbc..32bf3bda 100644 --- a/src/couch_external_manager.erl +++ b/src/couch_external_manager.erl @@ -65,8 +65,8 @@ terminate(_Reason, Handlers) -> handle_call({get, UrlName}, _From, Handlers) -> case ets:lookup(Handlers, UrlName) of [] -> - case config:get("external", UrlName, nil) of - nil -> + case config:get("external", UrlName, undefined) of + undefined -> Msg = lists:flatten( io_lib:format("No server configured for ~p.", [UrlName])), {reply, {error, {unknown_external_server, ?l2b(Msg)}}, Handlers}; diff --git a/src/couch_httpd.erl b/src/couch_httpd.erl index d298b947..8e5555cf 100644 --- a/src/couch_httpd.erl +++ b/src/couch_httpd.erl @@ -38,20 +38,20 @@ start_link(http) -> start_link(?MODULE, [{port, Port}]); start_link(https) -> Port = config:get("ssl", "port", "6984"), - {ok, Ciphers} = couch_util:parse_term(config:get("ssl", "ciphers", "nil")), - {ok, Versions} = couch_util:parse_term(config:get("ssl", "tls_versions", "nil")), - {ok, SecureRenegotiate} = couch_util:parse_term(config:get("ssl", "secure_renegotiate", "nil")), + {ok, Ciphers} = couch_util:parse_term(config:get("ssl", "ciphers", undefined)), + {ok, Versions} = couch_util:parse_term(config:get("ssl", "tls_versions", undefined)), + {ok, SecureRenegotiate} = couch_util:parse_term(config:get("ssl", "secure_renegotiate", undefined)), ServerOpts0 = - [{cacertfile, config:get("ssl", "cacert_file", nil)}, - {keyfile, config:get("ssl", "key_file", nil)}, - {certfile, config:get("ssl", "cert_file", nil)}, - {password, config:get("ssl", "password", nil)}, + [{cacertfile, config:get("ssl", "cacert_file", undefined)}, + {keyfile, config:get("ssl", "key_file", undefined)}, + {certfile, config:get("ssl", "cert_file", undefined)}, + {password, config:get("ssl", "password", undefined)}, {secure_renegotiate, SecureRenegotiate}, {versions, Versions}, {ciphers, Ciphers}], - case (couch_util:get_value(keyfile, ServerOpts0) == nil orelse - couch_util:get_value(certfile, ServerOpts0) == nil) of + case (couch_util:get_value(keyfile, ServerOpts0) == undefined orelse + couch_util:get_value(certfile, ServerOpts0) == undefined) of true -> couch_log:error("SSL enabled but PEM certificates are missing", []), throw({error, missing_certs}); @@ -59,7 +59,7 @@ start_link(https) -> ok end, - ServerOpts = [Opt || {_, V}=Opt <- ServerOpts0, V /= nil], + ServerOpts = [Opt || {_, V}=Opt <- ServerOpts0, V /= undefined], ClientOpts = case config:get("ssl", "verify_ssl_certificates", "false") of "false" -> @@ -73,8 +73,8 @@ start_link(https) -> "ssl_certificate_max_depth", "1"))}, {fail_if_no_peer_cert, FailIfNoPeerCert}, {verify, verify_peer}] ++ - case config:get("ssl", "verify_fun", nil) of - nil -> []; + case config:get("ssl", "verify_fun", undefined) of + undefined -> []; SpecStr -> [{verify_fun, make_arity_3_fun(SpecStr)}] end @@ -87,7 +87,7 @@ start_link(https) -> {ssl_opts, SslOpts}], start_link(https, Options). start_link(Name, Options) -> - BindAddress = config:get("httpd", "bind_address", any), + BindAddress = with_default(config:get("httpd", "bind_address"), any), validate_bind_address(BindAddress), DefaultSpec = "{couch_httpd_db, handle_request}", DefaultFun = make_arity_1_fun( @@ -854,14 +854,14 @@ error_headers(#httpd{mochi_req=MochiReq}=Req, Code, ErrorStr, ReasonStr) -> % this is where the basic auth popup is triggered case MochiReq:get_header_value("X-CouchDB-WWW-Authenticate") of undefined -> - case config:get("httpd", "WWW-Authenticate", nil) of - nil -> + case config:get("httpd", "WWW-Authenticate", undefined) of + undefined -> % If the client is a browser and the basic auth popup isn't turned on % redirect to the session page. case ErrorStr of <<"unauthorized">> -> - case config:get("couch_httpd_auth", "authentication_redirect", nil) of - nil -> {Code, []}; + case config:get("couch_httpd_auth", "authentication_redirect", undefined) of + undefined -> {Code, []}; AuthRedirect -> case config:get("couch_httpd_auth", "require_valid_user", "false") of "true" -> @@ -1091,3 +1091,6 @@ validate_bind_address(Address) -> {ok, _} -> ok; _ -> throw({error, invalid_bind_address}) end. + +with_default(undefined, Default) -> Default; +with_default(Value, _) -> Value. diff --git a/src/couch_httpd_auth.erl b/src/couch_httpd_auth.erl index 74e8ee91..9dfa539a 100644 --- a/src/couch_httpd_auth.erl +++ b/src/couch_httpd_auth.erl @@ -158,8 +158,8 @@ proxy_auth_user(Req) -> end, case config:get("couch_httpd_auth", "proxy_use_secret", "false") of "true" -> - case config:get("couch_httpd_auth", "secret", nil) of - nil -> + case config:get("couch_httpd_auth", "secret", undefined) of + undefined -> Req#httpd{user_ctx=#user_ctx{name=?l2b(UserName), roles=Roles}}; Secret -> ExpectedToken = couch_util:to_hex(crypto:sha_mac(Secret, UserName)), @@ -195,8 +195,8 @@ cookie_authentication_handler(#httpd{mochi_req=MochiReq}=Req, AuthModule) -> end, % Verify expiry and hash CurrentTime = make_cookie_time(), - case config:get("couch_httpd_auth", "secret", nil) of - nil -> + case config:get("couch_httpd_auth", "secret", undefined) of + undefined -> couch_log:debug("cookie auth secret is not set",[]), Req; SecretStr -> @@ -260,8 +260,8 @@ cookie_auth_cookie(Req, User, Secret, TimeStamp) -> [{path, "/"}] ++ cookie_scheme(Req) ++ max_age()). ensure_cookie_auth_secret() -> - case config:get("couch_httpd_auth", "secret", nil) of - nil -> + case config:get("couch_httpd_auth", "secret", undefined) of + undefined -> NewSecret = ?b2l(couch_uuids:random()), config:set("couch_httpd_auth", "secret", NewSecret), NewSecret; diff --git a/src/couch_httpd_misc_handlers.erl b/src/couch_httpd_misc_handlers.erl index e90140fc..84472457 100644 --- a/src/couch_httpd_misc_handlers.erl +++ b/src/couch_httpd_misc_handlers.erl @@ -177,8 +177,8 @@ handle_config_req(#httpd{method='GET', path_parts=[_,Section]}=Req) -> % GET /_config/Section/Key handle_config_req(#httpd{method='GET', path_parts=[_, Section, Key]}=Req) -> ok = couch_httpd:verify_is_server_admin(Req), - case config:get(Section, Key, null) of - null -> + case config:get(Section, Key, undefined) of + undefined -> throw({not_found, unknown_config_value}); Value -> send_json(Req, 200, list_to_binary(Value)) @@ -193,8 +193,8 @@ handle_config_req(#httpd{method=Method, path_parts=[_, Section, Key]}=Req) when (Method == 'PUT') or (Method == 'DELETE') -> ok = couch_httpd:verify_is_server_admin(Req), Persist = couch_httpd:header_value(Req, "X-Couch-Persist") /= "false", - case config:get(<<"httpd">>, <<"config_whitelist">>, null) of - null -> + case config:get("httpd", "config_whitelist", undefined) of + undefined -> % No whitelist; allow all changes. handle_approved_config_req(Req, Persist); WhitelistValue -> @@ -295,8 +295,8 @@ handle_approved_config_req(#httpd{method='PUT'}=Req, _Persist, UseRawValue) -> % DELETE /_config/Section/Key handle_approved_config_req(#httpd{method='DELETE',path_parts=[_,Section,Key]}=Req, Persist, _UseRawValue) -> - case config:get(Section, Key, null) of - null -> + case config:get(Section, Key, undefined) of + undefined -> throw({not_found, unknown_config_value}); OldValue -> config:delete(Section, Key, Persist), diff --git a/src/couch_os_daemons.erl b/src/couch_os_daemons.erl index 60dbcc3a..cbacdbd9 100644 --- a/src/couch_os_daemons.erl +++ b/src/couch_os_daemons.erl @@ -241,8 +241,8 @@ handle_port_message(#daemon{port=Port}=Daemon, [<<"get">>, Section]) -> port_command(Port, <>), {ok, Daemon}; handle_port_message(#daemon{port=Port}=Daemon, [<<"get">>, Section, Key]) -> - Value = case config:get(Section, Key, null) of - null -> null; + Value = case config:get(Section, Key, undefined) of + undefined -> null; String -> ?l2b(String) end, Json = iolist_to_binary(?JSON_ENCODE(Value)), diff --git a/src/couch_server.erl b/src/couch_server.erl index 598df6a0..5a4db2ec 100644 --- a/src/couch_server.erl +++ b/src/couch_server.erl @@ -59,8 +59,8 @@ get_version(short) -> get_uuid() -> - case config:get("couchdb", "uuid", nil) of - nil -> + case config:get("couchdb", "uuid", undefined) of + undefined -> UUID = couch_uuids:random(), config:set("couchdb", "uuid", ?b2l(UUID)), UUID; diff --git a/src/couch_sup.erl b/src/couch_sup.erl index c941a601..2926a0f6 100644 --- a/src/couch_sup.erl +++ b/src/couch_sup.erl @@ -112,8 +112,8 @@ write_pidfile() -> write_uris() -> - case config:get("couchdb", "uri_file", null) of - null -> + case config:get("couchdb", "uri_file", undefined) of + undefined -> ok; UriFile -> Lines = [io_lib:format("~s~n", [Uri]) || Uri <- get_uris()], diff --git a/test/couchdb_attachments_tests.erl b/test/couchdb_attachments_tests.erl index 78f9f493..71d685ac 100644 --- a/test/couchdb_attachments_tests.erl +++ b/test/couchdb_attachments_tests.erl @@ -40,7 +40,7 @@ setup() -> DbName = ?tempdb(), {ok, Db} = couch_db:create(DbName, []), ok = couch_db:close(Db), - Addr = config:get("httpd", "bind_address", any), + Addr = config:get("httpd", "bind_address", "127.0.0.1"), Port = mochiweb_socket_server:get(couch_httpd, port), Host = Addr ++ ":" ++ ?i2l(Port), {Host, ?b2l(DbName)}. @@ -542,11 +542,16 @@ chunked_body([Chunk | Rest], Acc) -> get_socket() -> Options = [binary, {packet, 0}, {active, false}], - Addr = config:get("httpd", "bind_address", any), Port = mochiweb_socket_server:get(couch_httpd, port), - {ok, Sock} = gen_tcp:connect(Addr, Port, Options), + {ok, Sock} = gen_tcp:connect(bind_address(), Port, Options), Sock. +bind_address() -> + case config:get("httpd", "bind_address") of + undefined -> any; + Address -> Address + end. + request(Method, Url, Headers, Body) -> RequestHead = [Method, " ", Url, " HTTP/1.1"], RequestHeaders = [[string:join([Key, Value], ": "), "\r\n"] From 817e4d749e5e4553a56d01c09aa5608a7869fb82 Mon Sep 17 00:00:00 2001 From: ILYA Khlopotov Date: Fri, 30 Jan 2015 11:12:51 -0800 Subject: [PATCH 3/3] Don't restart event handler when terminating COUCHDB-2561 --- src/couch_auth_cache.erl | 1 + src/couch_compaction_daemon.erl | 1 + src/couch_external_manager.erl | 1 + src/couch_external_server.erl | 1 + src/couch_httpd_vhost.erl | 1 + src/couch_os_daemons.erl | 1 + src/couch_proc_manager.erl | 1 + src/couch_server.erl | 1 + src/couch_sup.erl | 1 + src/couch_uuids.erl | 1 + 10 files changed, 10 insertions(+) diff --git a/src/couch_auth_cache.erl b/src/couch_auth_cache.erl index e95d209c..0b154899 100644 --- a/src/couch_auth_cache.erl +++ b/src/couch_auth_cache.erl @@ -254,6 +254,7 @@ handle_config_change("couch_httpd_auth", "authentication_db", _DbName, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, stop, _) -> ok; handle_config_terminate(_, _, _) -> spawn(fun() -> timer:sleep(5000), diff --git a/src/couch_compaction_daemon.erl b/src/couch_compaction_daemon.erl index 543db9f2..2294fbc4 100644 --- a/src/couch_compaction_daemon.erl +++ b/src/couch_compaction_daemon.erl @@ -103,6 +103,7 @@ handle_config_change("compactions", DbName, Value, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, stop, _) -> ok; handle_config_terminate(_, _, _) -> spawn(fun() -> timer:sleep(5000), diff --git a/src/couch_external_manager.erl b/src/couch_external_manager.erl index 32bf3bda..1aeb39ab 100644 --- a/src/couch_external_manager.erl +++ b/src/couch_external_manager.erl @@ -41,6 +41,7 @@ handle_config_change("external", UrlName, _, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, stop, _) -> ok; handle_config_terminate(_, _, _) -> spawn(fun() -> timer:sleep(5000), diff --git a/src/couch_external_server.erl b/src/couch_external_server.erl index 339e36f6..ff2e1859 100644 --- a/src/couch_external_server.erl +++ b/src/couch_external_server.erl @@ -78,6 +78,7 @@ handle_config_change("couchdb", "os_process_timeout", NewTimeout, _, Pid) -> handle_config_change(_, _, _, _, Pid) -> {ok, Pid}. +handle_config_terminate(_, stop, _) -> ok; handle_config_terminate(_, _, _) -> spawn(fun() -> timer:sleep(5000), diff --git a/src/couch_httpd_vhost.erl b/src/couch_httpd_vhost.erl index 67cfd036..05fc874b 100644 --- a/src/couch_httpd_vhost.erl +++ b/src/couch_httpd_vhost.erl @@ -374,6 +374,7 @@ handle_config_change("vhosts", _, _, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, stop, _) -> ok; handle_config_terminate(_, _, _) -> spawn(fun() -> timer:sleep(5000), diff --git a/src/couch_os_daemons.erl b/src/couch_os_daemons.erl index cbacdbd9..409ba020 100644 --- a/src/couch_os_daemons.erl +++ b/src/couch_os_daemons.erl @@ -195,6 +195,7 @@ handle_config_change(Section, Key, _, _, _) -> gen_server:cast(?MODULE, {config_change, Section, Key}), {ok, nil}. +handle_config_terminate(_, stop, _) -> ok; handle_config_terminate(_, _, _) -> spawn(fun() -> timer:sleep(5000), diff --git a/src/couch_proc_manager.erl b/src/couch_proc_manager.erl index 675b649e..f0fc6fa2 100644 --- a/src/couch_proc_manager.erl +++ b/src/couch_proc_manager.erl @@ -270,6 +270,7 @@ handle_info(_Msg, State) -> code_change(_OldVsn, #state{}=State, _Extra) -> {ok, State}. +handle_config_terminate(_, stop, _) -> ok; handle_config_terminate(_, _, _) -> spawn(fun() -> timer:sleep(5000), diff --git a/src/couch_server.erl b/src/couch_server.erl index 5a4db2ec..3057f181 100644 --- a/src/couch_server.erl +++ b/src/couch_server.erl @@ -249,6 +249,7 @@ handle_config_change("httpd_db_handlers", _, _, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, stop, _) -> ok; handle_config_terminate(_, _, _) -> spawn(fun() -> timer:sleep(5000), diff --git a/src/couch_sup.erl b/src/couch_sup.erl index 2926a0f6..2498a80e 100644 --- a/src/couch_sup.erl +++ b/src/couch_sup.erl @@ -76,6 +76,7 @@ handle_config_change("couchdb", "util_driver_dir", _, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, stop, _) -> ok; handle_config_terminate(_, _, _) -> spawn(fun() -> timer:sleep(5000), diff --git a/src/couch_uuids.erl b/src/couch_uuids.erl index 36fa0952..fd625be9 100644 --- a/src/couch_uuids.erl +++ b/src/couch_uuids.erl @@ -88,6 +88,7 @@ handle_config_change("uuids", _, _, _, _) -> handle_config_change(_, _, _, _, _) -> {ok, nil}. +handle_config_terminate(_, stop, _) -> ok; handle_config_terminate(Pid, _, _) -> spawn(fun() -> timer:sleep(5000),