goproxy

package module
v1.3.2 Latest Latest
Warning

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

Go to latest
Published: Apr 25, 2022 License: Apache-2.0 Imports: 17 Imported by: 1

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 added in v1.0.1

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

CloneHeader 深拷贝Header

func CopyHeader added in v1.0.1

func CopyHeader(dst, src http.Header)

CopyHeader 浅拷贝Header

Types

type ConnBuffer added in v1.1.1

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

func NewConnBuffer added in v1.1.1

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

func (*ConnBuffer) BufferReader added in v1.1.1

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

func (*ConnBuffer) Header added in v1.1.1

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

func (*ConnBuffer) Hijack added in v1.1.1

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

func (*ConnBuffer) Peek added in v1.1.1

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

func (*ConnBuffer) Read added in v1.1.1

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

func (*ConnBuffer) Write added in v1.1.1

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

func (*ConnBuffer) WriteHeader added in v1.1.1

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 added in v1.1.1

func (c *Context) Addr() string

func (*Context) IsAborted added in v1.0.2

func (c *Context) IsAborted() bool

IsAborted 是否已中断执行

func (*Context) IsHTTPS added in v1.1.1

func (c *Context) IsHTTPS() bool

func (*Context) Reset added in v1.1.1

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

Reset 重置

func (*Context) WebsocketUrl added in v1.1.1

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 added in v1.1.1

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

WebSockerReceiveMessage websocket接收 消息

func (*DefaultDelegate) WebSocketSendMessage added in v1.1.1

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 added in v1.2.7

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

type HeaderPool added in v1.1.1

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

func NewHeaderPool added in v1.1.2

func NewHeaderPool() *HeaderPool

func (*HeaderPool) Get added in v1.1.1

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

func (*HeaderPool) Put added in v1.1.1

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

type Option

type Option func(*options)

func WithClientTrace added in v1.2.3

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 added in v1.1.1

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 added in v1.1.1

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

func (*RequestPool) Get added in v1.1.1

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

func (*RequestPool) Put added in v1.1.1

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

Directories

Path Synopsis
Package cert HTTPS证书 Package cert 证书管理
Package cert HTTPS证书 Package cert 证书管理

Jump to

Keyboard shortcuts

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