日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

Go語言是 如何實現 HTTP代理 和 反向代理

來源: 責編: 時間:2024-04-26 17:34:32 240觀看
導讀代理的核心功能可以用一句話概括:接受客戶端的請求,轉發到后端服務器,獲得應答之后返回給客戶端。代理的功能有很多,事實上整個互聯網到處都充斥著代理服務器。如果所有的 HTTP 訪問都是客戶端和服務器端直接進行的話,我們

代理的核心功能可以用一句話概括:接受客戶端的請求,轉發到后端服務器,獲得應答之后返回給客戶端。2Zp28資訊網——每日最新資訊28at.com

代理的功能有很多,事實上整個互聯網到處都充斥著代理服務器。如果所有的 HTTP 訪問都是客戶端和服務器端直接進行的話,我們的網絡不僅會變得緩慢,而且性能會大打折扣。2Zp28資訊網——每日最新資訊28at.com

代理服務器根據不同的配置和使用,可能會有不同的功能,這些功能主要包括:2Zp28資訊網——每日最新資訊28at.com

內容過濾:代理可以根據一定的規則限制某些請求的連接。比如有些公司會設置內部網絡無法訪問某些購物、游戲網站,或者學校的網絡不讓學生訪問色情暴力的網站等2Zp28資訊網——每日最新資訊28at.com

節省成本:代理服務器可以作為緩存使用,對于某些資源只需要第一次訪問的時候去下載,以后代理直接把緩存的結果返回給客戶端,節約網絡帶寬的開銷。2Zp28資訊網——每日最新資訊28at.com

提高性能:通過代理服務器的緩存(比如 CDN)和負載均衡(比如 nginx lb)功能,服務器端可以加速請求的訪問,在更快的時間內返回結果)2Zp28資訊網——每日最新資訊28at.com

增加安全性:公司可以在內網和外網之間通過代理進行轉發,這樣不僅對外隱藏了實現的細節,而且可以在代理層對爬蟲、病毒性請求進行過濾,保護內部服務2Zp28資訊網——每日最新資訊28at.com

所有的這些功能的實現都依賴于代理的特性,它可以在客戶端和服務器端做一些事情,根據代理做的事情不同,它的角色和功能也就不同。2Zp28資訊網——每日最新資訊28at.com

那么,代理具體可以做哪些事情呢?比如:2Zp28資訊網——每日最新資訊28at.com

修改 HTTP 請求:url、header、body2Zp28資訊網——每日最新資訊28at.com

過濾請求:根據一定的規則丟棄、過濾請求2Zp28資訊網——每日最新資訊28at.com

決定轉發到哪個后端(可以是靜態定義的,也可以是動態決定)2Zp28資訊網——每日最新資訊28at.com

保存服務器的應答,后續的請求可以直接使用保存的應答2Zp28資訊網——每日最新資訊28at.com

修改應答:對應答做一些格式的轉換,修改數據,甚至返回完全不一樣的應答數據2Zp28資訊網——每日最新資訊28at.com

重試機制,如果后端服務器暫時無法響應,隔一段時間重試2Zp28資訊網——每日最新資訊28at.com

正向代理和反向代理

代理可以分為正向代理和反向代理兩種。2Zp28資訊網——每日最新資訊28at.com

正向代理需要客戶端來配置,一般來說我們會通過瀏覽器或者操作系統提供的工具或者界面來配置。2Zp28資訊網——每日最新資訊28at.com

這個時候,代理對客戶端不是透明的,客戶端需要知道代理的地址并且手動配置。配置了代理,瀏覽器在發送請求的時候會對報文做特殊的修改。2Zp28資訊網——每日最新資訊28at.com

反向代理對客戶端是透明的,也就是說客戶端一般不知道代理的存在,認為自己是直接和服務器通信。2Zp28資訊網——每日最新資訊28at.com

我們大部分訪問的網站就是反向代理服務器,反向代理服務器會轉發到真正的服務器,一般在反向代理這一層實現負載均衡和高可用的功能。而且這里也可以看到,客戶端是不會知道真正服務器端的 ip 地址和端口的,這在一定程度上起到了安全保護的作用。2Zp28資訊網——每日最新資訊28at.com

