goproxy

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 28, 2022 License: Apache-2.0 Imports: 17 Imported by: 0

README

goproxy

Go HTTP(S)代理库, 支持中间人代理解密HTTPS

安装

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)
	}
}
代理测试
curl -x localhost:8080 https://www.baidu.com

中间人代理, 解密HTTPS

系统需导入根证书 mitm-proxy.crt

package main

import (
	"crypto/tls"
	"net/http"
	"sync"
	"time"

	"github.com/ouqiang/goproxy"
)
// 实现证书缓存接口
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)
	}
}

事件处理

实现Delegate接口

type Delegate interface {
	// Connect 收到客户端连接
	Connect(ctx *Context, rw http.ResponseWriter)
	// Auth 代理身份认证
	Auth(ctx *Context, rw http.ResponseWriter)
	// BeforeRequest HTTP请求前 设置X-Forwarded-For, 修改Header、Body
	BeforeRequest(ctx *Context)
	// BeforeResponse 响应发送到客户端前, 修改Header、Body、Status Code
	BeforeResponse(ctx *Context, resp *http.Response, err error)
	// ParentProxy 上级代理
	ParentProxy(*http.Request) (*url.URL, error)
	// Finish 本次请求结束
	Finish(ctx *Context)
	// 记录错误信息
	ErrorLog(err error)
}
type EventHandler struct{}

func (e *EventHandler) Connect(ctx *goproxy.Context, rw http.ResponseWriter) {
	// 保存的数据可以在后面的回调方法中获取
	ctx.Data["req_id"] = "uuid"

	// 禁止访问某个域名
	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)  {
	// 身份验证
}

func (e *EventHandler) BeforeRequest(ctx *goproxy.Context) {
	// 修改header
	ctx.Req.Header.Add("X-Request-Id", ctx.Data["req_id"].(string))
	// 设置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 {
		// 错误处理
		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
}

// 设置上级代理
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("请求结束 URL:%s\n", ctx.Req.URL)
}

// 记录错误日志
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)
	}
}

Documentation

Overview

Package goproxy HTTP(S)代理, 支持中间人代理解密HTTPS数据

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CloneHeader

func CloneHeader(h http.Header, h2 http.Header)

CloneHeader 深拷贝Header

func CopyHeader

func CopyHeader(dst, src http.Header)

CopyHeader 浅拷贝Header

Types

type ConnBuffer

type ConnBuffer struct {
	net.Conn
	// contains filtered or unexported fields
}

func NewConnBuffer

func NewConnBuffer(conn net.Conn, buf *bufio.ReadWriter) *ConnBuffer

func (*ConnBuffer) BufferReader

func (cb *ConnBuffer) BufferReader() *bufio.Reader

func (*ConnBuffer) Header

func (cb *ConnBuffer) Header() http.Header

func (*ConnBuffer) Hijack

func (cb *ConnBuffer) Hijack() (net.Conn, *bufio.ReadWriter, error)

func (*ConnBuffer) Peek

func (cb *ConnBuffer) Peek(n int) ([]byte, error)

func (*ConnBuffer) Read

func (cb *ConnBuffer) Read(b []byte) (n int, err error)

func (*ConnBuffer) Write

func (cb *ConnBuffer) Write(p []byte) (n int, err error)

func (*ConnBuffer) WriteHeader

func (cb *ConnBuffer) WriteHeader(_ int)

type Context

type Context struct {
	Req         *http.Request
	Data        map[interface{}]interface{}
	TunnelProxy bool
	// contains filtered or unexported fields
}

Context 代理上下文

func (*Context) Abort

func (c *Context) Abort()

Abort 中断执行

func (*Context) Addr

func (c *Context) Addr() string

func (*Context) IsAborted

func (c *Context) IsAborted() bool

IsAborted 是否已中断执行

func (*Context) IsHTTPS

func (c *Context) IsHTTPS() bool

func (*Context) Reset

func (c *Context) Reset(req *http.Request)

Reset 重置

func (*Context) WebsocketUrl

func (c *Context) WebsocketUrl() *url.URL

type DefaultDelegate

type DefaultDelegate struct {
	Delegate
}

DefaultDelegate 默认Handler什么也不做

func (*DefaultDelegate) Auth

func (h *DefaultDelegate) Auth(ctx *Context, rw http.ResponseWriter)

func (*DefaultDelegate) BeforeRequest

func (h *DefaultDelegate) BeforeRequest(ctx *Context)

