ACL 这块后续有无考虑内置类似功能?
权限控制未来会通过社区模块的形式提供,不过目前暂无工作规划,欢迎大家贡献。
洋葱图上是不是应该加两个middleware描述.分别是在路由外层的global.Middleware及路由内层group.Middleware.
当客户端使用POST请求,并且有携带文件上传,比如
curl --location --request POST 'http://127.0.0.1:8080/api/tasks' --form 'file=@"/Users/test/Downloads/test.pdf"'
路由代码
func MiddlewareAuth(r *ghttp.Request) { r.Response.ClearBuffer() r.Response.WriteStatusExit(401,"哎哟我去,服务器居然开小差了,请稍后再试吧!") } func init() { s := g.Server() s.Group("/api", func(group *ghttp.RouterGroup) { group.Middleware(MiddlewareAuth) group.POST("/tasks", api.Task.Create) }) }
此时curl会返回 HTTP error before end of send, stop sending 错误
并且postman也是无法正常显示,提示错误
Could not get response,Error: write EPIPE
请问一下,现在我有多个中间件,如果前面的中间件需要抛出一个错误,后面的中间件能拦截到吗?
可以的,后面的中间件通过r.GetError可以获取前面的产生错误或者异常,中间件中也可以通过r.SetError来设置自定义的错误。
r.GetError
r.SetError
有拦截静态文件请求该如何实现?
静态资源使用HOOK
HOOK
郭强 中间件设置了httpStatus之后,为何response自动加上了 http 状态码的描述呢?
func (s *sMiddleware) ResponseHandler(r *ghttp.Request) { r.Middleware.Next() r.Response.Header().Set("Content-Type", "application/json;charset=utf-8") // 如果已经有返回内容,那么该中间件什么也不做 if r.Response.BufferLength() > 0 { return } var ( err error res interface{} code gcode.Code = gcode.CodeOK ) res, err = r.GetHandlerResponse() if err != nil { code = gerror.Code(err) if code == errorCode.CodeNil { code = errorCode.CodeInternalError } if detail, ok := code.Detail().(errorCode.MyCodeDetail); ok { r.Response.WriteStatus(detail.HttpCode) // 此处是 404 } response.JsonExit(r, code.Code(), err.Error()) // 此处code=65;Message="用户 uuid=1 不存在。";Data={} } else { response.JsonExit(r, code.Code(), "", res) } }
发起请求:curl -X 'GET' 'http://127.0.0.1:8199/user/1' -H 'accept: application/json' ,得到的response如下:
Not Found{"code":65,"message":"用户 uuid=1 不存在。","data":{}}
为什么多了 Not Found? 怎么去掉
r.Response.WriteStatus(detail.HttpCode 会往response 写数据
// WriteStatus writes HTTP `status` and `content` to the response. // Note that do not set Content-Type header here. func (r *Response) WriteStatus(status int, content ...interface{}) { r.WriteHeader(status) if len(content) > 0 { r.Write(content...) } else { r.Write(http.StatusText(status)) // 此处会写入404对应的字符串 } }
所以多了一个 response 会多了一个 “Not Found”
只需要在写入Status之后,把response 清空一下即可,完整代码如下:
// 返回处理中间件 func (s *sMiddleware) ResponseHandler(r *ghttp.Request) { r.Middleware.Next() // 如果已经有返回内容,那么该中间件什么也不做 if r.Response.BufferLength() > 0 { return } var ( err error res interface{} code gcode.Code = gcode.CodeOK ) res, err = r.GetHandlerResponse() if err != nil { code = gerror.Code(err) if code == errorCode.CodeNil { code = errorCode.CodeInternalError } // TODO: 修改http 状态码出问题 if detail, ok := code.Detail().(errorCode.MyCodeDetail); ok { r.Response.WriteStatus(detail.HttpCode) r.Response.ClearBuffer() // gf 会自动往response追加http.StatusText。此处不需要,所以删除掉。 } response.JsonExit(r, code.Code(), err.Error()) } else { response.JsonExit(r, code.Code(), "", res) } }
)
你有没有想过是你的问题呢?设置状态码不应该是改Header吗。你应该调用
r.WriteHeader(status)
就可以了。无需调用WriteStatus这个本来就是向浏览器输出状态内容的。你直接改header就可以了
郭强 middleware貌似不能return error。如文档上提到的同时存在MiddlewareAuth, MiddlewareErrorHandler,
group.Middleware(MiddlewareAuth, MiddlewareErrorHandler)
期望MiddlewareAuth校验失败,不再继续执行后续的业务功能代码,能否在MiddlewareAuth return error,然后在MiddlewareErrorHandler统一处理呢?
请问如何支持标准库的 http Handler 作为中间件使用?
郭强
支持这样的操作吗?因为很多时候可能需要直接使用标准库的 http.Handler
在中间件里可以修改HandlerResponse吗?
14 Comments
Yufan Sheng
ACL 这块后续有无考虑内置类似功能?
郭强
权限控制未来会通过社区模块的形式提供,不过目前暂无工作规划,欢迎大家贡献。
糖水不加糖
洋葱图上是不是应该加两个middleware描述.分别是在路由外层的global.Middleware及路由内层group.Middleware.
harry
当客户端使用POST请求,并且有携带文件上传,比如
curl --location --request POST 'http://127.0.0.1:8080/api/tasks' --form 'file=@"/Users/test/Downloads/test.pdf"'
路由代码
此时curl会返回 HTTP error before end of send, stop sending 错误
并且postman也是无法正常显示,提示错误
Could not get response,Error: write EPIPE
王一飞
请问一下,现在我有多个中间件,如果前面的中间件需要抛出一个错误,后面的中间件能拦截到吗?
郭强
可以的,后面的中间件通过
r.GetError
可以获取前面的产生错误或者异常,中间件中也可以通过r.SetError
来设置自定义的错误。yangyong
有拦截静态文件请求该如何实现?
郭强
静态资源使用
HOOK
白夜
郭强 中间件设置了httpStatus之后,为何response自动加上了 http 状态码的描述呢?
发起请求:curl -X 'GET' 'http://127.0.0.1:8199/user/1' -H 'accept: application/json' ,得到的response如下:
为什么多了 Not Found? 怎么去掉
白夜
r.Response.WriteStatus(detail.HttpCode 会往response 写数据
所以多了一个 response 会多了一个 “Not Found”
只需要在写入Status之后,把response 清空一下即可,完整代码如下:
)
langbin
你有没有想过是你的问题呢?设置状态码不应该是改Header吗。你应该调用
就可以了。无需调用WriteStatus这个本来就是向浏览器输出状态内容的。你直接改header就可以了
白夜
郭强 middleware貌似不能return error。如文档上提到的同时存在MiddlewareAuth, MiddlewareErrorHandler,
期望MiddlewareAuth校验失败,不再继续执行后续的业务功能代码,能否在MiddlewareAuth return error,然后在MiddlewareErrorHandler统一处理呢?
overbeck.jack
请问如何支持标准库的 http Handler 作为中间件使用?
郭强
支持这样的操作吗?因为很多时候可能需要直接使用标准库的 http.Handler
程建
在中间件里可以修改HandlerResponse吗?