代理服務器怎么知道目的服務器的地址?

在反向代理中,代理服務器要轉發的服務器地址都是事先知道的(包括靜態配置和動態配置)。比如 使用 nginx 來配置負載均衡 。

而對于正向代理來說,客戶端可能訪問的服務器地址是無法事先知道的。因為HTTP 協議活動在應用層,它無法獲取網絡層(IP層)信息,那么該協議要有一個地方可以拿到這個信息。2Zp28資訊網——每日最新資訊28at.com

HTTP 中可能保存這個信息的地方有兩個:URL 和 header。默認情況下,HTTP 請求的 status line 有三部分組成:方法、uri 和協議版本,比如:2Zp28資訊網——每日最新資訊28at.com

GET /index.html HTTP/1.0User-Agent: gohttp 1.0

如果客戶端(比如瀏覽器)知道自己在通過正向代理進行報文傳輸,那么它會在 status line 加上要訪問服務器的真實地址。這個時候發送的報文是:2Zp28資訊網——每日最新資訊28at.com

GET http://www.marys-antiques.com/index.html HTTP/1.0User-Agent: gohttp 1.0

代理路徑客戶端不管是通過代理服務器,還是直接訪問后端服務器對于最終的結果是沒有區別的,也就是說大多數情況下客戶端根本不關心它訪問的到底是什么,只需要(準確快速地)拿到想要的信息就夠了。2Zp28資訊網——每日最新資訊28at.com

但是有時候,我們還是希望知道請求到底在中間經歷了哪些代理,比如用來調試網絡異常,或者做數據統計,而 HTTP 協議也提供了響應的功能。2Zp28資訊網——每日最新資訊28at.com

雖然 RFC 2616 定義了 Via 頭部字段來跟蹤 HTTP 請求經過的代理路徑,但在實際中用的更多的還是 X-Forwarded-For 字段, X-Forwarded-For 是 Squid 緩存代理服務軟件引入的,目前已經在規范化在 RFC 7239 文檔。2Zp28資訊網——每日最新資訊28at.com

X-Forwarded-For 頭部格式也比較簡單,比如某個服務器接受到請求的對應頭部可能是:2Zp28資訊網——每日最新資訊28at.com

X-Forwarded-For: client, proxy1, proxy22Zp28資訊網——每日最新資訊28at.com

對應的值有多個字段,每個字段代表中間的一個節點,它們之間由逗號和空格隔開,從左到右距離當前節點越來越近。2Zp28資訊網——每日最新資訊28at.com

每個代理服務器會在 X-Forwarded-For 頭部填上前一個節點的 ip 地址,這個地址可以通過 TCP 請求的 remote address 獲取。為什么每個代理服務器不填寫自己的 ip 地址呢?2Zp28資訊網——每日最新資訊28at.com

有兩個原因,如果由代理服務器填寫自己的 ip 地址,那么代理可以很簡單地偽造這個地址,而上一個節點的 remote address 是根據 TCP 連接獲取的(如果不建立正確的 TCP 連接是無法進行 HTTP 通信的);另外一個原因是如果由當前節點填寫 X-Forwarded-For ,那么很多情況客戶端無法判斷自己是否會通過代理的。2Zp28資訊網——每日最新資訊28at.com

NOTE:1、最終客戶端或者服務器端接受的請求,X-Forwarded-For 是沒有最鄰近節點的 ip 地址的,而這個地址可以通過 remote address 獲取2Zp28資訊網——每日最新資訊28at.com

2、每個節點(不管是客戶端、代理服務器、真實服務器)都可以隨便更改 X-Forwarded-For 的值,因此這個字段只能作為參考2Zp28資訊網——每日最新資訊28at.com

代理服務器實現這個部分我們會介紹如何用 golang 來實現 HTTP 代理服務器,需要讀者了解一些 HTTP 服務器端編程的知識。2Zp28資訊網——每日最新資訊28at.com

正向代理按照我們之前介紹的代理原理,我們可以編寫出這樣的代碼:2Zp28資訊網——每日最新資訊28at.com

