// Copyright (c) 2025-2026 libaxuan // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. package utils import ( "fmt" "math/rand" "runtime" "time" ) // BrowserProfile 浏览器配置文件 type BrowserProfile struct { Platform string PlatformVersion string Architecture string Bitness string ChromeVersion int UserAgent string Mobile bool } var ( // 常见的浏览器版本 (Chrome) chromeVersions = []int{120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130} // Windows 平台配置 windowsProfiles = []BrowserProfile{ {Platform: "Windows", PlatformVersion: "10.0.0", Architecture: "x86", Bitness: "64"}, {Platform: "Windows", PlatformVersion: "11.0.0", Architecture: "x86", Bitness: "64"}, {Platform: "Windows", PlatformVersion: "15.0.0", Architecture: "x86", Bitness: "64"}, } // macOS 平台配置 macosProfiles = []BrowserProfile{ {Platform: "macOS", PlatformVersion: "13.0.0", Architecture: "arm", Bitness: "64"}, {Platform: "macOS", PlatformVersion: "14.0.0", Architecture: "arm", Bitness: "64"}, {Platform: "macOS", PlatformVersion: "15.0.0", Architecture: "arm", Bitness: "64"}, {Platform: "macOS", PlatformVersion: "13.0.0", Architecture: "x86", Bitness: "64"}, {Platform: "macOS", PlatformVersion: "14.0.0", Architecture: "x86", Bitness: "64"}, } // Linux 平台配置 linuxProfiles = []BrowserProfile{ {Platform: "Linux", PlatformVersion: "", Architecture: "x86", Bitness: "64"}, } ) // HeaderGenerator 动态 header 生成器 type HeaderGenerator struct { profile BrowserProfile chromeVersion int rng *rand.Rand } // NewHeaderGenerator 创建新的 header 生成器 func NewHeaderGenerator() *HeaderGenerator { // 使用当前时间作为随机种子 rng := rand.New(rand.NewSource(time.Now().UnixNano())) // 根据当前操作系统选择合适的配置文件 var profiles []BrowserProfile switch runtime.GOOS { case "darwin": profiles = macosProfiles case "linux": profiles = linuxProfiles default: profiles = windowsProfiles } // 随机选择一个配置文件 profile := profiles[rng.Intn(len(profiles))] // 随机选择 Chrome 版本 chromeVersion := chromeVersions[rng.Intn(len(chromeVersions))] profile.ChromeVersion = chromeVersion // 生成 User-Agent profile.UserAgent = generateUserAgent(profile) return &HeaderGenerator{ profile: profile, chromeVersion: chromeVersion, rng: rng, } } // generateUserAgent 生成 User-Agent 字符串 func generateUserAgent(profile BrowserProfile) string { switch profile.Platform { case "Windows": return fmt.Sprintf("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%d.0.0.0 Safari/537.36", profile.ChromeVersion) case "macOS": if profile.Architecture == "arm" { return fmt.Sprintf("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%d.0.0.0 Safari/537.36", profile.ChromeVersion) } return fmt.Sprintf("Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%d.0.0.0 Safari/537.36", profile.ChromeVersion) case "Linux": return fmt.Sprintf("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%d.0.0.0 Safari/537.36", profile.ChromeVersion) default: return fmt.Sprintf("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%d.0.0.0 Safari/537.36", profile.ChromeVersion) } } // GetChatHeaders 获取聊天请求的 headers func (g *HeaderGenerator) GetChatHeaders(xIsHuman string) map[string]string { // 随机选择语言 languages := []string{ "en-US,en;q=0.9", "zh-CN,zh;q=0.9,en;q=0.8", "en-GB,en;q=0.9", } lang := languages[g.rng.Intn(len(languages))] // 随机选择 referer referers := []string{ "https://cursor.com/en-US/learn/how-ai-models-work", "https://cursor.com/cn/learn/how-ai-models-work", "https://cursor.com/", } referer := referers[g.rng.Intn(len(referers))] headers := map[string]string{ "sec-ch-ua-platform": fmt.Sprintf(`"%s"`, g.profile.Platform), "x-path": "/api/chat", "Referer": referer, "sec-ch-ua": g.getSecChUa(), "x-method": "POST", "sec-ch-ua-mobile": "?0", "x-is-human": xIsHuman, "User-Agent": g.profile.UserAgent, "content-type": "application/json", "accept-language": lang, } // 添加可选的 headers if g.profile.Architecture != "" { headers["sec-ch-ua-arch"] = fmt.Sprintf(`"%s"`, g.profile.Architecture) } if g.profile.Bitness != "" { headers["sec-ch-ua-bitness"] = fmt.Sprintf(`"%s"`, g.profile.Bitness) } if g.profile.PlatformVersion != "" { headers["sec-ch-ua-platform-version"] = fmt.Sprintf(`"%s"`, g.profile.PlatformVersion) } return headers } // GetScriptHeaders 获取脚本请求的 headers func (g *HeaderGenerator) GetScriptHeaders() map[string]string { // 随机选择语言 languages := []string{ "en-US,en;q=0.9", "zh-CN,zh;q=0.9,en;q=0.8", "en-GB,en;q=0.9", } lang := languages[g.rng.Intn(len(languages))] // 随机选择 referer referers := []string{ "https://cursor.com/cn/learn/how-ai-models-work", "https://cursor.com/en-US/learn/how-ai-models-work", "https://cursor.com/", } referer := referers[g.rng.Intn(len(referers))] headers := map[string]string{ "User-Agent": g.profile.UserAgent, "sec-ch-ua-arch": fmt.Sprintf(`"%s"`, g.profile.Architecture), "sec-ch-ua-platform": fmt.Sprintf(`"%s"`, g.profile.Platform), "sec-ch-ua": g.getSecChUa(), "sec-ch-ua-bitness": fmt.Sprintf(`"%s"`, g.profile.Bitness), "sec-ch-ua-mobile": "?0", "sec-fetch-site": "same-origin", "sec-fetch-mode": "no-cors", "sec-fetch-dest": "script", "referer": referer, "accept-language": lang, } if g.profile.PlatformVersion != "" { headers["sec-ch-ua-platform-version"] = fmt.Sprintf(`"%s"`, g.profile.PlatformVersion) } return headers } // getSecChUa 生成 sec-ch-ua header func (g *HeaderGenerator) getSecChUa() string { // 生成随机的品牌版本 notABrand := 24 + g.rng.Intn(10) // 24-33 return fmt.Sprintf(`"Google Chrome";v="%d", "Chromium";v="%d", "Not(A:Brand";v="%d"`, g.chromeVersion, g.chromeVersion, notABrand) } // GetUserAgent 获取 User-Agent func (g *HeaderGenerator) GetUserAgent() string { return g.profile.UserAgent } // GetProfile 获取浏览器配置文件 func (g *HeaderGenerator) GetProfile() BrowserProfile { return g.profile } // Refresh 刷新配置文件(生成新的随机配置) func (g *HeaderGenerator) Refresh() { // 根据当前操作系统选择合适的配置文件 var profiles []BrowserProfile switch runtime.GOOS { case "darwin": profiles = macosProfiles case "linux": profiles = linuxProfiles default: profiles = windowsProfiles } // 随机选择一个配置文件 profile := profiles[g.rng.Intn(len(profiles))] // 随机选择 Chrome 版本 chromeVersion := chromeVersions[g.rng.Intn(len(chromeVersions))] profile.ChromeVersion = chromeVersion // 生成 User-Agent profile.UserAgent = generateUserAgent(profile) g.profile = profile g.chromeVersion = chromeVersion } // GetRandomReferer 获取随机 referer func GetRandomReferer() string { referers := []string{ "https://cursor.com/en-US/learn/how-ai-models-work", "https://cursor.com/cn/learn/how-ai-models-work", "https://cursor.com/", "https://cursor.com/features", } rng := rand.New(rand.NewSource(time.Now().UnixNano())) return referers[rng.Intn(len(referers))] } // GetRandomLanguage 获取随机语言设置 func GetRandomLanguage() string { languages := []string{ "en-US,en;q=0.9", "zh-CN,zh;q=0.9,en;q=0.8", "en-GB,en;q=0.9", "ja-JP,ja;q=0.9,en;q=0.8", } rng := rand.New(rand.NewSource(time.Now().UnixNano())) return languages[rng.Intn(len(languages))] }