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

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

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

一、背景

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

二、默認值

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

三、禁止重定向

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

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

如果 CheckRedirect 字段不設置值,或是設置 nil 值,都會采用上述的默認函數(shù)defaultCheckRedirect,進行最多 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,可以實現(xiàn)自定義重定向策略,其中 req.Response 參數(shù)表示導致該次重定向的返回。

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ù),如果不賦值時就會采用默認函數(shù),默認最多重定向 10 次。我們可以通過重寫默認函數(shù)來禁止重定向、改變重定向次數(shù)以及添加自定義的重定向過濾邏輯。

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

相關文章

  • Golang中互斥鎖和讀寫互斥鎖原理及示例代碼

    Golang中互斥鎖和讀寫互斥鎖原理及示例代碼

    在Golang中,互斥鎖是一種基本的同步原語,用于實現(xiàn)對共享資源的互斥訪問,讀寫互斥鎖是一種特殊類型的互斥鎖,它允許多個協(xié)程同時讀取某個共享資源,本文將通過過示例代碼詳細介紹Golang中互斥鎖和讀寫互斥鎖,需要的朋友可以參考下
    2023-05-05
  • golang switch語句的靈活寫法介紹

    golang switch語句的靈活寫法介紹

    這篇文章主要介紹了golang switch語句的靈活寫法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • Go語言實現(xiàn)新春祝福二維碼的生成

    Go語言實現(xiàn)新春祝福二維碼的生成

    二維碼現(xiàn)在是隨處度可以看到,買東西,支付,添加好友只要你掃一掃就能完成整個工作,簡單且方便。所以利用這個新春佳節(jié)做一個帶著新春祝福的二維碼吧
    2023-02-02
  • go項目中環(huán)境變量的配置

    go項目中環(huán)境變量的配置

    本文主要介紹了go項目中環(huán)境變量的配置,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2021-07-07
  • go語言日志實現(xiàn)詳解(打印日志、日志寫入文件和日志切割)

    go語言日志實現(xiàn)詳解(打印日志、日志寫入文件和日志切割)

    golang內(nèi)置了log包,實現(xiàn)簡單的日志服務,下面這篇文章主要給大家介紹了關于go語言日志實現(xiàn)(打印日志、日志寫入文件和日志切割)的相關資料,需要的朋友可以參考下
    2022-10-10
  • 一文詳解Go語言io包中的discard類型

    一文詳解Go語言io包中的discard類型

    這篇文章主要介紹了Go語言io包中的discard類型示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-07-07
  • go語言中的udp協(xié)議及TCP通訊實現(xiàn)示例

    go語言中的udp協(xié)議及TCP通訊實現(xiàn)示例

    這篇文章主要為大家介紹了go語言中的udp協(xié)議及TCP通訊的實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • 在golang中使用Sync.WaitGroup解決等待的問題

    在golang中使用Sync.WaitGroup解決等待的問題

    這篇文章主要介紹了在golang中使用Sync.WaitGroup解決等待的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • golang實現(xiàn)多協(xié)程下載文件(支持斷點續(xù)傳)

    golang實現(xiàn)多協(xié)程下載文件(支持斷點續(xù)傳)

    本文主要介紹了golang實現(xiàn)多協(xié)程下載文件,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 詳解Go語言中關于包導入必學的 8 個知識點

    詳解Go語言中關于包導入必學的 8 個知識點

    這篇文章主要介紹了詳解Go語言中關于包導入必學的 8 個知識點,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08

最新評論