教程集 www.jiaochengji.com
教程集 >  Golang编程  >  golang教程  >  正文 Go1.13标准库http包重大bug

Go1.13标准库http包重大bug

发布时间:2021-12-12   编辑:jiaochengji.com
教程集为您提供Go1.13标准库http包重大bug等资源,欢迎您收藏本站,我们将为您提供最新的Go1.13标准库http包重大bug资源
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;"><path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"/></svg>

2019年11月21日,golang的官方github仓库提交了一个https://github.com/golang/go/issues/35750,该issue指出如果初始化 http.Server 结构体时指定了一个非空的 ConnContext 成员函数,且如果在该函数内使用了 context.Value 方法写入数据到上下文并返回,则 Context 将会以链表的方式泄漏

据官方开发人员表示,该bug于1.13版本引进,目前已经在1.13.5修复。

ConnContext

<blockquote>

ConnContext optionally specifies a function that modifies the context used for a new connection c.

</blockquote>

ConnContext是用于更改新连接的context而设置的一个方法。然而,它把新context赋值给了被所有连接共享的一个变量。

代码如下:

<pre><code class="lang-go hljs"><span class="token keyword">type</span> Server <span class="token keyword">struct</span> <span class="token punctuation">{</span> <span class="token operator">...</span> <span class="token comment">// ConnContext optionally specifies a function that modifies</span> <span class="token comment">// the context used for a new connection c. The provided ctx</span> <span class="token comment">// is derived from the base context and has a ServerContextKey</span> <span class="token comment">// value.</span> ConnContext <span class="token keyword">func</span><span class="token punctuation">(</span>ctx context<span class="token punctuation">.</span>Context<span class="token punctuation">,</span> c net<span class="token punctuation">.</span>Conn<span class="token punctuation">)</span> context<span class="token punctuation">.</span>Context <span class="token operator">...</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token punctuation">(</span>srv <span class="token operator">*</span>Server<span class="token punctuation">)</span> <span class="token function">Serve</span><span class="token punctuation">(</span>l net<span class="token punctuation">.</span>Listener<span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span> <span class="token operator">...</span> baseCtx <span class="token operator">:=</span> context<span class="token punctuation">.</span><span class="token function">Background</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">...</span> ctx <span class="token operator">:=</span> context<span class="token punctuation">.</span><span class="token function">WithValue</span><span class="token punctuation">(</span>baseCtx<span class="token punctuation">,</span> ServerContextKey<span class="token punctuation">,</span> srv<span class="token punctuation">)</span> <span class="token keyword">for</span> <span class="token punctuation">{</span> rw<span class="token punctuation">,</span> e <span class="token operator">:=</span> l<span class="token punctuation">.</span><span class="token function">Accept</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">...</span> <span class="token keyword">if</span> cc <span class="token operator">:=</span> srv<span class="token punctuation">.</span>ConnContext<span class="token punctuation">;</span> cc <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> ctx <span class="token operator">=</span> <span class="token function">cc</span><span class="token punctuation">(</span>ctx<span class="token punctuation">,</span> rw<span class="token punctuation">)</span> <span class="token keyword">if</span> ctx <span class="token operator">==</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token function">panic</span><span class="token punctuation">(</span><span class="token string">"ConnContext returned nil"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token operator">...</span> <span class="token keyword">go</span> c<span class="token punctuation">.</span><span class="token function">serve</span><span class="token punctuation">(</span>ctx<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre>

问题出在<code>ctx = cc(ctx, rw)</code>,这一行错误的将<code>cc</code>方法生成的新context赋值给了全局的<code>ctx</code>变量。

修复方式

pull request diff 如下:

总结
通过此bug来看,对于开源代码,在使用之前还是应该了解其实现细节,即使是github的明星项目(甚至go官方sdk)都不能盲目相信。

参考来源:

<ol><li>https://github.com/golang/go/issues/35750</li><li>https://go-review.googlesource.com/c/go/ /208318/</li></ol> 到此这篇关于“Go1.13标准库http包重大bug”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!

您可能感兴趣的文章:
Go1.13标准库http包重大bug
Go 语言十年而立,Go2 蓄势待发
Go Modules与GOPROXY 配置
Python新手常见问题八:标准库模块命名
Golang实践-error
php第三方库有哪些?
为什么要Web标准化,有何价值?
IE6下溢出多余文字解决方案Iebug
对话jQuery之父John Resig
GO 依赖管理工具go Modules(官方推荐)

[关闭]
~ ~