<p>tl;dr: Has anyone run into a problem with Go net/http and TLS where browser connections abort but other clients are fine?</p>
<p>I haven't dug into the root cause for this, but I was curious if anyone else has seen this behavior. I have a standard net/http server with organization-signed key and cert PEM files (and intermediate keys), set up to communicate over TLS only. It works reasonably well with browsers and a Citrix NetScaler -- except when it doesn't. I'll get as fewer than two (2) in 10,000 requests abort under normal conditions, with the occasional spike to 400 or more in 10,000 requests.</p>
<p>The Go server is behind the NetScaler which provides a real certificate (signed by DigiCert, wildcard name) and proxies requests. TLS is used between the Go server and the NetScaler because of security requirements around the information transferred.</p>
<p>When running with TLS in my development environment, I can get an "Abort" on an HTTPS connection within the first 250 (or so) requests from Firefox. When running with TLS in either my development environment or against the production server, and when I'm using Python as my client, I get no errors with about 250,000 requests (parallel clients). When running without TLS in standard HTTP/1.1 mode, there are no errors with any client (Firefox or Python).</p>
<p>The Go version is 1.7.5 Darwin and also 1.7.5 Linux. I've experienced the error both with the default Go muxer and httprouter.</p>
<p>For the curious, here's the function used to initialize the HTTP server with TLS:</p>
<pre><code>func ListenAndServe(addr string, handler http.Handler) error {
// get the read timeout: this keeps the HTTP server from hanging
readTimeout := Config.GetDuration("server.timeout.read")
// get the write timeout: this lets HTTP clients timeout if we don't reply in a timely manner
writeTimeout := Config.GetDuration("server.timeout.write")
// TLS configuration
var tlsConfig *tls.Config
var certFile, keyFile string
isTls := Config.GetBool("server.tls")
if isTls {
certFile = Config.GetProperty("server.tls.cert")
keyFile = Config.GetProperty("server.tls.key")
insecureSkipVerify := Config.GetBool("server.tls.insecure.cert")
cert, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
os.Stderr.WriteString("FATAL: error building TLS configuration: " + string(err.Error()) + "\n")
exit(2)
}
tlsConfig = &tls.Config{
Certificates: []tls.Certificate{cert},
InsecureSkipVerify: insecureSkipVerify,
}
}
// configure the server
server := &http.Server{
ReadTimeout: readTimeout * time.Second,
WriteTimeout: writeTimeout * time.Second,
Addr: addr,
TLSConfig: tlsConfig,
Handler: handler,
}
// serve with or without TLS, based on configuration
if isTls {
return server.ListenAndServeTLS(certFile, keyFile)
} else {
return server.ListenAndServe()
}
}
</code></pre>
<p><em>Edit: code formatting</em></p>
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传