我想让我的应用程序在下面提供服务。
我制作了如下代码:
package main
import "github.com/gin-gonic/gin"
func main() {
r := gin.Default()
r.Static("/", "/www")
apiv1 := r.Group("api/v1")
{
apiv1.GET("/disk", diskSpaceHandler)
apiv1.GET("/memory", memoryHandler)
apiv1.GET("/cpu", cpuHandler)
}
r.Run(":80")
}
当我运行代码时,它会发生恐慌:
panic: path segment '/api/v1/disk' conflicts with existing wildcard '/*filepath' in path '/api/v1/disk'
我理解为什么会发生恐慌,但我不知道如何解决。
我脑海里浮现出两件事:
提前谢谢。
答案 0 :(得分:0)
您应该使用静态中间件,请参见其示例:
https://github.com/gin-contrib/static#canonical-example
r.Use(static.Serve("/", static.LocalFile("/tmp", false)))
答案 1 :(得分:0)
为静态文件路径添加唯一前缀:r.Static("/static", "/www")
。
正如@chespinoza 的评论所提到的,这是 Gin 底层路由器实现 github.com/julienschmidt/httprouter
的一个 feature(不是错误)。路由是基于前缀而不是整个路由来匹配的,因此任何路径参数和通配符在同一位置与另一个路径段都会导致冲突。
例如下面会发生冲突,因为两个路径参数都是root之后的第一个路径段:
/:foo/something
/:bar/blah
给定路线 /myroute/something
,第一段 /myroute
与 /:foo
和 /:bar
均匹配,而与第二段无关。
现在,方法 RouterGroup.Static
“从给定的文件系统根目录提供文件”,特别是它的实现使用了 path.Join(relativePath, "/*filepath")
。
在您的代码 r.Static("/", "/www")
中,relativePath
是 /
,因此静态文件路由变成了 /*filepath
。这是一个从 root 开始的路径通配符,因此它将与所有路由冲突,除非它是您服务器中的唯一路由。
解决这个问题的方法是给你的静态文件路径添加一个唯一的前缀,这样就不会在相同的位置出现路径参数或通配符,例如:
r.Static("/static", "/www")
导致以下路由(省略处理程序),通配符仅出现在 /static
之后:
[GIN-debug] GET /static/*filepath
[GIN-debug] HEAD /static/*filepath
[GIN-debug] GET /api/v1/disk
[GIN-debug] GET /api/v1/memory
[GIN-debug] GET /api/v1/cpu