濮阳杆衣贸易有限公司

主頁(yè) > 知識(shí)庫(kù) > Go 實(shí)現(xiàn)HTTP中間人代理的操作

Go 實(shí)現(xiàn)HTTP中間人代理的操作

熱門(mén)標(biāo)簽:外呼系統(tǒng)用什么卡 阿克蘇地圖標(biāo)注 excel地圖標(biāo)注分布數(shù)據(jù) 電話(huà)機(jī)器人軟件免費(fèi) 外呼系統(tǒng)顯本地手機(jī)號(hào) 評(píng)價(jià)高的400電話(huà)辦理 百度地圖標(biāo)注后傳給手機(jī) 壽光微信地圖標(biāo)注 涿州代理外呼系統(tǒng)

goproxy

Go HTTP(S)代理庫(kù), 支持中間人代理解密HTTPS

項(xiàng)目地址

安裝

go get github.com/ouqiang/goproxy

使用

package main
import (
    "net/http"
    "time"
    "github.com/ouqiang/goproxy"
)
func main() {
    proxy := goproxy.New()
    server := http.Server{
        Addr:         ":8080",
        Handler:      proxy,
        ReadTimeout:  1 * time.Minute,
        WriteTimeout: 1 * time.Minute,
    }
    err := server.ListenAndServe()
    if err != nil {
        panic(err)
    }
}

代理測(cè)試

curl -x localhost:8080 https://www.baidu.com

中間人代理, 解密HTTPS

系統(tǒng)需導(dǎo)入根證書(shū) mitm-proxy.crt

package main
import (
    "crypto/tls"
    "net/http"
    "sync"
    "time"
    "github.com/ouqiang/goproxy"
)
// 實(shí)現(xiàn)證書(shū)緩存接口
type Cache struct {
    m sync.Map
}
func (c *Cache) Set(host string, cert *tls.Certificate) {
    c.m.Store(host, cert)
}
func (c *Cache) Get(host string) *tls.Certificate {
    v, ok := c.m.Load(host)
    if !ok {
        return nil
    }
    return v.(*tls.Certificate)
}
func main() {
    proxy := goproxy.New(goproxy.WithDecryptHTTPS(Cache{}))
    server := http.Server{
        Addr:         ":8080",
        Handler:      proxy,
        ReadTimeout:  1 * time.Minute,
        WriteTimeout: 1 * time.Minute,
    }
    err := server.ListenAndServe()
    if err != nil {
        panic(err)
    }
}

事件處理

實(shí)現(xiàn)Delegate接口

