package proxy 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 }