亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從使用 Go 制作的生產服務器中獲取 panic

從使用 Go 制作的生產服務器中獲取 panic

Go
臨摹微笑 2023-05-15 14:42:56
我感到恐慌,我試圖理解它,但我不確定它為什么會恐慌。錯誤如下所示:main.HTTPSNonWWWRedirect.func1(0x9a5a20, 0xc42015c2a0, 0xc420441400)        /srv/www/go/src/srorapp.no/handler.go:119 +0x1efnet/http.HandlerFunc.ServeHTTP(0xc4200c5f20, 0x9a5a20, 0xc42015c2a0, 0xc420441400)        /usr/local/go/src/net/http/server.go:1918 +0x44net/http.serverHandler.ServeHTTP(0xc4200696c0, 0x9a5a20, 0xc42015c2a0, 0xc420441400)        /usr/local/go/src/net/http/server.go:2619 +0xb4net/http.(*conn).serve(0xc42006d180, 0x9a5fa0, 0xc42031e840)        /usr/local/go/src/net/http/server.go:1801 +0x71dcreated by net/http.(*Server).Serve        /usr/local/go/src/net/http/server.go:2720 +0x288它看起來像是從一個名為 HTTPSNonWWWRedirect 的函數中觸發的。這是我創建的 http 中間件:// HTTPSNonWWWRedirect redirects http requests to https non www.func HTTPSNonWWWRedirect(next http.Handler) http.Handler {    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        if r.TLS != nil {            // If already using HTTPS then continue.            next.ServeHTTP(w, r)            return        }        u := *r.URL        u.Scheme = "https"        if r.Host[:3] != "www" {            u.Host = r.Host            http.Redirect(w, r, u.String(), http.StatusMovedPermanently)            return        }        u.Host = r.Host[4:]        http.Redirect(w, r, u.String(), http.StatusMovedPermanently)    })}此功能與以下一起使用:// NonWWWRedirect redirects www requests to non www.func NonWWWRedirect(next http.Handler) http.Handler {    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {        if r.Host[:3] != "www" {            // If already non www, then continue.            next.ServeHTTP(w, r)            return        }        u := *r.URL        u.Host = r.Host[4:]        u.Scheme = utils.Scheme(r)        http.Redirect(w, r, u.String(), http.StatusMovedPermanently)    })}
查看完整描述

1 回答

?
qq_花開花謝_0

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

}


查看完整回答
反對 回復 2023-05-15
  • 1 回答
  • 0 關注
  • 154 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號