欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go重寫http請求重定向的方法

 更新時間:2024年08月30日 11:28:08   作者:二郎腿  
當(dāng)使用Go語言進(jìn)行 HTTP 請求時,默認(rèn)情況下,http.Client 會自動處理服務(wù)器返回的重定向響應(yīng)(3xx 狀態(tài)碼),本文將詳細(xì)介紹如何在 Go 中實(shí)現(xiàn)禁止 HTTP 請求的重定向、限制重定向次數(shù)以及添加自定義重定向策略,需要的朋友可以參考下

一、背景

當(dāng)使用 Go 語言進(jìn)行 HTTP 請求時,默認(rèn)情況下,http.Client 會自動處理服務(wù)器返回的重定向響應(yīng)(3xx 狀態(tài)碼)。但有時候,我們可能需要在請求中禁止自動的重定向。本文將詳細(xì)介紹如何在 Go 中實(shí)現(xiàn)禁止 HTTP 請求的重定向、限制重定向次數(shù)以及添加自定義重定向策略

二、默認(rèn)值

http.ClientCheckRedirect 字段是用于處理重定向策略的函數(shù),如果 CheckRedirect 不是 nil,則客戶端會在遵循 HTTP 重定向之前調(diào)用它。參數(shù) req 和 via 是即將到來的請求和已經(jīng)發(fā)出的請求,最早發(fā)出的請求在前面。如果 CheckRedirect 返回錯誤,則 ClientGet 方法將返回前一個 Response(其 Body 關(guān)閉)和 CheckRedirect 的錯誤(包裝在 url.Error),而不是繼續(xù)發(fā)出重定向請求。作為一種特殊情況,如果 CheckRedirect 返回 ErrUseLastResponse,則返回的最新響應(yīng)體的 body, 且 body 未關(guān)閉,并返回 nil 錯誤。如果 CheckRedirectnil,則客戶端使用其默認(rèn)重定向策略,即在連續(xù) 10 個請求后停止。相關(guān)源碼如下,來自src/net/http/client.go。

func defaultCheckRedirect(req *Request, via []*Request) error {
	if len(via) >= 10 {
		return errors.New("stopped after 10 redirects")
	}
	return nil
}

三、禁止重定向

通過設(shè)置 http.ClientCheckRedirect 字段為一個為一個自定義的函數(shù),可以控制重定向的行為。這個函數(shù)接收一個 *http.Request 和一個 []*http.Request 參數(shù),前者代表當(dāng)前正在處理的請求,后者代表已經(jīng)請求的重定向請求鏈,返回 http.ErrUseLastResponse 錯誤,收到這個錯誤后,http.Client 不會再繼續(xù)重定向請求,并且返回一個 nil 錯誤給上游,如下:

func forbidRedirect(req *http.Request, via []*http.Request) (err error) {
	// 返回一個錯誤,表示不允許重定向
	return http.ErrUseLastResponse
}

如果 CheckRedirect 字段不設(shè)置值,或是設(shè)置 nil 值,都會采用上述的默認(rèn)函數(shù)defaultCheckRedirect,進(jìn)行最多 10 重定向;如果返回的不是 http.ErrUseLastResponse 錯誤,那么該請求將會收到一個非 nil 的錯誤。

四、更改重定向次數(shù)

即更改對 []*http.Request 參數(shù)長度的限制即可,一定不能返回 http.ErrUseLastResponse 錯誤。

func limitRedirect(req *http.Request, via []*http.Request) error {
	// via 記錄了已經(jīng)請求的 url 個數(shù)
	if len(via) >= 3 {
		return errors.New("stopped after max redirects")
	}
	return nil
}

五、自定義重定向策略

通過對重定向函數(shù)的重寫,添加一些自定義的邏輯,并將該函數(shù)其賦值給 http client 的CheckRedirect,可以實(shí)現(xiàn)自定義重定向策略,其中 req.Response 參數(shù)表示導(dǎo)致該次重定向的返回。

func myRedirect(req *http.Request, via []*http.Request) error {
	// 限制重定向次數(shù)
	if len(via) >= 10 {
		return errors.New("stopped after 10 redirects")
	}
	if req == nil || req.URL == nil || req.Response == nil || !strings.HasPrefix(req.Response.Status, "3") {
		return http.ErrUseLastResponse
	}
	// 禁止重定向下載 apk 文件
	if strings.HasSuffix(req.URL.Path, "apk") {
		return fmt.Errorf("invalid redirect url, path: %s", req.URL.Path)
	}

	// 限制重定向請求類型
	contentType := req.Response.Header.Get("Content-Type")
	if strings.Contains(contentType, "octet-stream") {
		return fmt.Errorf("invalid redirect url, type: %s", contentType)
	}

	// 限制重定向請求體長度
	contentLength := req.Response.Header.Get("Content-Length")
	if contentLength != "" {
		length, _ := strconv.Atoi(contentLength)
		if length > 1000 {
			return fmt.Errorf("invalid redirect url, len: %s", contentLength)
		}
	}

	// 限制重定向請求傳輸編碼
	transferEncoding := req.Response.Header.Get("Transfer-Encoding")
	if strings.Contains(transferEncoding, "chunked") {
		return fmt.Errorf("invalid redirect url, encoding: %s", transferEncoding)
	}

	return http.ErrUseLastResponse
}

六、完整示例

package main

import (
	"errors"
	"fmt"
	"io"
	"net/http"
)

func forbidRedirect(req *http.Request, via []*http.Request) (err error) {
	// 返回一個錯誤,表示不允許重定向
	return http.ErrUseLastResponse
}

func limitRedirect(req *http.Request, via []*http.Request) error {
	// via 記錄了已經(jīng)請求的 url 個數(shù)
	if len(via) >= 3 {
		return errors.New("stopped after max redirects")
	}
	return nil
}
func main() {
    // 創(chuàng)建一個自定義的 HTTP Client
    client := &http.Client{
        CheckRedirect: forbidRedirect,
    }

    // 創(chuàng)建一個 GET 請求,該 url 一定要重定向
    req, err := http.NewRequest("GET", "https://weibo.com", nil)
    if err != nil {
        fmt.Println("Error creating request:", err)
        return
    }

    // 使用自定義的 Client 發(fā)送請求
    resp, err := client.Do(req)
    if err != nil {
        fmt.Println("Error sending request:", err)
        return
    }
    defer resp.Body.Close()

    fmt.Println("Response Status:", resp.Status)

	body, _ := io.ReadAll(resp.Body)
	fmt.Println("Response Body:", string(body))
}

七、總結(jié)

http.Client 的 CheckRedirect 字段是用于處理重定向策略的函數(shù),如果不賦值時就會采用默認(rèn)函數(shù),默認(rèn)最多重定向 10 次。我們可以通過重寫默認(rèn)函數(shù)來禁止重定向、改變重定向次數(shù)以及添加自定義的重定向過濾邏輯。

到此這篇關(guān)于Go重寫http請求重定向的方法的文章就介紹到這了,更多相關(guān)Go http請求重定向內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論