type Delegate interface {
    // Connect 收到客戶(hù)端連接
    Connect(ctx *Context, rw http.ResponseWriter)
    // Auth 代理身份認(rèn)證
    Auth(ctx *Context, rw http.ResponseWriter)
    // BeforeRequest HTTP請(qǐng)求前 設(shè)置X-Forwarded-For, 修改Header、Body
    BeforeRequest(ctx *Context)
    // BeforeResponse 響應(yīng)發(fā)送到客戶(hù)端前, 修改Header、Body、Status Code
    BeforeResponse(ctx *Context, resp *http.Response, err error)
    // ParentProxy 上級(jí)代理
    ParentProxy(*http.Request) (*url.URL, error)
    // Finish 本次請(qǐng)求結(jié)束
    Finish(ctx *Context)
    // 記錄錯(cuò)誤信息
    ErrorLog(err error)
}
type EventHandler struct{}
func (e *EventHandler) Connect(ctx *goproxy.Context, rw http.ResponseWriter) {
    // 保存的數(shù)據(jù)可以在后面的回調(diào)方法中獲取
    ctx.Data["req_id"] = "uuid"
    // 禁止訪(fǎng)問(wèn)某個(gè)域名
    if strings.Contains(ctx.Req.URL.Host, "example.com") {
        rw.WriteHeader(http.StatusForbidden)
        ctx.Abort()
        return
    }
}
func (e *EventHandler) Auth(ctx *goproxy.Context, rw http.ResponseWriter)  {
    // 身份驗(yàn)證
}
func (e *EventHandler) BeforeRequest(ctx *goproxy.Context) {
    // 修改header
    ctx.Req.Header.Add("X-Request-Id", ctx.Data["req_id"].(string))
    // 設(shè)置X-Forwarded-For
    if clientIP, _, err := net.SplitHostPort(ctx.Req.RemoteAddr); err == nil {
        if prior, ok := ctx.Req.Header["X-Forwarded-For"]; ok {
            clientIP = strings.Join(prior, ", ") + ", " + clientIP
        }
        ctx.Req.Header.Set("X-Forwarded-For", clientIP)
    }
    // 讀取Body
    body, err := ioutil.ReadAll(ctx.Req.Body)
    if err != nil {
        // 錯(cuò)誤處理
        return
    }
    // Request.Body只能讀取一次, 讀取后必須再放回去
    // Response.Body同理
    ctx.Req.Body = ioutil.NopCloser(bytes.NewReader(body))
}
func (e *EventHandler) BeforeResponse(ctx *goproxy.Context, resp *http.Response, err error) {
    if err != nil {
        return
    }
    // 修改response
}
// 設(shè)置上級(jí)代理
func (e *EventHandler) ParentProxy(req *http.Request) (*url.URL, error) {
    return url.Parse("http://localhost:1087")
}
func (e *EventHandler) Finish(ctx *goproxy.Context) {
    fmt.Printf("請(qǐng)求結(jié)束 URL:%s\n", ctx.Req.URL)
}
// 記錄錯(cuò)誤日志
func (e *EventHandler) ErrorLog(err error) {
    log.Println(err)
}
func main() {
    proxy := goproxy.New(goproxy.WithDelegate(EventHandler{}))
    server := http.Server{
        Addr:         ":8080",
        Handler:      proxy,
        ReadTimeout:  1 * time.Minute,
        WriteTimeout: 1 * time.Minute,
    }
    err := server.ListenAndServe()
    if err != nil {
        panic(err)
    }
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

您可能感興趣的文章:
  • go 原生http web 服務(wù)跨域restful api的寫(xiě)法介紹
  • golang http使用踩過(guò)的坑與填坑指南
  • Go http client 連接池不復(fù)用的問(wèn)題
  • Golang實(shí)現(xiàn)http server提供壓縮文件下載功能
  • golang語(yǔ)言http協(xié)議get拼接參數(shù)操作
  • 在go文件服務(wù)器加入http.StripPrefix的用途介紹
  • Golang 實(shí)現(xiàn)分片讀取http超大文件流和并發(fā)控制

標(biāo)簽:吐魯番 欽州 汕頭 雞西 梅河口 重慶 蘭州 銅川

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《Go 實(shí)現(xiàn)HTTP中間人代理的操作》,本文關(guān)鍵詞  實(shí)現(xiàn),HTTP,中間人,代理,的,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問(wèn)題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無(wú)關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《Go 實(shí)現(xiàn)HTTP中間人代理的操作》相關(guān)的同類(lèi)信息!
  • 本頁(yè)收集關(guān)于Go 實(shí)現(xiàn)HTTP中間人代理的操作的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    汉源县| 浏阳市| 营口市| 宝丰县| 平山县| 哈尔滨市| 桐梓县| 东平县| 枝江市| 鸡泽县| 滦南县| 甘孜| 墨玉县| 佳木斯市| 襄汾县| 峨眉山市| 鄄城县| 连州市| 塔河县| 嘉鱼县| 故城县| 临洮县| 永顺县| 彭水| 杭州市| 那曲县| 武强县| 慈利县| 乐昌市| 都匀市| 将乐县| 福安市| 太湖县| 方山县| 封开县| 安国市| 仪陇县| 陆川县| 石屏县| 大邑县| 都昌县|