diff options
author | Jiahui Li <54631519+jiahuili430@users.noreply.github.com> | 2021-05-17 07:41:45 -0500 |
---|---|---|
committer | Nick Vatamaniuc <nickva@users.noreply.github.com> | 2021-05-24 18:23:06 -0400 |
commit | f1dd5fe195715f72a1dc78712445b5af889d30a9 (patch) | |
tree | a66120edc6bbf73adb5e5ba066b349dc545ad521 | |
parent | e632b45cc556281887361f3e25196ddf5e800363 (diff) | |
download | couchdb-f1dd5fe195715f72a1dc78712445b5af889d30a9.tar.gz |
Moved some config options from httpd to chttpd
23 files changed, 267 insertions, 98 deletions
diff --git a/rel/overlay/etc/default.ini b/rel/overlay/etc/default.ini index a9698e250..614c14e55 100644 --- a/rel/overlay/etc/default.ini +++ b/rel/overlay/etc/default.ini @@ -147,6 +147,26 @@ max_db_number_for_dbs_info_req = 100 ; prevent non-admins from accessing /_all_dbs ; admin_only_all_dbs = true +; These options are moved from [httpd] +;secure_rewrites = true +;allow_jsonp = false + +;enable_cors = false +;enable_xframe_options = false + +; CouchDB can optionally enforce a maximum uri length; +;max_uri_length = 8000 + +;changes_timeout = 60000 +;config_whitelist = +;rewrite_limit = 100 +;x_forwarded_host = X-Forwarded-Host +;x_forwarded_proto = X-Forwarded-Proto +;x_forwarded_ssl = X-Forwarded-Ssl + +; Maximum allowed http request size. Applies to both clustered and local port. +;max_http_request_size = 4294967296 ; 4GB + ;[jwt_auth] ; List of claims to validate ; can be the name of a claim like "exp" or a tuple if the claim requires @@ -190,26 +210,17 @@ database_prefix = userdb- port = {{backend_port}} bind_address = 127.0.0.1 authentication_handlers = {couch_httpd_auth, cookie_authentication_handler}, {couch_httpd_auth, default_authentication_handler} -secure_rewrites = true -allow_jsonp = false + ; Options for the MochiWeb HTTP server. ;server_options = [{backlog, 128}, {acceptor_pool_size, 16}] ; For more socket options, consult Erlang's module 'inet' man page. ;socket_options = [{recbuf, undefined}, {sndbuf, 262144}, {nodelay, true}] socket_options = [{sndbuf, 262144}] -enable_cors = false -enable_xframe_options = false -; CouchDB can optionally enforce a maximum uri length; -; max_uri_length = 8000 -; changes_timeout = 60000 -; config_whitelist = -; max_uri_length = -; rewrite_limit = 100 -; x_forwarded_host = X-Forwarded-Host -; x_forwarded_proto = X-Forwarded-Proto -; x_forwarded_ssl = X-Forwarded-Ssl -; Maximum allowed http request size. Applies to both clustered and local port. -max_http_request_size = 4294967296 ; 4GB + +; These settings were moved to [chttpd] +; secure_rewrites, allow_jsonp, enable_cors, enable_xframe_options, +; max_uri_length, changes_timeout, config_whitelist, rewrite_limit, +; x_forwarded_host, x_forwarded_proto, x_forwarded_ssl, max_http_request_size ; [httpd_design_handlers] ; _view = diff --git a/src/chttpd/src/chttpd.erl b/src/chttpd/src/chttpd.erl index 0a0029d4e..a114ae8c5 100644 --- a/src/chttpd/src/chttpd.erl +++ b/src/chttpd/src/chttpd.erl @@ -416,7 +416,8 @@ possibly_hack(Req) -> Req. check_request_uri_length(Uri) -> - check_request_uri_length(Uri, config:get("httpd", "max_uri_length")). + check_request_uri_length(Uri, + chttpd_util:get_chttpd_config("max_uri_length")). check_request_uri_length(_Uri, undefined) -> ok; @@ -586,7 +587,8 @@ path(#httpd{mochi_req=MochiReq}) -> MochiReq:get(path). absolute_uri(#httpd{mochi_req=MochiReq, absolute_uri = undefined}, Path) -> - XHost = config:get("httpd", "x_forwarded_host", "X-Forwarded-Host"), + XHost = chttpd_util:get_chttpd_config( + "x_forwarded_host", "X-Forwarded-Host"), Host = case MochiReq:get_header_value(XHost) of undefined -> case MochiReq:get_header_value("Host") of @@ -601,12 +603,12 @@ absolute_uri(#httpd{mochi_req=MochiReq, absolute_uri = undefined}, Path) -> end; Value -> Value end, - XSsl = config:get("httpd", "x_forwarded_ssl", "X-Forwarded-Ssl"), + XSsl = chttpd_util:get_chttpd_config("x_forwarded_ssl", "X-Forwarded-Ssl"), Scheme = case MochiReq:get_header_value(XSsl) of "on" -> "https"; _ -> - XProto = config:get("httpd", "x_forwarded_proto", - "X-Forwarded-Proto"), + XProto = chttpd_util:get_chttpd_config( + "x_forwarded_proto", "X-Forwarded-Proto"), case MochiReq:get_header_value(XProto) of % Restrict to "https" and "http" schemes only "https" -> "https"; @@ -648,8 +650,8 @@ body(#httpd{mochi_req=MochiReq, req_body=ReqBody}) -> case ReqBody of undefined -> % Maximum size of document PUT request body (4GB) - MaxSize = config:get_integer("httpd", "max_http_request_size", - 4294967296), + MaxSize = chttpd_util:get_chttpd_config_integer( + "max_http_request_size", 4294967296), Begin = os:timestamp(), try MochiReq:recv_body(MaxSize) @@ -1028,7 +1030,7 @@ error_headers(#httpd{mochi_req=MochiReq}=Req, 401=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", undefined) of + case chttpd_util:get_chttpd_config("WWW-Authenticate") of undefined -> % If the client is a browser and the basic auth popup isn't turned on % redirect to the session page. @@ -1226,7 +1228,7 @@ stack_hash(Stack) -> %% this value to 0 to restore the older behavior of sending each row in a %% dedicated chunk. chunked_response_buffer_size() -> - config:get_integer("httpd", "chunked_response_buffer", 1490). + chttpd_util:get_chttpd_config_integer("chunked_response_buffer", 1490). basic_headers(Req, Headers0) -> Headers = Headers0 diff --git a/src/chttpd/src/chttpd_cors.erl b/src/chttpd/src/chttpd_cors.erl index a8dd348f8..62b19a0d2 100644 --- a/src/chttpd/src/chttpd_cors.erl +++ b/src/chttpd/src/chttpd_cors.erl @@ -280,7 +280,7 @@ allow_credentials(Config, Origin) -> get_cors_config(#httpd{cors_config = undefined, mochi_req = MochiReq}) -> Host = couch_httpd_vhost:host(MochiReq), - EnableCors = config:get("httpd", "enable_cors", "false") =:= "true", + EnableCors = chttpd_util:get_chttpd_config_boolean("enable_cors", false), AllowCredentials = cors_config(Host, "credentials", "false") =:= "true", AllowHeaders = case cors_config(Host, "headers", undefined) of diff --git a/src/chttpd/src/chttpd_external.erl b/src/chttpd/src/chttpd_external.erl index 283b1aff7..b44109e5a 100644 --- a/src/chttpd/src/chttpd_external.erl +++ b/src/chttpd/src/chttpd_external.erl @@ -59,7 +59,8 @@ json_req_obj_field(<<"headers">>, #httpd{mochi_req=Req}, _Db, _DocId) -> Hlist = mochiweb_headers:to_list(Headers), to_json_terms(Hlist); json_req_obj_field(<<"body">>, #httpd{req_body=undefined, mochi_req=Req}, _Db, _DocId) -> - MaxSize = config:get_integer("httpd", "max_http_request_size", 4294967296), + MaxSize = chttpd_util:get_chttpd_config_integer( + "max_http_request_size", 4294967296), try Req:recv_body(MaxSize) catch exit:normal -> diff --git a/src/chttpd/src/chttpd_node.erl b/src/chttpd/src/chttpd_node.erl index c48dfc09a..99407da72 100644 --- a/src/chttpd/src/chttpd_node.erl +++ b/src/chttpd/src/chttpd_node.erl @@ -137,7 +137,8 @@ handle_node_req(#httpd{path_parts=[_, Node | PathParts], {_, Query, Fragment} = mochiweb_util:urlsplit_path(RawUri), NewPath0 = "/" ++ lists:join("/", [couch_util:url_encode(P) || P <- PathParts]), NewRawPath = mochiweb_util:urlunsplit_path({NewPath0, Query, Fragment}), - MaxSize = config:get_integer("httpd", "max_http_request_size", 4294967296), + MaxSize = chttpd_util:get_chttpd_config_integer( + "max_http_request_size", 4294967296), NewOpts = [{body, MochiReq0:recv_body(MaxSize)} | MochiReq0:get(opts)], Ref = erlang:make_ref(), MochiReq = mochiweb_request:new({remote, self(), Ref}, diff --git a/src/chttpd/src/chttpd_rewrite.erl b/src/chttpd/src/chttpd_rewrite.erl index 1c2c1f333..22edb3fac 100644 --- a/src/chttpd/src/chttpd_rewrite.erl +++ b/src/chttpd/src/chttpd_rewrite.erl @@ -28,7 +28,7 @@ handle_rewrite_req(#httpd{}=Req, Db, DDoc) -> RewritesSoFar = erlang:get(?REWRITE_COUNT), - MaxRewrites = config:get_integer("httpd", "rewrite_limit", 100), + MaxRewrites = chttpd_util:get_chttpd_config_integer("rewrite_limit", 100), case RewritesSoFar >= MaxRewrites of true -> throw({bad_request, <<"Exceeded rewrite recursion limit">>}); @@ -442,12 +442,13 @@ path_to_list([<<>>|R], Acc, DotDotCount) -> path_to_list([<<"*">>|R], Acc, DotDotCount) -> path_to_list(R, [?MATCH_ALL|Acc], DotDotCount); path_to_list([<<"..">>|R], Acc, DotDotCount) when DotDotCount == 2 -> - case config:get("httpd", "secure_rewrites", "true") of - "false" -> - path_to_list(R, [<<"..">>|Acc], DotDotCount+1); - _Else -> - couch_log:notice("insecure_rewrite_rule ~p blocked", [lists:reverse(Acc) ++ [<<"..">>] ++ R]), - throw({insecure_rewrite_rule, "too many ../.. segments"}) + case chttpd_util:get_chttpd_config_boolean("secure_rewrites", true) of + false -> + path_to_list(R, [<<"..">>|Acc], DotDotCount+1); + true -> + couch_log:notice("insecure_rewrite_rule ~p blocked", + [lists:reverse(Acc) ++ [<<"..">>] ++ R]), + throw({insecure_rewrite_rule, "too many ../.. segments"}) end; path_to_list([<<"..">>|R], Acc, DotDotCount) -> path_to_list(R, [<<"..">>|Acc], DotDotCount+1); diff --git a/src/chttpd/src/chttpd_util.erl b/src/chttpd/src/chttpd_util.erl new file mode 100644 index 000000000..8c0b6f1c9 --- /dev/null +++ b/src/chttpd/src/chttpd_util.erl @@ -0,0 +1,39 @@ +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +-module(chttpd_util). + + +-export([ + get_chttpd_config/1, + get_chttpd_config/2, + get_chttpd_config_integer/2, + get_chttpd_config_boolean/2 +]). + + +get_chttpd_config(Key) -> + config:get("chttpd", Key, config:get("httpd", Key)). + + +get_chttpd_config(Key, Default) -> + config:get("chttpd", Key, config:get("httpd", Key, Default)). + + +get_chttpd_config_integer(Key, Default) -> + config:get_integer("chttpd", Key, + config:get_integer("httpd", Key, Default)). + + +get_chttpd_config_boolean(Key, Default) -> + config:get_boolean("chttpd", Key, + config:get_boolean("httpd", Key, Default)). diff --git a/src/chttpd/src/chttpd_xframe_options.erl b/src/chttpd/src/chttpd_xframe_options.erl index 9d3a554cc..2a43617fa 100644 --- a/src/chttpd/src/chttpd_xframe_options.erl +++ b/src/chttpd/src/chttpd_xframe_options.erl @@ -71,7 +71,8 @@ check_host(#httpd{mochi_req = MochiReq} = Req, Config) -> get_xframe_config(#httpd{xframe_config = undefined}) -> - EnableXFrame = config:get("httpd", "enable_xframe_options", "false") =:= "true", + EnableXFrame = chttpd_util:get_chttpd_config_boolean( + "enable_xframe_options", false), SameOrigin = config:get("x_frame_options", "same_origin", "false") =:= "true", AcceptedHosts = case config:get("x_frame_options", "hosts") of undefined -> []; diff --git a/src/chttpd/test/eunit/chttpd_util_test.erl b/src/chttpd/test/eunit/chttpd_util_test.erl new file mode 100644 index 000000000..fec05c830 --- /dev/null +++ b/src/chttpd/test/eunit/chttpd_util_test.erl @@ -0,0 +1,107 @@ +% Licensed under the Apache License, Version 2.0 (the "License"); you may not +% use this file except in compliance with the License. You may obtain a copy of +% the License at +% +% http://www.apache.org/licenses/LICENSE-2.0 +% +% Unless required by applicable law or agreed to in writing, software +% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +% License for the specific language governing permissions and limitations under +% the License. + +-module(chttpd_util_test). + + +-include_lib("couch/include/couch_eunit.hrl"). +-include("chttpd_test.hrl"). + + +setup() -> + ok = config:set("httpd", "both_exist", "get_in_httpd", _Persist = false), + ok = config:set("chttpd", "both_exist", "get_in_chttpd", _Persist = false), + ok = config:set("httpd", "httpd_only", "true", _Persist = false), + ok = config:set("chttpd", "chttpd_only", "1", _Persist = false). + + +teardown(_) -> + ok = config:delete("httpd", "both_exist", _Persist = false), + ok = config:delete("chttpd", "both_exist", _Persist = false), + ok = config:delete("httpd", "httpd_only", _Persist = false), + ok = config:delete("chttpd", "chttpd_only", _Persist = false). + + +chttpd_util_config_test_() -> + { + "chttpd util config tests", + { + setup, + fun test_util:start_couch/0, + fun test_util:stop_couch/1, + { + foreach, + fun setup/0, + fun teardown/1, + [ + ?TDEF_FE(test_behavior), + ?TDEF_FE(test_with_undefined_option), + ?TDEF_FE(test_with_httpd_option), + ?TDEF_FE(test_with_chttpd_option), + ?TDEF_FE(test_with_chttpd_option_which_moved_from_httpd), + ?TDEF_FE(test_get_chttpd_config_integer), + ?TDEF_FE(test_get_chttpd_config_boolean) + ] + } + } + }. + + +test_behavior(_) -> + ?assertEqual("get_in_chttpd", chttpd_util:get_chttpd_config("both_exist")), + ?assertEqual(1, chttpd_util:get_chttpd_config_integer("chttpd_only", 0)), + ?assert(chttpd_util:get_chttpd_config_boolean("httpd_only", false)). + + +test_with_undefined_option(_) -> + ?assertEqual(undefined, chttpd_util:get_chttpd_config("undefined_option")), + ?assertEqual(abc, chttpd_util:get_chttpd_config("undefined_option", abc)), + ?assertEqual(123, chttpd_util:get_chttpd_config("undefined_option", 123)), + ?assertEqual(0.2, chttpd_util:get_chttpd_config("undefined_option", 0.2)), + ?assertEqual("a", chttpd_util:get_chttpd_config("undefined_option", "a")), + ?assertEqual("", chttpd_util:get_chttpd_config("undefined_option", "")), + ?assert(chttpd_util:get_chttpd_config("undefined_option", true)), + ?assertNot(chttpd_util:get_chttpd_config("undefined_option", false)). + + +test_with_httpd_option(_) -> + ?assertEqual("{couch_httpd_auth, cookie_authentication_handler}, " ++ + "{couch_httpd_auth, default_authentication_handler}", + chttpd_util:get_chttpd_config("authentication_handlers")). + + +test_with_chttpd_option(_) -> + ?assertEqual("512", chttpd_util:get_chttpd_config("backlog")), + ?assertEqual("512", chttpd_util:get_chttpd_config("backlog", 123)), + ?assertEqual(512, chttpd_util:get_chttpd_config_integer("backlog", 123)), + ?assertEqual("false", + chttpd_util:get_chttpd_config("require_valid_user")), + ?assertEqual("false", + chttpd_util:get_chttpd_config("require_valid_user", "true")), + ?assertEqual(false, + chttpd_util:get_chttpd_config_boolean("require_valid_user", true)). + + +test_with_chttpd_option_which_moved_from_httpd(_) -> + ?assertEqual(undefined, chttpd_util:get_chttpd_config("max_uri_length")), + ?assertEqual(8000, chttpd_util:get_chttpd_config("max_uri_length", 8000)), + ?assertEqual(undefined, chttpd_util:get_chttpd_config("WWW-Authenticate")), + ?assert(chttpd_util:get_chttpd_config("enable_cors", true)). + + +test_get_chttpd_config_integer(_) -> + ?assertEqual(123, + chttpd_util:get_chttpd_config_integer("max_http_request_size", 123)). + + +test_get_chttpd_config_boolean(_) -> + ?assert(chttpd_util:get_chttpd_config_boolean("allow_jsonp", true)). diff --git a/src/couch/src/couch_changes.erl b/src/couch/src/couch_changes.erl index 41b132152..2078fed3a 100644 --- a/src/couch/src/couch_changes.erl +++ b/src/couch/src/couch_changes.erl @@ -370,9 +370,8 @@ get_changes_timeout(Args, Callback) -> timeout = Timeout, feed = ResponseType } = Args, - DefaultTimeout = list_to_integer( - config:get("httpd", "changes_timeout", "60000") - ), + DefaultTimeout = chttpd_util:get_chttpd_config_integer( + "changes_timeout", 60000), case Heartbeat of undefined -> case Timeout of diff --git a/src/couch/src/couch_httpd.erl b/src/couch/src/couch_httpd.erl index a1798b705..d23db21d2 100644 --- a/src/couch/src/couch_httpd.erl +++ b/src/couch/src/couch_httpd.erl @@ -387,7 +387,7 @@ handle_request_int(MochiReq, DefaultFun, {ok, Resp}. validate_host(#httpd{} = Req) -> - case config:get_boolean("httpd", "validate_host", false) of + case chttpd_util:get_chttpd_config_boolean("validate_host", false) of true -> Host = hostname(Req), ValidHosts = valid_hosts(), @@ -411,11 +411,12 @@ hostname(#httpd{} = Req) -> end. valid_hosts() -> - List = config:get("httpd", "valid_hosts", ""), + List = chttpd_util:get_chttpd_config("valid_hosts", ""), re:split(List, ",", [{return, list}]). check_request_uri_length(Uri) -> - check_request_uri_length(Uri, config:get("httpd", "max_uri_length")). + check_request_uri_length(Uri, + chttpd_util:get_chttpd_config("max_uri_length")). check_request_uri_length(_Uri, undefined) -> ok; @@ -464,7 +465,8 @@ validate_ctype(Req, Ctype) -> check_max_request_length(Req) -> Len = list_to_integer(header_value(Req, "Content-Length", "0")), - MaxLen = config:get_integer("httpd", "max_http_request_size", 4294967296), + MaxLen = chttpd_util:get_chttpd_config_integer( + "max_http_request_size", 4294967296), case Len > MaxLen of true -> exit({body_too_large, Len}); @@ -533,7 +535,8 @@ path(#httpd{mochi_req=MochiReq}) -> MochiReq:get(path). host_for_request(#httpd{mochi_req=MochiReq}) -> - XHost = config:get("httpd", "x_forwarded_host", "X-Forwarded-Host"), + XHost = chttpd_util:get_chttpd_config( + "x_forwarded_host", "X-Forwarded-Host"), case MochiReq:get_header_value(XHost) of undefined -> case MochiReq:get_header_value("Host") of @@ -551,11 +554,12 @@ host_for_request(#httpd{mochi_req=MochiReq}) -> absolute_uri(#httpd{mochi_req=MochiReq}=Req, [$/ | _] = Path) -> Host = host_for_request(Req), - XSsl = config:get("httpd", "x_forwarded_ssl", "X-Forwarded-Ssl"), + XSsl = chttpd_util:get_chttpd_config("x_forwarded_ssl", "X-Forwarded-Ssl"), Scheme = case MochiReq:get_header_value(XSsl) of "on" -> "https"; _ -> - XProto = config:get("httpd", "x_forwarded_proto", "X-Forwarded-Proto"), + XProto = chttpd_util:get_chttpd_config( + "x_forwarded_proto", "X-Forwarded-Proto"), case MochiReq:get_header_value(XProto) of %% Restrict to "https" and "http" schemes only "https" -> "https"; @@ -586,13 +590,15 @@ recv_chunked(#httpd{mochi_req=MochiReq}, MaxChunkSize, ChunkFun, InitState) -> % Fun({Length, Binary}, State) % called with Length == 0 on the last time. MochiReq:stream_body(MaxChunkSize, ChunkFun, InitState, - config:get_integer("httpd", "max_http_request_size", 4294967296)). + chttpd_util:get_chttpd_config_integer( + "max_http_request_size", 4294967296)). body_length(#httpd{mochi_req=MochiReq}) -> MochiReq:get(body_length). body(#httpd{mochi_req=MochiReq, req_body=undefined}) -> - MaxSize = config:get_integer("httpd", "max_http_request_size", 4294967296), + MaxSize = chttpd_util:get_chttpd_config_integer( + "max_http_request_size", 4294967296), MochiReq:recv_body(MaxSize); body(#httpd{req_body=ReqBody}) -> ReqBody. @@ -837,11 +843,12 @@ initialize_jsonp(Req) -> CallBack -> try % make sure jsonp is configured on (default off) - case config:get("httpd", "allow_jsonp", "false") of - "true" -> - validate_callback(CallBack); - _Else -> - put(jsonp, no_jsonp) + case chttpd_util:get_chttpd_config_boolean( + "allow_jsonp", false) of + true -> + validate_callback(CallBack); + false -> + put(jsonp, no_jsonp) end catch Error -> @@ -944,7 +951,7 @@ 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", undefined) of + case chttpd_util:get_chttpd_config("WWW-Authenticate") of undefined -> % If the client is a browser and the basic auth popup isn't turned on % redirect to the session page. diff --git a/src/couch/src/couch_httpd_misc_handlers.erl b/src/couch/src/couch_httpd_misc_handlers.erl index 3d25f5853..9bbede746 100644 --- a/src/couch/src/couch_httpd_misc_handlers.erl +++ b/src/couch/src/couch_httpd_misc_handlers.erl @@ -157,7 +157,7 @@ handle_config_req(#httpd{method=Method, path_parts=[_, Section, Key]}=Req) ok = couch_httpd:verify_is_server_admin(Req), couch_util:check_config_blacklist(Section), Persist = couch_httpd:header_value(Req, "X-Couch-Persist") /= "false", - case config:get("httpd", "config_whitelist", undefined) of + case chttpd_util:get_chttpd_config("config_whitelist") of undefined -> % No whitelist; allow all changes. handle_approved_config_req(Req, Persist); @@ -167,7 +167,7 @@ handle_config_req(#httpd{method=Method, path_parts=[_, Section, Key]}=Req) % Erlang term. To intentionally lock down the whitelist, supply a % well-formed list which does not include the whitelist config % variable itself. - FallbackWhitelist = [{<<"httpd">>, <<"config_whitelist">>}], + FallbackWhitelist = [{<<"chttpd">>, <<"config_whitelist">>}], Whitelist = case couch_util:parse_term(WhitelistValue) of {ok, Value} when is_list(Value) -> diff --git a/src/couch/src/couch_httpd_rewrite.erl b/src/couch/src/couch_httpd_rewrite.erl index 2845c0b16..40e5c9e3c 100644 --- a/src/couch/src/couch_httpd_rewrite.erl +++ b/src/couch/src/couch_httpd_rewrite.erl @@ -123,7 +123,7 @@ handle_rewrite_req(#httpd{ QueryList = lists:map(fun decode_query_value/1, couch_httpd:qs(Req)), RewritesSoFar = erlang:get(?REWRITE_COUNT), - MaxRewrites = list_to_integer(config:get("httpd", "rewrite_limit", "100")), + MaxRewrites = chttpd_util:get_chttpd_config_integer("rewrite_limit", 100), case RewritesSoFar >= MaxRewrites of true -> throw({bad_request, <<"Exceeded rewrite recursion limit">>}); @@ -438,13 +438,13 @@ path_to_list([<<>>|R], Acc, DotDotCount) -> path_to_list([<<"*">>|R], Acc, DotDotCount) -> path_to_list(R, [?MATCH_ALL|Acc], DotDotCount); path_to_list([<<"..">>|R], Acc, DotDotCount) when DotDotCount == 2 -> - case config:get("httpd", "secure_rewrites", "true") of - "false" -> - path_to_list(R, [<<"..">>|Acc], DotDotCount+1); - _Else -> - couch_log:info("insecure_rewrite_rule ~p blocked", - [lists:reverse(Acc) ++ [<<"..">>] ++ R]), - throw({insecure_rewrite_rule, "too many ../.. segments"}) + case chttpd_util:get_chttpd_config_boolean("secure_rewrites", true) of + false -> + path_to_list(R, [<<"..">>|Acc], DotDotCount+1); + true -> + couch_log:info("insecure_rewrite_rule ~p blocked", + [lists:reverse(Acc) ++ [<<"..">>] ++ R]), + throw({insecure_rewrite_rule, "too many ../.. segments"}) end; path_to_list([<<"..">>|R], Acc, DotDotCount) -> path_to_list(R, [<<"..">>|Acc], DotDotCount+1); diff --git a/src/couch/src/couch_httpd_vhost.erl b/src/couch/src/couch_httpd_vhost.erl index 574dba9c8..409631d25 100644 --- a/src/couch/src/couch_httpd_vhost.erl +++ b/src/couch/src/couch_httpd_vhost.erl @@ -253,8 +253,8 @@ bind_path(_, _) -> %% create vhost list from ini host(MochiReq) -> - XHost = config:get("httpd", "x_forwarded_host", - "X-Forwarded-Host"), + XHost = chttpd_util:get_chttpd_config( + "x_forwarded_host", "X-Forwarded-Host"), case MochiReq:get_header_value(XHost) of undefined -> case MochiReq:get_header_value("Host") of diff --git a/src/couch/test/eunit/couchdb_cors_tests.erl b/src/couch/test/eunit/couchdb_cors_tests.erl index 82630bba7..8ec61cc8a 100644 --- a/src/couch/test/eunit/couchdb_cors_tests.erl +++ b/src/couch/test/eunit/couchdb_cors_tests.erl @@ -27,7 +27,7 @@ start() -> Ctx = test_util:start_couch([ioq]), - ok = config:set("httpd", "enable_cors", "true", false), + ok = config:set("chttpd", "enable_cors", "true", false), ok = config:set("vhosts", "example.com", "/", false), Ctx. diff --git a/src/couch/test/eunit/couchdb_mrview_cors_tests.erl b/src/couch/test/eunit/couchdb_mrview_cors_tests.erl index 0f69048a0..3a560edce 100644 --- a/src/couch/test/eunit/couchdb_mrview_cors_tests.erl +++ b/src/couch/test/eunit/couchdb_mrview_cors_tests.erl @@ -33,7 +33,7 @@ start() -> Ctx = test_util:start_couch([chttpd]), Hashed = couch_passwords:hash_admin_password(?PASS), ok = config:set("admins", ?USER, ?b2l(Hashed), _Persist=false), - ok = config:set("httpd", "enable_cors", "true", false), + ok = config:set("chttpd", "enable_cors", "true", false), ok = config:set("vhosts", "example.com", "/", false), Ctx. diff --git a/src/couch_replicator/test/eunit/couch_replicator_small_max_request_size_target.erl b/src/couch_replicator/test/eunit/couch_replicator_small_max_request_size_target.erl index 8aebbe151..91bda33fa 100644 --- a/src/couch_replicator/test/eunit/couch_replicator_small_max_request_size_target.erl +++ b/src/couch_replicator/test/eunit/couch_replicator_small_max_request_size_target.erl @@ -24,7 +24,7 @@ setup(remote) -> setup({A, B}) -> Ctx = test_util:start_couch([couch_replicator]), - config:set("httpd", "max_http_request_size", "10000", false), + config:set("chttpd", "max_http_request_size", "10000", false), Source = setup(A), Target = setup(B), {Ctx, {Source, Target}}. diff --git a/test/elixir/test/changes_test.exs b/test/elixir/test/changes_test.exs index fe7329176..e3e8ba784 100644 --- a/test/elixir/test/changes_test.exs +++ b/test/elixir/test/changes_test.exs @@ -274,7 +274,7 @@ defmodule ChangesTest do assert resp.body["error"] == "bad_request" assert resp.body["reason"] == "invalid UTF-8 JSON" - set_config({"httpd", "max_http_request_size", "16"}) + set_config({"chttpd", "max_http_request_size", "16"}) resp = Couch.post("/#{db_name}/_changes?filter=changes_filter/bop", body: %{doc_ids: ["doc1", "doc3", "doc4"]}, diff --git a/test/elixir/test/config_test.exs b/test/elixir/test/config_test.exs index 53c5bc82e..7600cecf2 100644 --- a/test/elixir/test/config_test.exs +++ b/test/elixir/test/config_test.exs @@ -80,7 +80,7 @@ defmodule ConfigTest do end test "Settings can be altered with undefined whitelist allowing any change", context do - refute context["config"]["httpd"]["config_whitelist"], "Default whitelist is empty" + refute context["config"]["chttpd"]["config_whitelist"], "Default whitelist is empty" set_config(context, "test", "foo", "bar") assert get_config(context, "test")["foo"] == "bar" assert get_config(context, "test", "foo") == "bar" @@ -104,32 +104,32 @@ defmodule ConfigTest do test "Non-term whitelist values allow further modification of the whitelist", context do val = "!This is an invalid Erlang term!" - set_config(context, "httpd", "config_whitelist", val) - assert val == get_config(context, "httpd", "config_whitelist") - delete_config(context, "httpd", "config_whitelist") + set_config(context, "chttpd", "config_whitelist", val) + assert val == get_config(context, "chttpd", "config_whitelist") + delete_config(context, "chttpd", "config_whitelist") end test "Non-list whitelist values allow further modification of the whitelist", context do val = "{[yes, a_valid_erlang_term, but_unfortunately, not_a_list]}" - set_config(context, "httpd", "config_whitelist", val) - assert val == get_config(context, "httpd", "config_whitelist") - delete_config(context, "httpd", "config_whitelist") + set_config(context, "chttpd", "config_whitelist", val) + assert val == get_config(context, "chttpd", "config_whitelist") + delete_config(context, "chttpd", "config_whitelist") end test "Keys not in the whitelist may not be modified", context do - val = "[{httpd,config_whitelist}, {test,foo}]" - set_config(context, "httpd", "config_whitelist", val) - assert val == get_config(context, "httpd", "config_whitelist") + val = "[{chttpd,config_whitelist}, {test,foo}]" + set_config(context, "chttpd", "config_whitelist", val) + assert val == get_config(context, "chttpd", "config_whitelist") set_config(context, "test", "foo", "PUT to whitelisted config variable") delete_config(context, "test", "foo") end test "Non-2-tuples in the whitelist are ignored", context do val = - "[{httpd,config_whitelist}, these, {are}, {nOt, 2, tuples}, [so], [they, will], [all, become, noops], {test,foo}]" + "[{chttpd,config_whitelist}, these, {are}, {nOt, 2, tuples}, [so], [they, will], [all, become, noops], {test,foo}]" - set_config(context, "httpd", "config_whitelist", val) - assert val == get_config(context, "httpd", "config_whitelist") + set_config(context, "chttpd", "config_whitelist", val) + assert val == get_config(context, "chttpd", "config_whitelist") set_config(context, "test", "foo", "PUT to whitelisted config variable") delete_config(context, "test", "foo") end @@ -140,9 +140,9 @@ defmodule ConfigTest do Enum.each(vals, fn pair -> set_config( context, - "httpd", + "chttpd", "config_whitelist", - "[{httpd,config_whitelist}, #{pair}" + "[{chttpd,config_whitelist}, #{pair}" ) pair_format = @@ -156,7 +156,7 @@ defmodule ConfigTest do delete_config(context, "test", "foo") end) - delete_config(context, "httpd", "config_whitelist") + delete_config(context, "chttpd", "config_whitelist") end test "Blacklist is functional", context do diff --git a/test/elixir/test/http_test.exs b/test/elixir/test/http_test.exs index 09d743060..4f4cf26d6 100644 --- a/test/elixir/test/http_test.exs +++ b/test/elixir/test/http_test.exs @@ -30,7 +30,7 @@ defmodule HttpTest do server_config = [ %{ - :section => "httpd", + :section => "chttpd", :key => "x_forwarded_host", :value => "X-Host" } diff --git a/test/elixir/test/jsonp_test.exs b/test/elixir/test/jsonp_test.exs index 3fdc2ba5f..169f66387 100644 --- a/test/elixir/test/jsonp_test.exs +++ b/test/elixir/test/jsonp_test.exs @@ -19,7 +19,7 @@ defmodule JsonpTest do server_config = [ %{ - :section => "httpd", + :section => "chttpd", :key => "allow_jsonp", :value => "true" } @@ -50,7 +50,7 @@ defmodule JsonpTest do server_config = [ %{ - :section => "httpd", + :section => "chttpd", :key => "allow_jsonp", :value => "true" } diff --git a/test/elixir/test/rewrite_test.exs b/test/elixir/test/rewrite_test.exs index 30feac0ea..e23d63609 100644 --- a/test/elixir/test/rewrite_test.exs +++ b/test/elixir/test/rewrite_test.exs @@ -15,7 +15,7 @@ defmodule RewriteTest do @tag config: [ {"httpd", "authentication_handlers", "{couch_httpd_auth, special_test_authentication_handler}"}, - {"httpd", "WWW-Authenticate", "X-Couch-Test-Auth"} + {"chttpd", "WWW-Authenticate", "X-Couch-Test-Auth"} ] test "Test basic rewrites on #{db_name}", context do db_name = context[:db_name] @@ -449,7 +449,7 @@ defmodule RewriteTest do @tag with_random_db: db_name @tag config: [ - {"httpd", "secure_rewrites", "false"} + {"chttpd", "secure_rewrites", "false"} ] test "path relative to server on #{db_name}", context do db_name = context[:db_name] @@ -473,7 +473,7 @@ defmodule RewriteTest do @tag with_random_db: db_name @tag config: [ - {"httpd", "rewrite_limit", "2"} + {"chttpd", "rewrite_limit", "2"} ] test "loop detection on #{db_name}", context do db_name = context[:db_name] @@ -491,8 +491,8 @@ defmodule RewriteTest do @tag with_random_db: db_name @tag config: [ - {"httpd", "rewrite_limit", "2"}, - {"httpd", "secure_rewrites", "false"} + {"chttpd", "rewrite_limit", "2"}, + {"chttpd", "secure_rewrites", "false"} ] test "serial execution is not spuriously counted as loop on #{db_name}", context do db_name = context[:db_name] diff --git a/test/javascript/tests/rewrite.js b/test/javascript/tests/rewrite.js index 88479b877..a470eaee6 100644 --- a/test/javascript/tests/rewrite.js +++ b/test/javascript/tests/rewrite.js @@ -26,7 +26,7 @@ couchTests.rewrite = function(debug) { [{section: "httpd", key: "authentication_handlers", value: "{couch_httpd_auth, special_test_authentication_handler}"}, - {section:"httpd", + {section:"chttpd", key: "WWW-Authenticate", value: "X-Couch-Test-Auth"}], @@ -430,7 +430,7 @@ couchTests.rewrite = function(debug) { T(result.error == "insecure_rewrite_rule"); run_on_modified_server( - [{section: "httpd", + [{section: "chttpd", key: "secure_rewrites", value: "false"}], function() { @@ -483,7 +483,7 @@ couchTests.rewrite = function(debug) { // Assert loop detection run_on_modified_server( - [{section: "httpd", + [{section: "chttpd", key: "rewrite_limit", value: "2"}], function(){ @@ -494,10 +494,10 @@ couchTests.rewrite = function(debug) { // Assert serial execution is not spuriously counted as loop run_on_modified_server( - [{section: "httpd", + [{section: "chttpd", key: "rewrite_limit", value: "2"}, - {section: "httpd", + {section: "chttpd", key: "secure_rewrites", value: "false"}], function(){ |