内容简介:最近的项目从golang0.9升级到golang1.13后,项目中出现了很特殊的现象,在APP里,用户登录后访问页面正常,用户不登录,报错。大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)
起因
最近的项目从golang0.9升级到golang1.13后,项目中出现了很特殊的现象,在APP里,用户登录后访问页面正常,用户不登录,报错。
处理过程
-
Charles抓包发现,登录的情况下,服务返回的是protobuf的数据,未登录情况下返回的是json结构。服务是根据cookie中传入的数据来返回对应的数据类型。初步断定未登录情况下无法获取到cookie
-
检查登录和未登录情况下cookie的区别。
- 登录: serviceToken=abc ;type=protobuf;session=123
- 未登录:;type=protobuf;session=123
serviceToken是登录后的验证信息,用户如果未登录,数据不存在,但是分号却存在。初步怀疑是golang版本引起
-
在代码不变的情况下,使用不同golang版本生成服务,使用脚本进行测试
<?php $url = "http://10.220.130.8:8081/in/app/sync"; //$url = "http://in-go.buy.mi.com/in/app/sync"; $cookie = "; xmuuid=XMGUEST-FCF117BF-4D1B-272F-829D-25E19826D4F8;type=protobuf"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_COOKIE, $cookie); $output = curl_exec($ch); curl_close($ch); var_dump($output,11) ;
确定是golang版本问题
-
查看源码,在net/http/cookie.go中,可以看到
- golang1.12将cookie直接做了分割strings.Split(strings.TrimSpace(line), ";"),所以无论分号在什么位置都能解析出来
- 在golang1.13中 if splitIndex := strings.Index(line, ";"); splitIndex > 0 ,使用这种切割方式,如果引号位于第一个,整个获取过程便结束了,无法获得正确的cookie值
golang1.12
// readCookies parses all "Cookie" values from the header h and // returns the successfully parsed Cookies. // // if filter isn't empty, only cookies of that name are returned func readCookies(h Header, filter string) []*Cookie { lines, ok := h["Cookie"] if !ok { return []*Cookie{} } cookies := []*Cookie{} for _, line := range lines { parts := strings.Split(strings.TrimSpace(line), ";") if len(parts) == 1 && parts[0] == "" { continue } // Per-line attributes for i := 0; i < len(parts); i++ { parts[i] = strings.TrimSpace(parts[i]) if len(parts[i]) == 0 { continue } name, val := parts[i], "" if j := strings.Index(name, "="); j >= 0 { name, val = name[:j], name[j+1:] } if !isCookieNameValid(name) { continue } if filter != "" && filter != name { continue } val, ok := parseCookieValue(val, true) if !ok { continue } cookies = append(cookies, &Cookie{Name: name, Value: val}) } } return cookies }
golang1.13
// readCookies parses all "Cookie" values from the header h and // returns the successfully parsed Cookies. // // if filter isn't empty, only cookies of that name are returned func readCookies(h Header, filter string) []*Cookie { lines := h["Cookie"] if len(lines) == 0 { return []*Cookie{} } cookies := make([]*Cookie, 0, len(lines)+strings.Count(lines[0], ";")) for _, line := range lines { line = strings.TrimSpace(line) var part string for len(line) > 0 { // continue since we have rest if splitIndex := strings.Index(line, ";"); splitIndex > 0 { part, line = line[:splitIndex], line[splitIndex+1:] } else { part, line = line, "" } part = strings.TrimSpace(part) if len(part) == 0 { continue } name, val := part, "" if j := strings.Index(part, "="); j >= 0 { name, val = name[:j], name[j+1:] } if !isCookieNameValid(name) { continue } if filter != "" && filter != name { continue } val, ok := parseCookieValue(val, true) if !ok { continue } cookies = append(cookies, &Cookie{Name: name, Value: val}) } } return cookies }
总结
- 胆大心细
- 升级这种操作有时候是必然要做的,新版会有更多的新特性,带来更好的性能,情况合适的话,需要大胆去做
- 一定要让测试同学,将各个终端,各种状态,各种流程过一遍
- 上线之后,需要继续观察
- 遇到问题,需要不断追查,这是一个自我成长和提升的过程
- 小的方面也需要完美,否则会导致很大的代价。客户端写cookie的方法虽然没错,但也不是很标准,当时写的时候也没在意。目前老的版本已经无法修复,如果想升级1.13,要么修复golang里的问题,要么在项目里添加处理cookie的逻辑,处理起来都有些麻烦
最后
大家如果喜欢我的文章,可以关注我的公众号(程序员麻辣烫)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 追查闪退的六个日与夜
- MySQL主从同步机制和同步延时问题追查
- 如何深入 Python 虚拟机追查 HTTP 服务 core dump 导致 502 的问题
- 【源码阅读】AndPermission源码阅读
- ReactNative源码解析-初识源码
- 【源码阅读】Gson源码阅读
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
极致:互联网时代的产品设计
戴维•罗斯 / 中信出版集团 / 2016-6 / 49.00元
在不远的未来,日常物品将能够迅速理解我们的需求,改善我们的生活,并随处可见。为了实现这一预期,我们需要能够发现用户使用产品的场景,找到用户高频刚需痛点的产品设计者。 站在下一个转型发展的悬崖上,我们看到技术将更具人性。随着物联网的发展,我们习以为常的数百件日常物品:汽车、钱包、手表、雨伞甚至垃圾桶,都将回应我们的需求,了解我们,学习为我们思考。最先出现的智能硬件为什么是智能手环、无人驾驶汽车......一起来看看 《极致:互联网时代的产品设计》 这本书的介绍吧!