Skip to content

Commit

Permalink
refine
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangnanscu committed Dec 4, 2024
1 parent 7b93920 commit e0c2426
Show file tree
Hide file tree
Showing 6 changed files with 342 additions and 131 deletions.
75 changes: 57 additions & 18 deletions app.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,35 @@ local Router = require('resty.router')

local router = Router:new()

-- 测试插件
router:use(function(ctx)
ctx.plugin_executed = true
ctx:yield()
end)
local success_cnt = 0
local error_cnt = 0


-- 测试事件
router:on('success', function(ctx)
-- ngx.log(ngx.INFO, "请求成功")
success_cnt = success_cnt + 1
end)

router:on('error', function(ctx)
-- ngx.log(ngx.INFO, "请求失败")
error_cnt = error_cnt + 1
end)

-- 测试插件
router:use(function(ctx)
ctx.success_cnt = success_cnt
ctx.error_cnt = error_cnt
end)

-- 1. 测试静态路径
router:get("/hello", function()
return "Hello World"
end)

-- 测试自定义成功状态码
router:get("/hello-201", function()
return "Hello World", 201
end)

-- 2. 测试JSON响应
router:get("/json", function()
return { message = "success", code = 0 }
Expand All @@ -31,32 +40,30 @@ end)
router:get("/users/#id", function(ctx)
return {
id = ctx.params.id,
type = "number"
type = type(ctx.params.id)
}
end)

router:get("/users/:name", function(ctx)
return {
name = ctx.params.name,
type = "string"
type = type(ctx.params.name)
}
end)

-- 4. 测试正则路径
router:get("/version/<ver>\\d+\\.\\d+", function(ctx)
router:get([[/version/<ver>\d+\.\d+]], function(ctx)
return {
version = ctx.params.ver
}
end)

-- 5. 测试通配符
router:get("/files/*path", function(ctx)
return {
path = ctx.params.path
}
return ctx.params.path
end)

-- 6. 测试多个HTTP方法
-- 6. 测试其他HTTP方法
router:post("/accounts", function(ctx)
return { method = "POST" }
end)
Expand All @@ -70,6 +77,21 @@ router:get("/error", function()
error("测试错误")
end)

-- 测试error抛出的自定义错误
router:get("/custom-error", function()
error({ code = 400, message = "自定义错误" })
end)

-- 测试return nil, err, code形式的错误
router:get("/return-error", function()
return nil, "参数错误", 402
end)

-- 测试handled error
router:get("/handled-error", function()
error { "handled error" }
end)

-- 8. 测试状态码
router:get("/404", function()
return nil, "Not Found", 404
Expand All @@ -79,13 +101,30 @@ end)
router:get("/html", function()
return "<h1>Hello HTML</h1>"
end)
-- 测试html错误
router:get("/html-error", function()
return nil, "<h1>Hello HTML error</h1>", 501
end)
-- 测试error抛出的html错误
router:get("/html-error2", function()
error { "<h1>Hello HTML error2</h1>" }
end)

-- 10. 测试函数返回
router:get("/func", function()
router:get("/func", function(ctx)
return function()
ngx.say("function called")
return true
ngx.header.content_type = 'text/plain; charset=utf-8'
ngx.say("function called2")
end
end)
ngx.log(ngx.ERR, require("resty.repr")(router))

-- 11. 查看events是否正常执行
router:get("/events", function(ctx)
return {
success_cnt = ctx.success_cnt,
error_cnt = ctx.error_cnt
}
end)

-- ngx.log(ngx.ERR, require("resty.repr")(router))
return router
2 changes: 1 addition & 1 deletion conf/nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ events {
}

http {
default_type application/json;
default_type text/plain;
access_log logs/access.log;

lua_package_path './lib/?.lua;;';
Expand Down
114 changes: 77 additions & 37 deletions lib/resty/router.lua
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,6 @@ end
---@param path string
---@param method string
---@return boolean
---@overload fun(string, string): boolean
function Router:dispatch(path, method)
-- before plugins
local ctx = self:create_context()
Expand All @@ -412,13 +411,13 @@ function Router:dispatch(path, method)
-- match route
local handler, params_or_code = self:match(path, method)
if handler == nil then
return self:fail(ctx, 'match route failed', params_or_code)
return self:echo(ctx, 'match route failed', params_or_code --[[@as number]])
end
if params_or_code then
ctx.params = params_or_code
end
if type(handler) == 'string' then
return self:ok(ctx, handler)
return self:echo(ctx, handler, 200)
else
---@diagnostic disable-next-line: param-type-mismatch
local ok, result, err_or_okcode, errcode = xpcall(handler, trace_back, ctx)
Expand All @@ -429,53 +428,94 @@ function Router:dispatch(path, method)
return self:fail(ctx, err_or_okcode, errcode)
elseif rawget(ctx, 'response') then
local code = ctx.response.status or 200
return self:finish(ctx, code, ngx.exit, code)
return self:finish(ctx, code, ngx.exit, 0)
else
return self:fail(ctx, 'no response')
return self:echo(ctx, 'no response', 500)
end
elseif type(result) ~= 'function' then
return self:echo(ctx, result, err_or_okcode or 200)
else
local resp_type = type(result)
if resp_type == 'table' or resp_type == 'boolean' or resp_type == 'number' then
local response_json, encode_err = encode(result)
if not response_json then
return self:fail(ctx, encode_err)
else
ngx_header.content_type = 'application/json; charset=utf-8'
return self:ok(ctx, response_json, err_or_okcode)
end
elseif resp_type == 'string' then
if byte(result) == 60 then -- 60 is ASCII value of '<'
ngx_header.content_type = 'text/html; charset=utf-8'
else
ngx_header.content_type = 'text/plain; charset=utf-8'
end
return self:ok(ctx, result, err_or_okcode)
elseif type(result) == 'function' then
ok, result, err_or_okcode, errcode = xpcall(result, trace_back, ctx)
if not ok then
return self:fail(ctx, result)
elseif result == nil then
return self:finish(ctx, 500, ngx.exit, 500)
else
return self:finish(ctx, 200, ngx.exit, 200)
end
ok, result = xpcall(result, trace_back, ctx)
if not ok then
return self:fail(ctx, result)
else
return self:fail(ctx, 'invalid response type: ' .. resp_type)
return self:finish(ctx, 200, ngx.exit, 0)
end
end
end
end

function Router:ok(ctx, body, code)
ngx_print(body)
code = code or 200
return self:finish(ctx, code, ngx.exit, code)
---success response
---@param ctx table request context
---@param body string response body
---@param code number response code
---@return unknown
function Router:echo(ctx, body, code)
ngx.status = code
local res, err = self:print(body)
if res == nil then
return self:fail(ctx, err)
else
return self:finish(ctx, code, ngx.exit, 0)
end
end

---failed response
---@param ctx table request context
---@param err string|table error message
---@param code? number error code
---@return unknown
function Router:fail(ctx, err, code)
ngx_print(err)
code = code or 500
return self:finish(ctx, code, ngx.exit, code)
ngx.status = code
self:print_error(err)
return self:finish(ctx, code, ngx.exit, 0)
end

function Router:print(body)
if type(body) == 'string' then
if not ngx_header.content_type then
if byte(body) == 60 then -- 60 is ASCII value of '<'
ngx_header.content_type = 'text/html; charset=utf-8'
else
ngx_header.content_type = 'text/plain; charset=utf-8'
end
end
return ngx_print(body)
elseif type(body) == 'number' or type(body) == 'boolean' then
if not ngx_header.content_type then
ngx_header.content_type = 'application/json; charset=utf-8'
end
local t, e = encode(body)
if t then
return ngx_print(t)
else
return nil, e
end
elseif type(body) == 'table' then
if not ngx_header.content_type then
ngx_header.content_type = 'application/json; charset=utf-8'
end
local t, e = encode(body)
if t then
return ngx_print(t)
else
return nil, e
end
else
return nil, 'invalid response type: ' .. type(body)
end
end

function Router:print_error(body)
if type(body) == 'table' and #body == 1 and type(body[1]) == 'string' then
if not ngx_header.content_type then
ngx_header.content_type = 'text/plain; charset=utf-8'
end
return ngx_print(body[1])
else
return self:print(body)
end
end

function Router:redirect(ctx, uri, code)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"prepublishOnly": "pnpm build",
"prepublishOnly2": "zx ./scripts/prepublish.mjs",
"nginx": "nginx -p . -c conf/nginx.conf",
"test": "yarn nginx; ./test.sh ; yarn nginx -s stop"
"test": "mv logs/error.log; yarn nginx -s stop;yarn nginx; ./test.py ; yarn nginx -s stop"
},
"author": "",
"license": "ISC",
Expand Down
Loading

0 comments on commit e0c2426

Please sign in to comment.