Loading [MathJax]/jax/input/TeX/jax.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Go 1.22 对 net/http.ServeMux 多路复用器新增两个增强功能

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

作者头像
frank.
发布于 2024-03-21 08:03:43
发布于 2024-03-21 08:03:43
76700
代码可运行
举报
运行总次数:0
代码可运行

01

介绍

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

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

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

02

路由模式

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

[METHOD ][HOST]/[PATH]

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

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

示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

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

特殊通配符 {Extra close brace or missing open brace} 仅匹配路径 /,而路由模式 / 匹配任意路径。

为了进行匹配,路由模式的路径和传入请求路径都是逐段未转义的。比如路径 /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 删除。

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

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Go1.22来了!还需要HTTP框架吗?
在Go语言原生的HTTP路由中大家是否注意到过功能不是很完善,比如需要硬编码区分GET还是POST请求,在Go 1.22中对Go的HTTP路由做了一定程度的增强,这都要源于一个提案:net/http: enhanced ServeMux routing(https://github.com/golang/go/issues/61410)
闫同学
2024/04/24
2170
Go 1.22中的路由提升
Go 1.22对net/http包的路由进行了两项增强:方法匹配和通配符。这些功能允许你将常见的路由表示为模式,而不是Go代码。尽管它们很容易解释和使用,但在选择多个匹配请求的模式时,确定胜出的模式的规则是一个挑战。
孟斯特
2024/02/21
3240
Go 1.22中的路由提升
Go 1.22 相比 Go 1.21 有哪些值得注意的改动?
Go 1.22 对 for 循环进行了两项重要的改进:循环变量的语义变更和对整数的 range 支持。
Piper破壳
2025/05/05
840
[Introduction]万字手撕Go http源码server.go
从路由注册到监听本地端口后请求路由的一系列动作的分析,基本上仅限于net/http server.go这个包文件的路由相关部分解读
Wzy_CC
2020/08/28
1.3K0
【Golang那些事】go1.22和1.23 更新重点及测评
好久没有写文章了,攒了一年的Golang版本特性的技术点以及踩过的坑,那就在新年第一篇的文章中做一个总结吧:
粲然忧生
2025/01/18
6470
【Golang那些事】go1.22和1.23 更新重点及测评
Go 源码学习之--net/http
其实自己不是很会看源码,但是学习优秀的源码是提升自己代码能力的一种方式,也可以对自己以后写代码有一个很好的影响,所以决定在之后的时间内,要有一个很好的习惯,阅读优秀的源码。刚开始自己会觉得看源码很痛苦,这个和我自己的方法有关系,刚开始自己总是想要知道源码的每一步操作,以及每个部分都是做什么,导致看着看着就看不下去了,所以也是从这次整理开始,调整自己阅读源码的方式,先去源码框架的主要流程,细枝末节后面等对整体框架有个了解,并且很清晰了,再回头来细致看,所以阅读过程中如果有不理解的地方自己先进行跳过,先对主体的
coders
2018/03/30
1.8K0
Go 源码学习之--net/http
深入理解Go标准库-ServeMux的使用与模式匹配
‍‍根据 Golang 文档 中的介绍,ServeMux是一个 HTTP 请求多路复用器(HTTP Request multiplexer)。它按照一定规则匹配请求URL和已注册的模式,并执行其中最匹配的模式的Handler
KevinYan
2023/12/13
6370
深入理解Go标准库-ServeMux的使用与模式匹配
图文吃透Golang net/http 标准库--服务端
今天分享下Go语言net/http标准库的实现逻辑,文章将从客户端(Client)--服务端(Server)两个方向作为切入点,进而一步步分析http标准库内部是如何运作的。
小许code
2024/01/29
6730
图文吃透Golang net/http 标准库--服务端
Go 语言 Web 编程系列(三)—— 基于官方标准库自定义路由处理器
我们在上篇教程介绍过这段代码的底层实现,这里 http.ListenAndServe 方法第二个参数传入的是 nil,表示底层会使用默认的 DefaultServeMux 实现将上述 HandleFunc 方法传入的处理函数转化为基于闭包方式定义的路由:
学院君
2019/12/20
9710
Go 语言 Web 编程系列(三)—— 基于官方标准库自定义路由处理器
Go语言经典库使用分析(七)| 高性能可扩展 HTTP 路由 httprouter
Go语言(golang)的一个很大的优势,就是很容易的开发出网络后台服务,而且性能快,效率高。在开发后端HTTP网络应用服务的时候,我们需要处理很多HTTP的请求访问,比如常见的API服务,我们就要处理很多HTTP请求,然后把处理的信息返回给使用者。对于这类需求,Golang提供了内置的net/http包帮我们来处理这些HTTP请求,让我们可以比较方便的开发一个HTTP服务。
飞雪无情
2020/02/10
1.2K0
Go web之旅(路由篇)
据说Go语言设计出来就是为了解决web软件的并发等诸多问题的,所以Go语言又被称为互联网中的c语言。一般的web应用采用的是"请求-响应"模式。在Go web中数据请求与数据返回相当于是基于"请求-响应"模式的web程序的输入输出。而其中数据在不同地方或者叫层次上有不同的表现形式,在客户端上数据一般采用字符串形式体现,而在后台数据一般体现为结构体或对象,这中间的转换需要相应的工具。 用servlet/jsp直接开发过Java web程序的同学应该知道,在整个架构中必不可少的元素有web容器,web.x
李海彬
2018/03/19
1.2K0
Go 每日一库之 net/http(基础和中间件)
几乎所有的编程语言都以Hello World作为入门程序的示例,其中有一部分以编写一个 Web 服务器作为实战案例的开始。每种编程语言都有很多用于编写 Web 服务器的库,或以标准库,或通过第三方库的方式提供。Go 语言也不例外。本文及后续的文章就去探索 Go 语言中的各个Web 编程框架,它们的基本使用,阅读它们的源码,比较它们优缺点。让我们先从 Go 语言的标准库net/http开始。标准库net/http让编写 Web 服务器的工作变得非常简单。我们一起探索如何使用net/http库实现一些常见的功能或模块,了解这些对我们学习其他的库或框架将会很有帮助。
用户7731323
2021/07/23
1.3K0
「Go工具箱」一文读懂主流web框架中路由的实现原理
大家好,我是渔夫子。本号新推出「Go工具箱」系列,意在给大家分享使用go语言编写的、实用的、好玩的工具。同时了解其底层的实现原理,以便更深入地了解Go语言。
Go学堂
2023/01/31
8210
Go 1.22 is released!
Go 1.22 带来了一系列重要的新功能和提升。以下是一些值得注意的变化;有关完整列表,请参阅发布[3]说明。
孟斯特
2024/02/21
3160
Go 1.22 is released!
Golang:深入理解http服务开发原理
http 是典型的 C/S 架构,客户端向服务端发送请求(request),服务端做出应答(response)。
公号:咻咻ing
2019/10/22
1.7K0
go net/http标准库源码
可以看到 Go 实现的http服务步骤非常简单,首先注册路由,然后创建服务并开启监听即可。
leobhao
2024/04/01
1510
深入学习用Go编写HTTP服务器
Go是一门通用的编程语言,想要学习 Go 语言的 Web 开发,就必须知道如何用 Go 启动一个 HTTP 服务器用于接收和响应来自客户端的 HTTP 请求。用 Go实现一个http server非常容易,Go 语言标准库net/http自带了一系列结构和方法来帮助开发者简化 HTTP 服务开发的相关流程。因此,我们不需要依赖任何第三方组件就能构建并启动一个高并发的 HTTP 服务器。这篇文章会学习如何用net/http自己编写实现一个HTTP Serverk并探究其实现原理,以此来学习了解网络编程的常见范式以及设计思路。
KevinYan
2020/02/17
2.5K0
深入学习用Go编写HTTP服务器
package http
要管理代理、TLS配置、keep-alive、压缩和其他设置,创建一个Transport:
李海彬
2018/07/26
4K0
package http
Go之Http包的服务端介绍
对于go的net/http包,主要分为两个部分,一部分是针对客户端的,一部分是针对服务端的,本篇文章主要介绍服务端这部分内容。
灰子学技术
2021/05/06
5100
Golang构建HTTP服务(一)--- net/http库源码笔记
实现一个最简单HTTP server需要多少代码?只需要一行,Python2的python -m SimpleHTTPServer,ruby的ruby -run -e httpd . -p 8888。对于Golang,实现一个最简单的http server也用不着几行,却能带来更具杀伤力的性能。 一个Go最简单的http服务器: package main import ( "fmt" "net/http" ) func IndexHandler(w http.ResponseWriter
李海彬
2018/03/19
1.9K0
Golang构建HTTP服务(一)--- net/http库源码笔记
相关推荐
Go1.22来了!还需要HTTP框架吗?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档