亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Go重寫http請(qǐng)求重定向的方法

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

一、背景

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

二、默認(rèn)值

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

三、禁止重定向

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

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

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

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

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

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

五、自定義重定向策略

通過(guò)對(duì)重定向函數(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)
	}

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

	// 限制重定向請(qǐng)求體長(zhǎng)度
	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)
		}
	}

	// 限制重定向請(qǐng)求傳輸編碼
	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) {
	// 返回一個(gè)錯(cuò)誤,表示不允許重定向
	return http.ErrUseLastResponse
}

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

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

    // 使用自定義的 Client 發(fā)送請(qǐng)求
    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ù),如果不賦值時(shí)就會(huì)采用默認(rèn)函數(shù),默認(rèn)最多重定向 10 次。我們可以通過(guò)重寫默認(rèn)函數(shù)來(lái)禁止重定向、改變重定向次數(shù)以及添加自定義的重定向過(guò)濾邏輯。

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

相關(guān)文章

最新評(píng)論