前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Go 1.22 对 net/http.ServeMux 多路复用器新增两个增强功能

Go 1.22 对 net/http.ServeMux 多路复用器新增两个增强功能

作者头像
frank.
发布2024-03-21 16:03:43
1790
发布2024-03-21 16:03:43
举报

01

介绍

在 Go 1.22 中,标准库 net/http`ServeMux` 路由模式增强[1],可以区分 HTTP 请求方法和支持通配符。

ServeMux 是一个 HTTP 请求多路复用器。它将每个传入请求的 URL 与已注册路由模式列表进行匹配,并调用与 URL 最匹配的路由模式的处理器。

本文我们介绍路由模式增强的多路复用器 ServeMux 的使用方式。

02

路由模式

路由模式可以匹配请求方法、请求 HOST 和请求路径,路由模式的格式如下:

[METHOD ][HOST]/[PATH]

三个部分都是可选的,如果路由模式中存在 METHOD,它的后面必须有一个空格。

限定 HTTP 请求方法的路由模式

示例代码:

代码语言:javascript
复制
func main() {
 // 使用 GET 方法注册处理器函数
 mux := http.NewServeMux()
 mux.HandleFunc("GET /goods/", func(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "iPhone")
 })
 // 创建 HTTP 服务器
 server := http.Server{
  Handler: mux,
 }
 log.Fatal(server.ListenAndServe())
}

阅读上面这段代码,我们可以发现路由模式参数的字符串中包含 GET HTTP 请求方法。

GET /goods/ 匹配请求路径以 /goods/ 开头的 GET 请求。

没有请求方法的路由模式与每个请求方法匹配。具有 GET 方法的请求模式同时匹配 GETHEAD 请求。

需要注意的是,其它请求方法必须完全匹配。

限定请求 HOST 的路由模式

没有 HOST 的路由模式,与任意 HOST 上的 URL 匹配。

具有 HOST 的路由模式,仅与该 HOST 上的 URL 匹配。

比如 example.com/ 匹配对 HOST example.com 的任何请求。

example.com/{$} 匹配对 HOST example.com 和路径 / 的请求,即 example.com/

通配符的路由模式

请求路径可以包含格式为 {NAME}{NAME...} 的通配符段。例如,/b/{bucket}/o/{objectname...}

通配符名称必须是有效的 Go 标识符。通配符必须是完整路径段:它们前面必须有一个斜杠,后面必须有一个斜杠或字符串的末尾。例如,/{bucket}//{bucket}/name 是有效的路由模式,而 /b_{bucket} 不是有效的路由模式。

通常,通配符仅匹配单个路径段,以请求 URL 中的下一个文字斜杠 /(而不是 %2F)结尾。但是,如果存在 ...,例如 {NAME...},则通配符与 URL 路径的其余部分(包括斜杠)匹配。

因此,对于存在 ... 的通配符,它出现在除路由模式末尾以外的任何位置,都不是有效的路由模式,例如 /b/{bucket}/o/{objectname...}/name 不是有效的路由模式。

可以通过使用 Request.PathValue(bucket) 调用通配符的名称,来获取通配符的匹配项。

需要注意的是,除了新增 PathValue,还新增了 SetPathValue

路径中的尾部斜杠,充当匿名的通配符 ...

特殊通配符 {} 仅与 URL 的末尾匹配。例如,路由模式 /{} 仅匹配路径 /,而路由模式 / 匹配任意路径。

为了进行匹配,路由模式的路径和传入请求路径都是逐段未转义的。比如路径 /a%2Fb/100%25 被视为具有两个路径段,a/b100%。路由模式 /a%2fb/ 匹配它,但路由模式 /a/b/ 不匹配。

03

优先级

如果两个或多个路由模式与一个请求匹配,则以最具体的路由模式为准。

如果 P1 与 P2 请求的严格子集匹配,也就是如果 P2 与 P1 的所有请求匹配,甚至更多,则路由模式 P1 比 P2 更具体。如果两者都不是更具体的,则路由模式会冲突。

对于向后兼容性,此规则有一个例外:如果两个路由模式会发生冲突,并且一个路由模式具有 HOST,而另一个路由模式没有,则具有 HOST 的路由模式优先级更高。

如果传递了 ServeMux.HandleServeMux.HandleFunc 的路由模式与已注册的另一个路由模式冲突,则这些函数会崩溃。

比如 /images/thumbnails//images/ 更具体,因此两者都可以注册。前者匹配以 /images/thumbnails/ 开头的路径,后者将匹配 /images/ 子树中的任何其他路径。前者的优先级高于后者。

再比如路由模式 GET //index.html:两者都匹配 /index.htmlGET 请求,但前者匹配所有其他 GETHEAD 请求,而后者匹配使用不同请求方法的任何 /index.html 请求。因为两者都不是更具体的路由模式,所以两者冲突。

04

兼容性

在 Go 1.22 中,ServeMux 的路由模式语法和匹配行为发生了重大变化。若要还原旧行为,请将 GODEBUG 环境变量设置为 httpmuxgo121=1。此设置在程序启动时读取一次,在程序执行期间更改此设置,不会直接生效。

向后不兼容的更改包括:

  • 通配符只是 1.21 中的普通文字路径段。例如,模式 /{x} 将仅匹配 1.21 中的该路径,但将匹配 1.22 中的任何单段路径。
  • 在 1.21 中,没有路由模式被拒绝,除非它是空的或与现有路由模式冲突。在 1.22 中,语法无效的路由模式将导致 ServeMux.HandleServeMux.HandleFunc 程序崩溃。例如,在 1.21 中,路由模式 /{/a{x} 匹配它们自己,但在 1.22 中,它们是无效的,路由模式注册时会引发 panic。
  • 在 1.22 中,路由模式的每个段都是未转义的,这在 1.21 中没有完成。例如,在 1.22 中,路由模式 %61 与路径 /a 匹配(%61a 的 URL 转义序列),但在 1.21 中,它只会匹配路径 /%2561(其中 %25 是百分号的转义)。
  • 当将路由模式与路径匹配时,在 1.22 中,路径的每一段都是未转义的;在 1.21 中,整个路径都是未转义的。此更改主要影响如何处理与斜杠相邻的 `%2F` 转义路径[2]

05

总结

本文我们介绍 Go 1.22 对 ServeMux 新增的两个增强功能:

  • 根据 HTTP 请求方法(GET、POST 等)区分请求。
  • 在匹配路径中支持通配符。

感兴趣的读者朋友们,可以阅读参考资料中的链接地址,了解更多。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-03-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言开发栈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档