-
Notifications
You must be signed in to change notification settings - Fork 2.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
help request: How to create a custom-404-redirect plugin? #12023
Comments
This comment has been minimized.
This comment has been minimized.
I slightly changed your plugin, by removing I tested it with the example below, using external service httpbin.org, and it seems to be working. Can you have a look and provide a feedback? ExampleFile Structure
File SourcesFile apisix:
extra_lua_path: "/usr/local/apisix/apisix/plugins/custom/?.lua"
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
plugins:
- custom-404-redirect
#END File upstreams:
- id: external_httpbin
nodes:
"httpbin.org": 1
scheme: https
routes:
- id: 1
uri: /anything
upstream_id: external_httpbin
- id: 2
uris:
- /shop/products/*
upstream_id: external_httpbin
plugins:
custom-404-redirect:
redirect_url: /anything
#END File local core = require("apisix.core")
local ngx = ngx
local plugin_name = "custom-404-redirect"
local schema = {
type = "object",
properties = {
redirect_url = { type = "string", minLength = 1 }
},
required = { "redirect_url" }
}
local _M = {
version = 0.1,
priority = 1010, -- set the plugin priority, higher means earlier execution
name = plugin_name,
schema = schema
}
function _M.check_schema(conf)
return core.schema.check(schema, conf)
end
function _M.header_filter(conf, ctx)
if ngx.status == 404 then
ngx.status = ngx.HTTP_MOVED_TEMPORARILY
ngx.header["Location"] = conf.redirect_url
core.log.warn("Redirecting to custom 404 page: " .. conf.redirect_url)
-- ngx.exit(ngx.HTTP_MOVED_TEMPORARILY) -- Comment/remove this line
end
end
File compose.yaml:
services:
apisix:
container_name: apisix-test-redirect
image: apache/apisix:latest
restart: no
stdin_open: true
tty: true
environment:
- APISIX_STAND_ALONE=true
volumes:
- ./conf/config.yaml:/usr/local/apisix/conf/config.yaml
- ./conf/apisix.yaml:/usr/local/apisix/conf/apisix.yaml
- ./plugins:/usr/local/apisix/apisix/plugins/custom/apisix/plugins
ports:
- "9080:9080/tcp"
- "9443:9443/tcp" TestingSetupRun the following: docker compose up Testing the RouteRun the following: curl -sL localhost:9080/shop/products/test -i Result: HTTP/1.1 302 Moved Temporarily
Content-Type: text/html
Content-Length: 233
Connection: keep-alive
Date: Mon, 17 Mar 2025 16:58:54 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.11.0
Location: /anything
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 388
Connection: keep-alive
Date: Mon, 17 Mar 2025 16:58:55 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Server: APISIX/3.11.0
{
"args": {},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Host": "localhost",
"User-Agent": "curl/8.5.0",
"X-Amzn-Trace-Id": "Root=1-67d854ce-0853fc4a1447023a613f0439",
"X-Forwarded-Host": "localhost"
},
"json": null,
"method": "GET",
"origin": "172.X.X.X, 89.X.X.X",
"url": "https://localhost/anything"
} |
@mikyll Thanks for the help. Now it seems to be working, however I have a weird issue. I applied this to a route called "/shop/*". So when I go to a page like "/shop/invalid-product" I get proper 404 page as expected. However if I go to a valid page "/shop/valid-product", then this page makes some asset calls(css, js, ajax etc). Lets assume one such call is "/shop/price/...". Lets also assume that this endpoint throws a 404, but because we have a custom plugin its returning a 404 but with custom html body(the 404 url that we gave) and as a result that 404 page is being embedded into my main "/shop/valid-product" page. Is there a way to apply this to only the main endpoint which I am hitting from the browser? That is if I go "google.com", this should apply only to that endpoint and not for any ajax/css/js(etc) calls that happen on that page? |
Description
I want to create a plugin where if upstream status is 404, I will be able to specify a custom 404 page and it should go there.
So this is what I have so far.
My apisix configuration for route
And my plugin code is as shown below
But this is not working and simply throwing a 500 status code instead of going to a 404 as expected. Is it not possible to do it via plugin?
Note: I found below links but they are still open or dont work
Note: I also opened another issue asking if apisix has a built-in plugin but someone commented saying that we can use custom plugin to do so: #12007. Hence I am creating this issue since I am stuck at creating a custom plugin for this usecase.
Environment
apisix version
): 3.10.0-debianuname -a
): UbuntuThe text was updated successfully, but these errors were encountered: