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

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

 更新時(shí)間:2021年04月30日 11:29:39   作者:order_c  
這篇文章主要介紹了Go 實(shí)現(xiàn)HTTP中間人代理的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

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"
    // 禁止訪問(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ò)誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • Golang時(shí)間及時(shí)間戳的獲取轉(zhuǎn)換超全面詳細(xì)講解

    Golang時(shí)間及時(shí)間戳的獲取轉(zhuǎn)換超全面詳細(xì)講解

    說(shuō)實(shí)話(huà),golang的時(shí)間轉(zhuǎn)化還是很麻煩的,最起碼比php麻煩很多,下面這篇文章主要給大家介紹了關(guān)于golang時(shí)間/時(shí)間戳的獲取與轉(zhuǎn)換的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • 解決golang內(nèi)存溢出的方法

    解決golang內(nèi)存溢出的方法

    這篇文章主要介紹了解決golang內(nèi)存溢出的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • go語(yǔ)言實(shí)現(xiàn)的memcache協(xié)議服務(wù)的方法

    go語(yǔ)言實(shí)現(xiàn)的memcache協(xié)議服務(wù)的方法

    這篇文章主要介紹了go語(yǔ)言實(shí)現(xiàn)的memcache協(xié)議服務(wù)的方法,實(shí)例分析了Go語(yǔ)言使用memcache的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-03-03
  • golang代碼中調(diào)用Linux命令

    golang代碼中調(diào)用Linux命令

    本文主要介紹了golang代碼中調(diào)用Linux命令,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Golang語(yǔ)言使用像JAVA?Spring注解一樣的DI和AOP依賴(lài)注入實(shí)例

    Golang語(yǔ)言使用像JAVA?Spring注解一樣的DI和AOP依賴(lài)注入實(shí)例

    這篇文章主要為大家介紹了Golang語(yǔ)言使用像JAVA?Spring注解一樣的DI和AOP依賴(lài)注入實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • 詳解Go語(yǔ)言中的監(jiān)視器模式與配置熱更新

    詳解Go語(yǔ)言中的監(jiān)視器模式與配置熱更新

    這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言中的監(jiān)視器模式與配置熱更新的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-03-03
  • Golang中Gin框架的使用入門(mén)教程

    Golang中Gin框架的使用入門(mén)教程

    這篇文章主要為大家詳細(xì)介紹了Golang中Gin框架的使用教程,文中通過(guò)簡(jiǎn)單的示例為大家講解了Gin框架的安裝與使用,感興趣的小伙伴開(kāi)業(yè)跟隨小編一起學(xué)習(xí)一下
    2022-10-10
  • Go語(yǔ)言實(shí)現(xiàn)分布式鎖

    Go語(yǔ)言實(shí)現(xiàn)分布式鎖

    分布式鎖是控制分布式系統(tǒng)之間同步訪問(wèn)共享資源的一種方式。如果不同的系統(tǒng)或是同一個(gè)系統(tǒng)的不同主機(jī)之間共享了一個(gè)或一組資源,那么訪問(wèn)這些資源時(shí),需要通過(guò)一些互斥手段來(lái)防止彼此之間的干擾以保證一致性,在這種情況下,就需要使用分布式鎖了
    2023-01-01
  • Golang常用環(huán)境變量說(shuō)明與設(shè)置詳解

    Golang常用環(huán)境變量說(shuō)明與設(shè)置詳解

    這篇文章主要介紹了Golang常用環(huán)境變量說(shuō)明與設(shè)置,需要的朋友可以參考下
    2020-02-02
  • go語(yǔ)言題解LeetCode1299將每個(gè)元素替換為右側(cè)最大元素

    go語(yǔ)言題解LeetCode1299將每個(gè)元素替換為右側(cè)最大元素

    這篇文章主要為大家介紹了go語(yǔ)言LeetCode刷題1299將每個(gè)元素替換為右側(cè)最大元素示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01

最新評(píng)論