diff --git a/config/default.yml b/config/default.yml index a1b7a5352..21486ff2f 100644 --- a/config/default.yml +++ b/config/default.yml @@ -130,8 +130,9 @@ router: ip_connections_log_level: error web_app_host: "*" web_app_backend_regex: "^/(admin|admins|web-assets)(/|$)" - web_app_backend_required_https_regex: "^/(admin|admins)(/|$)" - website_backend_required_https_regex_default: "^/(account|signup|contact)(/|$)" + web_app_backend_required_https_regex: "^.*" + website_backend_required_https_regex_default: "^.*" + redirect_not_found_to_https: true rsyslog: host: 127.0.0.1 port: 14014 diff --git a/src/api-umbrella/proxy/error_handler.lua b/src/api-umbrella/proxy/error_handler.lua index c5f2145cd..06b32c7cb 100644 --- a/src/api-umbrella/proxy/error_handler.lua +++ b/src/api-umbrella/proxy/error_handler.lua @@ -1,5 +1,6 @@ -local is_hash = require "api-umbrella.utils.is_hash" local deep_merge_overwrite_arrays = require "api-umbrella.utils.deep_merge_overwrite_arrays" +local httpsify_current_url = require "api-umbrella.utils.httpsify_current_url" +local is_hash = require "api-umbrella.utils.is_hash" local lustache = require "lustache" local mustache_unescape = require "api-umbrella.utils.mustache_unescape" local path = require "pl.path" @@ -122,6 +123,20 @@ local function render_template(template, data, format, strip_whitespace) end return function(denied_code, settings, extra_data) + -- Redirect "not_found" errors to HTTPS. + -- + -- Since these errors aren't subject to an API Backend's HTTPS requirements + -- (where we might return the "https_required" error), this helps ensure that + -- requests to unknown location (neither API or website backend) are + -- redirected to HTTPS like the rest of our non-API content. This ensures + -- HTTPS redirects are in place for the root request on custom domains + -- without a website or API at the root. + if denied_code == "not_found" and config["router"]["redirect_not_found_to_https"] then + if ngx.ctx.protocol ~= "https" then + return ngx.redirect(httpsify_current_url(), ngx.HTTP_MOVED_PERMANENTLY) + end + end + -- Store the gatekeeper rejection code for logging. ngx.ctx.gatekeeper_denied_code = denied_code diff --git a/test/processes/test_reloads.rb b/test/processes/test_reloads.rb index 2c855d339..dbdda3fd8 100644 --- a/test/processes/test_reloads.rb +++ b/test/processes/test_reloads.rb @@ -171,7 +171,7 @@ def test_file_based_config_changes_updates_templates end def test_file_based_config_changes_updates_apis - response = Typhoeus.get("http://127.0.0.1:9080/#{unique_test_id}/file-config/info/", http_options) + response = Typhoeus.get("https://127.0.0.1:9081/#{unique_test_id}/file-config/info/", http_options) assert_response_code(404, response) override_config({ @@ -187,13 +187,13 @@ def test_file_based_config_changes_updates_apis }, ], }, "--router") do - response = Typhoeus.get("http://127.0.0.1:9080/#{unique_test_id}/file-config/info/", http_options) + response = Typhoeus.get("https://127.0.0.1:9081/#{unique_test_id}/file-config/info/", http_options) assert_response_code(200, response) data = MultiJson.load(response.body) assert_equal(data["headers"]["x-test-file-config"], "foo") end - response = Typhoeus.get("http://127.0.0.1:9080/#{unique_test_id}/file-config/info/", http_options) + response = Typhoeus.get("https://127.0.0.1:9081/#{unique_test_id}/file-config/info/", http_options) assert_response_code(404, response) end diff --git a/test/proxy/logging/test_basics.rb b/test/proxy/logging/test_basics.rb index 66c044f83..bb9bedb9f 100644 --- a/test/proxy/logging/test_basics.rb +++ b/test/proxy/logging/test_basics.rb @@ -510,7 +510,7 @@ def test_case_sensitivity end def test_does_not_website_backend_requests - response = Typhoeus.get("http://127.0.0.1:9080/", log_http_options) + response = Typhoeus.get("https://127.0.0.1:9081/", log_http_options) assert_response_code(200, response) error = assert_raises Timeout::Error do diff --git a/test/proxy/routing/test_https_config.rb b/test/proxy/routing/test_https_config.rb new file mode 100644 index 000000000..0e39d0286 --- /dev/null +++ b/test/proxy/routing/test_https_config.rb @@ -0,0 +1,58 @@ +require_relative "../../test_helper" + +class Test::Proxy::Routing::TestHttpsConfig < Minitest::Test + include ApiUmbrellaTestHelpers::Setup + include ApiUmbrellaTestHelpers::AdminAuth + include Minitest::Hooks + + def setup + super + setup_server + once_per_class_setup do + override_config_set({ + "router" => { + "web_app_backend_required_https_regex" => "^/admin/web-app-https-test", + "website_backend_required_https_regex_default" => "^/website-https-test", + "redirect_not_found_to_https" => false, + "web_app_host" => "127.0.0.1", + }, + }, "--router") + end + end + + def after_all + super + override_config_reset("--router") + end + + def test_custom_web_app_regex + response = Typhoeus.get("http://127.0.0.1:9080/admin/", keyless_http_options) + assert_response_code(200, response) + assert_match(%r{