func (*DefaultDelegate) BeforeResponse

func (h *DefaultDelegate) BeforeResponse(ctx *Context, resp *http.Response, err error)

func (*DefaultDelegate) Connect

func (h *DefaultDelegate) Connect(ctx *Context, rw http.ResponseWriter)

func (*DefaultDelegate) ErrorLog

func (h *DefaultDelegate) ErrorLog(err error)

func (*DefaultDelegate) Finish

func (h *DefaultDelegate) Finish(ctx *Context)

func (*DefaultDelegate) ParentProxy

func (h *DefaultDelegate) ParentProxy(req *http.Request) (*url.URL, error)

func (*DefaultDelegate) WebSocketReceiveMessage

func (h *DefaultDelegate) WebSocketReceiveMessage(ctx *Context, messageType *int, payload *[]byte)

WebSockerReceiveMessage websocket接收 消息

func (*DefaultDelegate) WebSocketSendMessage

func (h *DefaultDelegate) WebSocketSendMessage(ctx *Context, messageType *int, payload *[]byte)

WebSocketSendMessage websocket发送消息

type Delegate

type Delegate interface {
	// Connect 收到客户端连接
	Connect(ctx *Context, rw http.ResponseWriter)
	// Auth 代理身份认证
	Auth(ctx *Context, rw http.ResponseWriter)
	// BeforeRequest HTTP请求前 设置X-Forwarded-For, 修改Header、Body
	BeforeRequest(ctx *Context)
	// BeforeResponse 响应发送到客户端前, 修改Header、Body、Status Code
	BeforeResponse(ctx *Context, resp *http.Response, err error)
	// WebSocketSendMessage websocket发送消息
	WebSocketSendMessage(ctx *Context, messageType *int, p *[]byte)
	// WebSockerReceiveMessage websocket接收 消息
	WebSocketReceiveMessage(ctx *Context, messageType *int, p *[]byte)
	// ParentProxy 上级代理
	ParentProxy(*http.Request) (*url.URL, error)
	// Finish 本次请求结束
	Finish(ctx *Context)
	// 记录错误信息
	ErrorLog(err error)
}

type DialContext

type DialContext func(ctx context.Context, network, addr string) (net.Conn, error)

type HeaderPool

type HeaderPool struct {
	// contains filtered or unexported fields
}

func NewHeaderPool

func NewHeaderPool() *HeaderPool

func (*HeaderPool) Get

func (p *HeaderPool) Get() http.Header

func (*HeaderPool) Put

func (p *HeaderPool) Put(header http.Header)

type Option

type Option func(*options)

func WithClientTrace

func WithClientTrace(t *httptrace.ClientTrace) Option

func WithDecryptHTTPS

func WithDecryptHTTPS(c cert.Cache) Option

WithDecryptHTTPS 中间人代理, 解密HTTPS, 需实现证书缓存接口

func WithDelegate

func WithDelegate(delegate Delegate) Option

WithDelegate 设置委托类

func WithDisableKeepAlive

func WithDisableKeepAlive(disableKeepAlive bool) Option

WithDisableKeepAlive 连接是否重用

func WithEnableWebsocketIntercept

func WithEnableWebsocketIntercept() Option

WithEnableWebsocketIntercept 拦截websocket

func WithTransport

func WithTransport(t *http.Transport) Option

WithTransport 自定义http transport

type Proxy

type Proxy struct {
	// contains filtered or unexported fields
}

Proxy 实现了http.Handler接口

func New

func New(opt ...Option) *Proxy

New 创建proxy实例

func (*Proxy) ClientConnNum

func (p *Proxy) ClientConnNum() int32

ClientConnNum 获取客户端连接数

func (*Proxy) DoRequest

func (p *Proxy) DoRequest(ctx *Context, responseFunc func(*http.Response, error))

DoRequest 执行HTTP请求,并调用responseFunc处理response

func (*Proxy) ServeHTTP

func (p *Proxy) ServeHTTP(rw http.ResponseWriter, req *http.Request)

ServeHTTP 实现了http.Handler接口

type RequestPool

type RequestPool struct {
	// contains filtered or unexported fields
}

func (*RequestPool) Get

func (p *RequestPool) Get() *http.Request

func (*RequestPool) Put

func (p *RequestPool) Put(req *http.Request)

Directories

Path Synopsis
Package cert HTTPS证书
Package cert HTTPS证书

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL