Skip to content

refactor: refactor http middleware #166

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

Closed
wants to merge 10 commits into from
Closed

refactor: refactor http middleware #166

wants to merge 10 commits into from

Conversation

devhaozi
Copy link
Member

@devhaozi devhaozi commented Apr 9, 2025

📑 Description

Closes goravel/goravel#655

✅ Checks

  • Added test cases for my code

@devhaozi devhaozi requested a review from a team as a code owner April 9, 2025 21:55
Comment on lines +110 to +113
func (r *Route) NotAllowed(handler contractshttp.HandlerFunc) {
panic("not support")
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

goravel/framework#996 (comment) 所提到,fiber 目前不支持自定义。

Comment on lines +12 to +31
// nilHandler is a nil handler for global middleware to build chain.
var nilHandler contractshttp.HandlerFunc = func(ctx contractshttp.Context) error {
// TODO if use a fiber middleware as global middleware by type assert, they already call ctx.Next(),
// if duplicate call ctx.Next() will cause a error. Need to find a better way to handle this.
if ctx.Value("no_next") != nil {
// reset no_next flag for next global middleware
ctx.WithValue("no_next", nil)
return nil
}

fiberCtx := ctx.(*Context)
return fiberCtx.Instance().Next()
}

// invalidFiber instance.Context() will be nil when the request is timeout,
// the request will panic if ctx.Response() is called in this situation.
func invalidFiber(instance *fiber.Ctx) bool {
return instance.Context() == nil
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个空处理器是为了全局中间件构建处理器链(因为全局中间件没有路由处理器),但 fiber 有个特点是处理器需要调用Next来运行下一个处理器(全局中间件也一样,否则不会运行路由的处理器),所以就添加了fiberCtx.Instance().Next()调用。

这就导致一些比较 hacker 的用法(比如通过类型断言拿到 fiber 实例附加中间件)下,会重复调用Next,而 fiber 的设计如果调用Next时没有可用的处理器(所有处理器都用过了)的话会报错Cannot get xxx,这个用法框架内只在 cors 中间件用到,所以我添加了一个标志位来处理,如果有更好的优化方法可以评论讨论下。

Comment on lines +131 to +137
func (r *Group) getMiddlewares(handler httpcontract.HandlerFunc) fiber.Handler {
var middlewares []httpcontract.Middleware
middlewares = append(middlewares, r.originMiddlewares...)
middlewares = append(middlewares, r.middlewares...)
middlewares = append(middlewares, r.lastMiddlewares...)

return middlewares
return handlerToFiberHandler(middlewares, handler)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

重写了获取中间件的方法,现在会先聚合全部中间件,然后传给handlerToFiberHandler函数构建处理器链

Comment on lines +52 to 53
assert.Equal(t, contractshttp.StatusText(contractshttp.StatusRequestTimeout), string(body))
})
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

类似的几个测试修改得更加规范

Comment on lines +276 to +285
r.instance.Use(func(c *fiber.Ctx) error {
ctx := NewContext(c)
defer func() {
contextRequestPool.Put(ctx.request)
contextResponsePool.Put(ctx.response)
ctx.request = nil
ctx.response = nil
contextPool.Put(ctx)
}()
return r.fallback(ctx)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里之前的实现 bug,没有回收 Context 导致资源泄露

Comment on lines +294 to +298

// Interface guards
var (
_ route.Route = (*Route)(nil)
)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

新增了 go 常用的接口守卫,确保 Route 实现了route.Route 的所有接口,防止运行时 panic。

@devhaozi devhaozi closed this Apr 11, 2025
@devhaozi devhaozi deleted the haozi/middleware branch April 11, 2025 16:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant