Golang Go语言中遇到诡异的问题:字符串"突变"

发布于 1周前 作者 wuwangju 来自 Go语言

代码如下:

for k, value := range MetaMap {
	k = "Meta-" + k
	header.Set(k, value)
}

其中 header ==> http.Header{}, MetaMap ==> map[string]string 且只有一个键值对: Password: admin123 ,但是 Debug 发现 header 中却是 Meta_password ,而不是 Meta-Password 。有人遇到过这种问题吗

Debug 是在远程主机上运行的,本地和远端代码一模一样,本地通过 git push 到 GitHub ,远端直接 git pull ,且两端的编译命令相同,go 版本相同。本地却没有这样的问题。


Golang Go语言中遇到诡异的问题:字符串"突变"

更多关于Golang Go语言中遇到诡异的问题:字符串"突变"的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

17 回复

你远端是不是套网关了

更多关于Golang Go语言中遇到诡异的问题:字符串"突变"的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


没有,两端的配置文件一模一样,请求地址也一样,都是 Cloudflare ,而且情况是发生在发生请求前。应该和网关无关

既然是 cf ,那可以看下 cf 的 trace 吧,看看 cf 传的是啥

源站用 nginx ,根据 nginx"特性",默认会把 header 中含有"“过滤掉,造成后端收不到含有”"的 header 字段信息

cf 不会有问题的,有问题的话本地应该也请求失败才对

浏览器上看的头吗?有可能浏览器显示的是这样,实际上传输的就是小写和下划线。

我这个是客户端请求,没有使用浏览器,请求前看了 request 里的 header ,就是有问题的

这种 header 不规范,可能因为 nginx 的版本导致各种意想不到的差异,规范的做法是 X-USERNAME 。(虽然这个规范后来被废弃了,但是实际场景中还是有很多问题)

header 确实没有一个统一强有力的规范,首字母大小写的规范不一样,每段首字母大小写的规范也不一样,甚至用横杠 /下划线分隔多段的规范也不一样。

header.set 会经过 mime 标准化,就是会换成横杠的,不想被转换要用 header[k] = []string{v}

文档其实说的很清楚的
Set sets the header entries associated with key to the single element value. It replaces any existing values associated with key. The key is case insensitive; it is canonicalized by textproto.CanonicalMIMEHeaderKey. To use non-canonical keys, assign to the map directly.

// Set sets the header entries associated with key to the
// single element value. It replaces any existing values
// associated with key. The key is case insensitive; it is
// canonicalized by textproto.CanonicalMIMEHeaderKey.
// To use non-canonical keys, assign to the map directly.
func (h Header) Set(key, value string) {
textproto.MIMEHeader(h).Set(key, value)
}

我的意思是 key 是横杠,设置 header 后 header 里面变成下划线。

spring 里面用 spring 工具取 header 时,不区分大小写,-或_都能取出来

没错啊我也是这个意思,这就是设置的方法的文档里面说了,代码里面也可以看

还是没懂我的意思,我知道 set 函数会自动格式化 key ,但是我这里的 key 进去是横杠,set 之后变成了下划线,难道函数有这样的实现吗

网关是真的搞,有次把我们的 sql 改了;查了小半周

在Go语言中遇到字符串“突变”这类诡异问题时,通常需要从几个方面来排查和定位问题。

首先,确认字符串的编码方式。Go语言默认使用UTF-8编码,如果字符串在其他地方(如文件、数据库或网络传输中)使用了不同的编码,可能会导致显示异常。使用[]byte转换和检查原始字节数据,可以帮助确认编码问题。

其次,检查字符串的赋值和传递过程。确保在传递和修改字符串时,没有发生意外的内存覆盖或指针错误。在Go中,字符串是不可变的,但通过指针或其他引用类型间接修改底层数据,可能会导致不可预期的行为。

再者,考虑并发访问的问题。如果在多个goroutine中共享和修改字符串,而没有适当的同步机制,可能会导致数据竞争和“突变”现象。使用sync包中的工具或channel来确保并发安全。

最后,检查是否有外部库或依赖引入了不兼容的修改。有时候,第三方库中的bug或更新可能会导致字符串处理异常。查阅相关库的文档和更新日志,或者尝试更新/替换库,可能有助于解决问题。

如果以上方法都不能解决问题,建议编写一个简单的测试用例,逐步复现问题,并使用调试工具(如Delve)来跟踪和检查字符串的状态变化。通过这种方法,通常可以定位到问题的根源。

回到顶部