You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by to...@apache.org on 2021/05/11 08:53:02 UTC
[apisix] branch master updated: feat: add 50x html for error page
(#4164)
This is an automated email from the ASF dual-hosted git repository.
tokers pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new adc9977 feat: add 50x html for error page (#4164)
adc9977 is described below
commit adc9977dd0459be7ee5386b7269684b70d69f29b
Author: Peter Zhu <st...@gmail.com>
AuthorDate: Tue May 11 16:52:48 2021 +0800
feat: add 50x html for error page (#4164)
---
.gitignore | 1 +
apisix/cli/html_page.lua | 39 ++++++++++++
apisix/cli/ngx_tpl.lua | 39 ++++++++++++
apisix/cli/ops.lua | 9 +++
apisix/init.lua | 19 +++++-
ci/ASF-Release.cfg | 1 +
t/APISIX.pm | 29 +++++++++
t/error_page/50x.html | 38 ++++++++++++
t/error_page/error_page.t | 141 +++++++++++++++++++++++++++++++++++++++++++
t/lib/server.lua | 9 +++
t/node/upstream-status-5xx.t | 4 +-
11 files changed, 325 insertions(+), 4 deletions(-)
diff --git a/.gitignore b/.gitignore
index 98b0b7e..92d7722 100644
--- a/.gitignore
+++ b/.gitignore
@@ -74,3 +74,4 @@ ci/openwhisk-utilities/
# release tar package
*.tgz
release/*
+html/*
diff --git a/apisix/cli/html_page.lua b/apisix/cli/html_page.lua
new file mode 100644
index 0000000..f262ad8
--- /dev/null
+++ b/apisix/cli/html_page.lua
@@ -0,0 +1,39 @@
+--
+-- Licensed to the Apache Software Foundation (ASF) under one or more
+-- contributor license agreements. See the NOTICE file distributed with
+-- this work for additional information regarding copyright ownership.
+-- The ASF licenses this file to You 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.
+--
+
+return [=[
+<!DOCTYPE html>
+<html>
+<head>
+<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
+<meta content="utf-8" http-equiv="encoding">
+<title>500 Internal Server Error</title>
+<style>
+ body {
+ width: 35em;
+ margin: 0 auto;
+ font-family: Tahoma, Verdana, Arial, sans-serif;
+ }
+</style>
+</head>
+<body>
+<h1>An error occurred.</h1>
+<p>You can report issue to <a href="https://github.com/apache/apisix/issues">APISIX</a></p>
+<p><em>Faithfully yours, <a href="https://apisix.apache.org/">APISIX</a>.</em></p>
+</body>
+</html>
+]=]
diff --git a/apisix/cli/ngx_tpl.lua b/apisix/cli/ngx_tpl.lua
index c9c5d78..041a2d6 100644
--- a/apisix/cli/ngx_tpl.lua
+++ b/apisix/cli/ngx_tpl.lua
@@ -219,6 +219,9 @@ http {
include mime.types;
charset utf-8;
+ # error_page
+ error_page 500 @50x.html;
+
{% if real_ip_header then %}
real_ip_header {* real_ip_header *};
{% print("\nDeprecated: apisix.real_ip_header has been moved to nginx_config.http.real_ip_header. apisix.real_ip_header will be removed in the future version. Please use nginx_config.http.real_ip_header first.\n\n") %}
@@ -290,6 +293,18 @@ http {
apisix.http_control()
}
}
+
+ location @50x.html {
+ set $from_error_page 'true';
+ try_files /50x.html $uri;
+ header_filter_by_lua_block {
+ apisix.http_header_filter_phase()
+ }
+
+ log_by_lua_block {
+ apisix.http_log_phase()
+ }
+ }
}
{% end %}
@@ -367,6 +382,18 @@ http {
apisix.http_admin()
}
}
+
+ location @50x.html {
+ set $from_error_page 'true';
+ try_files /50x.html $uri;
+ header_filter_by_lua_block {
+ apisix.http_header_filter_phase()
+ }
+
+ log_by_lua_block {
+ apisix.http_log_phase()
+ }
+ }
}
{% end %}
@@ -617,6 +644,18 @@ http {
proxy_pass $upstream_mirror_host$request_uri;
}
{% end %}
+
+ location @50x.html {
+ set $from_error_page 'true';
+ try_files /50x.html $uri;
+ header_filter_by_lua_block {
+ apisix.http_header_filter_phase()
+ }
+
+ log_by_lua_block {
+ apisix.http_log_phase()
+ }
+ }
}
# http end configuration snippet starts
{% if http_end_configuration_snippet then %}
diff --git a/apisix/cli/ops.lua b/apisix/cli/ops.lua
index fbf0160..7b681a6 100644
--- a/apisix/cli/ops.lua
+++ b/apisix/cli/ops.lua
@@ -19,6 +19,7 @@ local etcd = require("apisix.cli.etcd")
local util = require("apisix.cli.util")
local file = require("apisix.cli.file")
local ngx_tpl = require("apisix.cli.ngx_tpl")
+local html_page = require("apisix.cli.html_page")
local profile = require("apisix.core.profile")
local template = require("resty.template")
local argparse = require("argparse")
@@ -586,6 +587,14 @@ Please modify "admin_key" in conf/config.yaml .
if not ok then
util.die("failed to update nginx.conf: ", err, "\n")
end
+
+ local cmd_html = "mkdir -p " .. env.apisix_home .. "/html"
+ util.execute_cmd(cmd_html)
+
+ local ok, err = util.write_file(env.apisix_home .. "/html/50x.html", html_page)
+ if not ok then
+ util.die("failed to write 50x.html: ", err, "\n")
+ end
end
diff --git a/apisix/init.lua b/apisix/init.lua
index 87da8bc..ae305f7 100644
--- a/apisix/init.lua
+++ b/apisix/init.lua
@@ -475,14 +475,13 @@ function _M.http_access_phase()
set_upstream_host(api_ctx)
+ ngx_var.ctx_ref = ctxdump.stash_ngx_ctx()
local up_scheme = api_ctx.upstream_scheme
if up_scheme == "grpcs" or up_scheme == "grpc" then
- ngx_var.ctx_ref = ctxdump.stash_ngx_ctx()
return ngx.exec("@grpc_pass")
end
if api_ctx.dubbo_proxy_enabled then
- ngx_var.ctx_ref = ctxdump.stash_ngx_ctx()
return ngx.exec("@dubbo_pass")
end
end
@@ -490,11 +489,13 @@ end
function _M.dubbo_access_phase()
ngx.ctx = ctxdump.apply_ngx_ctx(ngx_var.ctx_ref)
+ ngx_var.ctx_ref = ''
end
function _M.grpc_access_phase()
ngx.ctx = ctxdump.apply_ngx_ctx(ngx_var.ctx_ref)
+ ngx_var.ctx_ref = ''
local api_ctx = ngx.ctx.api_ctx
if not api_ctx then
@@ -534,6 +535,16 @@ end
function _M.http_header_filter_phase()
+ if ngx_var.ctx_ref ~= '' then
+ -- prevent for the table leak
+ local stash_ctx = ctxdump.apply_ngx_ctx(ngx_var.ctx_ref)
+
+ -- internal redirect, so we should apply the ctx
+ if ngx_var.from_error_page == "true" then
+ ngx.ctx = stash_ctx
+ end
+ end
+
core.response.set_header("Server", ver_header)
local up_status = get_var("upstream_status")
@@ -620,6 +631,10 @@ end
function _M.http_log_phase()
local api_ctx = common_phase("log")
+ if not api_ctx then
+ return
+ end
+
healthcheck_passive(api_ctx)
if api_ctx.server_picker and api_ctx.server_picker.after_balance then
diff --git a/ci/ASF-Release.cfg b/ci/ASF-Release.cfg
index 10de19f..7efd557 100644
--- a/ci/ASF-Release.cfg
+++ b/ci/ASF-Release.cfg
@@ -88,6 +88,7 @@ grpcurl
t/servroot
t/lib/dubbo-backend/dubbo-backend-provider/target
t/lib/dubbo-backend/dubbo-backend-interface/target
+html
conf
ci/openwhisk-utilities
diff --git a/t/APISIX.pm b/t/APISIX.pm
index c2a5359..68821bd 100644
--- a/t/APISIX.pm
+++ b/t/APISIX.pm
@@ -89,6 +89,7 @@ my $ssl_ecc_crt = read_file("t/certs/apisix_ecc.crt");
my $ssl_ecc_key = read_file("t/certs/apisix_ecc.key");
my $test2_crt = read_file("t/certs/test2.crt");
my $test2_key = read_file("t/certs/test2.key");
+my $test_50x_html = read_file("t/error_page/50x.html");
$user_yaml_config = <<_EOC_;
apisix:
node_listen: 1984
@@ -374,6 +375,8 @@ _EOC_
lua_socket_log_errors off;
client_body_buffer_size 8k;
+ error_page 500 \@50x.html;
+
upstream apisix_backend {
server 0.0.0.1;
balancer_by_lua_block {
@@ -426,6 +429,18 @@ _EOC_
more_clear_headers Date;
}
+ location \@50x.html {
+ set \$from_error_page 'true';
+ try_files /50x.html \$uri;
+ header_filter_by_lua_block {
+ apisix.http_header_filter_phase()
+ }
+
+ log_by_lua_block {
+ apisix.http_log_phase()
+ }
+ }
+
location = /v3/auth/authenticate {
content_by_lua_block {
ngx.log(ngx.WARN, "etcd auth failed!")
@@ -512,6 +527,18 @@ _EOC_
}
}
+ location \@50x.html {
+ set \$from_error_page 'true';
+ try_files /50x.html \$uri;
+ header_filter_by_lua_block {
+ apisix.http_header_filter_phase()
+ }
+
+ log_by_lua_block {
+ apisix.http_log_phase()
+ }
+ }
+
location /v1/ {
content_by_lua_block {
apisix.http_control()
@@ -625,6 +652,8 @@ $ssl_ecc_key
$test2_crt
>>> ../conf/cert/test2.key
$test2_key
+>>> 50x.html
+$test_50x_html
$user_apisix_yaml
_EOC_
diff --git a/t/error_page/50x.html b/t/error_page/50x.html
new file mode 100644
index 0000000..f3b9e20
--- /dev/null
+++ b/t/error_page/50x.html
@@ -0,0 +1,38 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+-->
+<!DOCTYPE html>
+<html>
+<head>
+<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
+<meta content="utf-8" http-equiv="encoding">
+<title>500 Internal Server Error</title>
+<style>
+ body {
+ width: 35em;
+ margin: 0 auto;
+ font-family: Tahoma, Verdana, Arial, sans-serif;
+ }
+</style>
+</head>
+<body>
+<h1>An error occurred.</h1>
+<p>You can report issue to <a href="https://github.com/apache/apisix/issues">APISIX</a></p>
+<p><em>Faithfully yours, <a href="https://apisix.apache.org/">APISIX</a>.</em></p>
+</body>
+</html>
diff --git a/t/error_page/error_page.t b/t/error_page/error_page.t
new file mode 100644
index 0000000..6f154c1
--- /dev/null
+++ b/t/error_page/error_page.t
@@ -0,0 +1,141 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+#
+use t::APISIX 'no_plan';
+
+log_level('debug');
+repeat_each(1);
+no_long_string();
+no_root_location();
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: set route with serverless-post-function plugin
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "serverless-post-function": {
+ "functions" : ["return function() if ngx.var.http_x_test_status ~= nil then;ngx.exit(tonumber(ngx.var.http_x_test_status));end;end"]
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/*"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+--- no_error_log
+[error]
+
+
+
+=== TEST 2: test apisix with internal error code 500
+--- request
+GET /hello
+--- more_headers
+X-Test-Status: 500
+--- error_code: 500
+--- response_body_like
+.*apisix.apache.org.*
+
+
+
+=== TEST 3: test apisix with internal error code 502
+--- request
+GET /hello
+--- more_headers
+X-Test-Status: 502
+--- error_code: 502
+--- response_body eval
+qr/502 Bad Gateway/
+
+
+
+=== TEST 4: test apisix with internal error code 503
+--- request
+GET /hello
+--- more_headers
+X-Test-Status: 503
+--- error_code: 503
+--- response_body eval
+qr/503 Service Temporarily Unavailable/
+
+
+
+=== TEST 5: test apisix with internal error code 504
+--- request
+GET /hello
+--- more_headers
+X-Test-Status: 504
+--- error_code: 504
+--- response_body eval
+qr/504 Gateway Time-out/
+
+
+
+=== TEST 6: test apisix with upstream error code 500
+--- request
+GET /specific_status
+--- more_headers
+X-Test-Upstream-Status: 500
+--- error_code: 500
+--- response_body
+upstream status: 500
+
+
+
+=== TEST 7: delete route(id: 1)
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, message = t('/apisix/admin/routes/1',
+ ngx.HTTP_DELETE,
+ nil,
+ [[{
+ "action": "delete"
+ }]]
+ )
+ ngx.say("[delete] code: ", code, " message: ", message)
+ }
+ }
+--- request
+GET /t
+--- response_body
+[delete] code: 200 message: passed
+--- no_error_log
+[error]
diff --git a/t/lib/server.lua b/t/lib/server.lua
index 5a1b454..984886e 100644
--- a/t/lib/server.lua
+++ b/t/lib/server.lua
@@ -103,6 +103,15 @@ function _M.plugin_proxy_rewrite_args()
end
+function _M.specific_status()
+ local status = ngx.var.http_x_test_upstream_status
+ if status ~= nil then
+ ngx.status = status
+ ngx.say("upstream status: ", status)
+ end
+end
+
+
function _M.status()
ngx.say("ok")
end
diff --git a/t/node/upstream-status-5xx.t b/t/node/upstream-status-5xx.t
index 7f42bec..c69b5cb 100644
--- a/t/node/upstream-status-5xx.t
+++ b/t/node/upstream-status-5xx.t
@@ -206,8 +206,8 @@ passed
--- request
GET /server_error
--- error_code: 500
---- response_body eval
-qr/500 Internal Server Error/
+--- response_body_like
+.*apisix.apache.org.*
--- error_log
X-APISIX-Upstream-Status: 500