package mainimport (    "fmt"    "io"    "net"    "net/http"    "strings")type Pxy struct {}func (p *Pxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {    fmt.Printf("Received request %s %s %s/n", req.Method, req.Host, req.RemoteAddr)    transport :=  http.DefaultTransport    // step 1    outReq := new(http.Request)    *outReq = *req // this only does shallow copies of maps    if clientIP, _, err := net.SplitHostPort(req.RemoteAddr); err == nil {        if prior, ok := outReq.Header["X-Forwarded-For"]; ok {            clientIP = strings.Join(prior, ", ") + ", " + clientIP        }        outReq.Header.Set("X-Forwarded-For", clientIP)    }    // step 2    res, err := transport.RoundTrip(outReq)    if err != nil {        rw.WriteHeader(http.StatusBadGateway)        return    }    // step 3    for key, value := range res.Header {        for _, v := range value {            rw.Header().Add(key, v)        }    }    rw.WriteHeader(res.StatusCode)    io.Copy(rw, res.Body)    res.Body.Close()}func main() {    fmt.Println("Serve on :8080")    http.Handle("/", &Pxy{})    http.ListenAndServe("0.0.0.0:8080", nil)}

這段代碼比較直觀,只包含了最核心的代碼邏輯,完全按照最上面的代理圖例進行組織。一共分成幾個步驟:2Zp28資訊網——每日最新資訊28at.com

1、代理接收到客戶端的請求,復制了原來的請求對象,并根據數據配置新請求的各種參數(添加上 X-Forward-For 頭部等)2Zp28資訊網——每日最新資訊28at.com

2、把新請求發送到服務器端,并接收到服務器端返回的響應2Zp28資訊網——每日最新資訊28at.com

3、代理服務器對響應做一些處理,然后返回給客戶端2Zp28資訊網——每日最新資訊28at.com

上面的代碼運行之后,會在本地的 8080 端口啟動代理服務。修改瀏覽器的代理為 127.0.0.1::8080 再訪問網站,可以驗證代理正常工作,也能看到它在終端打印出所有的請求信息。2Zp28資訊網——每日最新資訊28at.com

雖然這段代碼非常簡短,但是你可以添加更多的邏輯實現非常有用的功能。比如在請求發送之前進行過濾,根據一定的規則直接阻止某些請求的訪問;或者對請求進行限流,某個客戶端在一定的時間里執行的請求有最大限額;統計請求的數據進行分析等等。2Zp28資訊網——每日最新資訊28at.com

這個代理目前不支持 HTTPS 協議,因為它只提供了 HTTP 請求的轉發功能,并沒有處理證書和認證有關的內容。2Zp28資訊網——每日最新資訊28at.com

如果了解 HTTPS 協議的話,你會明白這種模式下是無法完成 HTTPS 握手的,雖然代理可以和真正的服務器建立連接(知道了對方的公鑰和證書),但是代理無法代表服務器和客戶端建立連接,因為代理服務器無法知道真正服務器的私鑰。2Zp28資訊網——每日最新資訊28at.com

反向代理編寫反向代理按照上面的思路當然沒有問題,只需要在第二步的時候,根據之前的配置修改 outReq 的 URL Host 地址可以了。2Zp28資訊網——每日最新資訊28at.com

不過 Golang 已經給我們提供了編寫代理的框架:httputil.ReverseProxy 。我們可以用非常簡短的代碼來實現自己的代理,而且內部的細節問題都已經被很好地處理了。2Zp28資訊網——每日最新資訊28at.com

這部分我們會實現一個簡單的反向代理,它能夠對請求實現負載均衡,隨機地把請求發送給某些配置好的后端服務器。使用 httputil.ReverseProxy 編寫反向代理最重要的就是實現自己的 Director 對象,這是 GoDoc 對它的介紹:2Zp28資訊網——每日最新資訊28at.com

看代碼:2Zp28資訊網——每日最新資訊28at.com

package mainimport (        "log"        "math/rand"        "net/http"        "net/http/httputil"        "net/url")func NewMultipleHostsReverseProxy(targets []*url.URL) *httputil.ReverseProxy {        director := func(req *http.Request) {                target := targets[rand.Int()%len(targets)]                req.URL.Scheme = target.Scheme                req.URL.Host = target.Host                req.URL.Path = target.Path        }        return &httputil.ReverseProxy{Director: director}}func main() {        proxy := NewMultipleHostsReverseProxy([]*url.URL{                {                        Scheme: "http",                        Host:   "localhost:9091",                },                {                        Scheme: "http",                        Host:   "localhost:9092",                },        })        log.Fatal(http.ListenAndServe(":9090", proxy))}

我們讓代理監聽在 9090 端口,在后端啟動兩個返回不同響應的服務器分別監聽在 9091 和 9092 端口,通過 curl 訪問,可以看到多次請求會返回不同的結果。2Zp28資訊網——每日最新資訊28at.com

?  curl http://127.0.0.1:9090116064a9eb83?  curl http://127.0.0.1:90908f7ccc11718f

同樣的,這段代碼也只是一個 demo,存在著很多問題,比如沒有錯誤處理機制,如果后端某個服務器掛了,代理會返回 502 錯誤,更好的做法是把請求轉發到另外的可用服務器。當然也可以添加更多的特性讓它更好用,比如動態地添加后端服務器列表;根據后端服務器的負載情況進行負載轉發等等。2Zp28資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-85872-0.htmlGo語言是 如何實現 HTTP代理 和 反向代理

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 從RPC到HTTP:網絡通信協議的演變

下一篇: Node.js 重大更新,你知道更新了啥?

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
在线天堂一区av电影| 国产精品国产三级国产aⅴ浪潮| 欧美一级久久久| 伊人精品视频| 欧美午夜精品伦理| 久热精品视频在线观看| 午夜精品久久久久久| 国产精品中文字幕欧美| 欧美日本一区二区高清播放视频| 欧美在线免费一级片| 亚洲最快最全在线视频| 亚洲国产精品999| 国产精品一区亚洲| 欧美另类一区二区三区| 久久亚洲综合网| 销魂美女一区二区三区视频在线| 亚洲一区区二区| 一区二区三区视频在线观看| 亚洲欧美日韩爽爽影院| 亚洲欧美日韩电影| 久久中文字幕一区| 欧美手机在线| 欧美日韩18| 欧美日韩成人免费| 国产精品亚洲综合| 亚洲国产天堂久久国产91| 亚洲网站在线看| 一区二区三区精品| 亚洲毛片在线看| 亚洲青色在线| 亚洲伦理自拍| 久久电影一区| 久久九九久久九九| 久久久99久久精品女同性| 国产精品色一区二区三区| 欧美日韩一区二区高清| 欧美激情一区二区三区在线视频| 欧美jizzhd精品欧美喷水| 久久综合免费视频影院| 国产精品久久久久免费a∨大胸| 欧美大片va欧美在线播放| 欧美成人在线网站| 国产精品视频一区二区高潮| 亚洲国产精品va在看黑人| 亚洲欧美视频一区二区三区| 午夜久久影院| 久久激情婷婷| 欧美午夜片欧美片在线观看| 欧美日韩一区综合| 国产伦一区二区三区色一情| 国产欧美日韩精品一区| 亚洲麻豆av| 99国产一区| 一区二区三区成人精品| 亚洲特色特黄| 亚洲影院污污.| 亚洲欧美综合网| 欧美人交a欧美精品| 欧美日韩一区二区视频在线观看| 国产精品v亚洲精品v日韩精品| 在线看一区二区| 99re热精品| 亚洲一区二区三区午夜| 久久本道综合色狠狠五月| 久久嫩草精品久久久久| 欧美精品123区| 伊人精品视频| 亚洲日韩欧美视频一区| 久久夜色精品亚洲噜噜国产mv| 另类天堂视频在线观看| 欧美日韩免费观看中文| 国产视频不卡| 亚洲经典三级| 亚洲最新中文字幕| 欧美第十八页| 国产精品日韩欧美| 一区在线影院| 久久本道综合色狠狠五月| 国产女主播一区二区| 激情综合色综合久久| 亚洲人成免费| 欧美r片在线| 国产精品免费区二区三区观看| 国产字幕视频一区二区| 亚洲免费av电影| 欧美激情精品久久久| 国产亚洲欧美一区二区| 91久久精品日日躁夜夜躁欧美| 在线视频你懂得一区| 欧美日韩精品一区| 伊人婷婷久久| 久久综合色88| 国产精品毛片一区二区三区 | 亚洲一区在线观看免费观看电影高清| 欧美三日本三级少妇三99| 99成人精品| 欧美天堂亚洲电影院在线观看 | 国产免费观看久久| 欧美一区二区免费观在线| 久久伊人亚洲| 国产精品久久久久一区二区三区共| 精品成人一区二区| 久久久久久免费| 国产精品人人爽人人做我的可爱| 亚洲四色影视在线观看| 国产精品丝袜91| 欧美在线精品免播放器视频| 欧美视频一区二区三区在线观看 | 日韩一级欧洲| 欧美sm视频| 国产曰批免费观看久久久| 亚洲一卡久久| 国产乱码精品一区二区三区五月婷| 香蕉久久夜色精品| 黄色亚洲在线| 午夜精品视频| 国产一区二区三区久久精品| 久久综合电影| 一区二区三区高清在线| 国产日本欧美一区二区| 老司机67194精品线观看| 亚洲精品欧美激情| 美国成人毛片| 黄色小说综合网站| 欧美成人精品在线| 亚洲视频国产视频| 欧美日韩在线一区| 香蕉久久精品日日躁夜夜躁| 黄网站免费久久| 欧美精品色一区二区三区| 亚洲黄色影院| 巨乳诱惑日韩免费av| 日韩视频在线观看| 欧美激情视频一区二区三区免费| 一区二区三区精品在线 | 欧美日韩国产精品自在自线| 亚洲资源av| 国产精品免费看片| 久久伊人精品天天| 宅男精品视频| 欧美在线观看视频| 国产精品麻豆欧美日韩ww| 欧美在线观看网址综合| 亚洲黄色成人网| 国产乱码精品一区二区三区忘忧草 | 久久久亚洲人| 国产亚洲视频在线观看| 91久久精品日日躁夜夜躁欧美 | 欧美午夜精品久久久久久久| 久久久精品一品道一区| 狠狠色2019综合网| 久久久国产午夜精品| 亚洲毛片av| 国内外成人在线视频| 久久夜色精品国产欧美乱| 一区二区三区四区五区视频| 韩国精品一区二区三区| 久久久久久亚洲精品不卡4k岛国| 韩国v欧美v日本v亚洲v| 欧美日韩国产限制| 亚洲一区二区欧美| 亚洲成人在线网| 欧美好骚综合网| 在线视频精品一区| 永久域名在线精品| 欧美日本成人| 久久免费观看视频| 亚洲一区激情| 亚洲美女黄网| 亚洲成人原创 | 久久综合狠狠综合久久综青草| 亚洲一区欧美| 亚洲激情小视频| 国产一区二区三区的电影| 久久久综合视频| 午夜精品短视频| 一本久道久久综合中文字幕 | 黄色日韩精品| 国产女人水真多18毛片18精品视频| 国产精品成人免费| 欧美精品二区三区四区免费看视频| 亚洲午夜久久久| 欧美精品免费在线观看| 久久久免费精品视频| 亚洲欧美日韩一区二区在线| 一本色道精品久久一区二区三区| 亚洲激情图片小说视频| 欧美日韩在线视频一区| 欧美成人高清视频| 久久久久久香蕉网| 欧美一区二区三区在线免费观看| 亚洲视频 欧洲视频| 一区二区激情小说| 亚洲麻豆一区| 亚洲乱码国产乱码精品精| 亚洲黄网站在线观看| 在线看片一区| 国产精品免费网站| 欧美网站在线观看| 欧美日韩1080p| 欧美日韩国产一中文字不卡| 欧美精品一区二区三区一线天视频 | 国产日韩在线看片| 欧美激情一区二区三级高清视频|