init
This commit is contained in:
132
context.go
Normal file
132
context.go
Normal file
@@ -0,0 +1,132 @@
|
||||
package goproxy
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Context 代理上下文
|
||||
// 包含了代理请求的上下文信息,用于在代理处理过程中传递数据
|
||||
type Context struct {
|
||||
// 原始请求
|
||||
Req *http.Request
|
||||
// 请求开始时间
|
||||
StartTime time.Time
|
||||
// 上下文数据,用于在各个处理阶段传递数据
|
||||
Data map[interface{}]interface{}
|
||||
// 是否是隧道代理
|
||||
TunnelProxy bool
|
||||
// 请求ID
|
||||
RequestID string
|
||||
// 目标地址
|
||||
TargetAddr string
|
||||
// 上级代理地址
|
||||
ParentProxyURL *url.URL
|
||||
// 是否中断执行
|
||||
abort bool
|
||||
// 请求标签,用于标记请求类型
|
||||
Tags []string
|
||||
// 是否已中止
|
||||
aborted bool
|
||||
// 互斥锁
|
||||
mu sync.RWMutex
|
||||
}
|
||||
|
||||
// IsHTTPS 是否是HTTPS请求
|
||||
func (c *Context) IsHTTPS() bool {
|
||||
return c.Req.URL.Scheme == "https" || c.Req.Method == http.MethodConnect
|
||||
}
|
||||
|
||||
// defaultPorts 默认端口映射
|
||||
var defaultPorts = map[string]string{
|
||||
"https": "443",
|
||||
"http": "80",
|
||||
"": "80",
|
||||
}
|
||||
|
||||
// WebSocketURL 获取WebSocket URL
|
||||
func (c *Context) WebSocketURL() *url.URL {
|
||||
u := *c.Req.URL
|
||||
if c.IsHTTPS() {
|
||||
u.Scheme = "wss"
|
||||
} else {
|
||||
u.Scheme = "ws"
|
||||
}
|
||||
return &u
|
||||
}
|
||||
|
||||
// Addr 获取请求地址
|
||||
func (c *Context) Addr() string {
|
||||
addr := c.Req.Host
|
||||
|
||||
if !strings.Contains(c.Req.URL.Host, ":") {
|
||||
addr += ":" + defaultPorts[c.Req.URL.Scheme]
|
||||
}
|
||||
|
||||
return addr
|
||||
}
|
||||
|
||||
// AddTag 添加请求标签
|
||||
func (c *Context) AddTag(tag string) {
|
||||
c.Tags = append(c.Tags, tag)
|
||||
}
|
||||
|
||||
// HasTag 检查是否包含指定标签
|
||||
func (c *Context) HasTag(tag string) bool {
|
||||
for _, t := range c.Tags {
|
||||
if t == tag {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Abort 中断执行
|
||||
func (c *Context) Abort() {
|
||||
c.aborted = true
|
||||
}
|
||||
|
||||
// IsAborted 是否已中断执行
|
||||
func (c *Context) IsAborted() bool {
|
||||
return c.aborted
|
||||
}
|
||||
|
||||
// Reset 重置上下文
|
||||
func (c *Context) Reset(req *http.Request) {
|
||||
c.Req = req
|
||||
c.StartTime = time.Now()
|
||||
c.Data = make(map[interface{}]interface{})
|
||||
c.abort = false
|
||||
c.TunnelProxy = false
|
||||
c.Tags = make([]string, 0)
|
||||
c.RequestID = ""
|
||||
c.TargetAddr = ""
|
||||
c.ParentProxyURL = nil
|
||||
c.aborted = false
|
||||
}
|
||||
|
||||
// Set 设置数据
|
||||
func (c *Context) Set(key, value interface{}) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if c.Data == nil {
|
||||
c.Data = make(map[interface{}]interface{})
|
||||
}
|
||||
c.Data[key] = value
|
||||
}
|
||||
|
||||
// Get 获取数据
|
||||
func (c *Context) Get(key interface{}) (interface{}, bool) {
|
||||
c.mu.RLock()
|
||||
defer c.mu.RUnlock()
|
||||
|
||||
if c.Data == nil {
|
||||
return nil, false
|
||||
}
|
||||
val, ok := c.Data[key]
|
||||
return val, ok
|
||||
}
|
||||
Reference in New Issue
Block a user