1 回答
TA贡献1835条经验 获得超7个赞
1. 问题
包含handler.go:119一个if声明。您试图从标题中获取前三个字符Host。
if r.Host[:3] != "www" {
u.Host = r.Host
http.Redirect(w, r, u.String(), http.StatusMovedPermanently)
return
}
正常情况下,r.Host会存储请求的URL信息。除非标Host头在请求中明确更改。来自net/http 包文档:
type Request struct {
// ...
// For server requests Host specifies the host on which the URL
// is sought. Per RFC 7230, section 5.4, this is either the value
// of the "Host" header or the host name given in the URL itself.
// It may be of the form "host:port". For international domain
// names, Host may be in Punycode or Unicode form. Use
// golang.org/x/net/idna to convert it to either format if
// needed.
// To prevent DNS rebinding attacks, server Handlers should
// validate that the Host header has a value for which the
// Handler considers itself authoritative. The included
// ServeMux supports patterns registered to particular host
// names and thus protects its registered Handlers.
//
// For client requests Host optionally overrides the Host
// header to send. If empty, the Request.Write method uses
// the value of URL.Host. Host may contain an international
// domain name.
Host string
// ...
}
所以恐慌的发生是因为r.Host填充了空字符串,或者一些字符数小于 3 的字符串。
2. 测试
我使用 go 创建了非常简单的 Web 应用程序,它打印r.Host[:3]. 我使用 curl 对其进行了测试,并将Host标头设置为空。
curl --verbose --header 'Host: ' http://localhost:8080
它会引发恐慌,我很确定这和你得到的一样是恐慌错误。
2018/12/07 08:11:54 http: panic serving 127.0.0.1:50889: runtime error: slice bounds out of range
goroutine 37 [running]:
net/http.(*conn).serve.func1(0xc0001380a0)
/usr/local/opt/go/libexec/src/net/http/server.go:1746 +0xd0
panic(0x125c0c0, 0x14964d0)
/usr/local/opt/go/libexec/src/runtime/panic.go:513 +0x1b9
main.main.func1(0x12efa80, 0xc00014c2a0, 0xc000162300)
/Users/novalagung/Desktop/test.go:11 +0x13d
net/http.HandlerFunc.ServeHTTP(0x12bcd98, 0x12efa80, 0xc00014c2a0, 0xc000162300)
/usr/local/opt/go/libexec/src/net/http/server.go:1964 +0x44
net/http.(*ServeMux).ServeHTTP(0x14a17a0, 0x12efa80, 0xc00014c2a0, 0xc000162300)
/usr/local/opt/go/libexec/src/net/http/server.go:2361 +0x127
net/http.serverHandler.ServeHTTP(0xc000093110, 0x12efa80, 0xc00014c2a0, 0xc000162300)
/usr/local/opt/go/libexec/src/net/http/server.go:2741 +0xab
net/http.(*conn).serve(0xc0001380a0, 0x12efc80, 0xc000146100)
/usr/local/opt/go/libexec/src/net/http/server.go:1847 +0x646
created by net/http.(*Server).Serve
/usr/local/opt/go/libexec/src/net/http/server.go:2851 +0x2f5
3.解决方案
解决方法很简单,只要确保该r.Host值不是空字符串且长度大于 2 即可。更好地使用strings.HasPrefix()来完成此操作。
if strings.HasPrefix(r.Host, "www") {
u.Host = r.Host
http.Redirect(w, r, u.String(), http.StatusMovedPermanently)
return
}
- 1 回答
- 0 关注
- 109 浏览
添加回答
举报