diff --git a/CloudflareSpeedTest b/CloudflareSpeedTest deleted file mode 160000 index 6eaacd6..0000000 --- a/CloudflareSpeedTest +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6eaacd6b2ca37fd43fbb9a9d5d89c94ff96dc162 diff --git a/browser-extension/README.md b/browser-extension/README.md new file mode 100644 index 0000000..6be49f0 --- /dev/null +++ b/browser-extension/README.md @@ -0,0 +1,18 @@ +# CFspider GitHub 加速扩展 + +CFspider 项目附带的浏览器扩展,用于加速 GitHub 文件下载。 + +## 安装 + +1. 打开 Chrome,访问 `chrome://extensions/` +2. 开启「开发者模式」 +3. 点击「加载已解压的扩展程序」 +4. 选择此 `browser-extension` 文件夹 + +## 配置 + +点击扩展图标,填写 Workers 地址和 UUID,保存即可。 + +## 使用 + +访问 GitHub Releases 页面,下载链接旁会显示「加速」按钮。 diff --git a/browser-extension/content.css b/browser-extension/content.css new file mode 100644 index 0000000..796a9f5 --- /dev/null +++ b/browser-extension/content.css @@ -0,0 +1,80 @@ +/* CFspider GitHub 加速按钮样式 */ + +.cfspider-btn { + display: inline-flex; + align-items: center; + gap: 4px; + margin-left: 8px; + padding: 4px 10px; + background: linear-gradient(135deg, #00d4ff 0%, #7b2cbf 100%); + color: #fff !important; + font-size: 12px; + font-weight: 500; + border-radius: 6px; + text-decoration: none !important; + cursor: pointer; + transition: all 0.2s ease; + vertical-align: middle; + white-space: nowrap; + box-shadow: 0 2px 8px rgba(0, 212, 255, 0.3); +} + +.cfspider-btn:hover { + transform: translateY(-1px); + box-shadow: 0 4px 12px rgba(0, 212, 255, 0.4); + opacity: 0.95; +} + +.cfspider-btn:active { + transform: translateY(0); +} + +.cfspider-btn svg { + flex-shrink: 0; +} + +.cfspider-btn.loading { + pointer-events: none; + opacity: 0.8; +} + +.cfspider-btn .spinner { + animation: cfspider-spin 1s linear infinite; +} + +@keyframes cfspider-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +/* GitHub Releases 页面特殊适配 */ +.release-main-section .cfspider-btn { + margin-left: 12px; +} + +/* Assets 列表适配 */ +.Box-row .cfspider-btn { + margin-left: 8px; +} + +/* 代码下载按钮适配 */ +.get-repo-btn + .cfspider-btn, +.btn-primary + .cfspider-btn { + margin-left: 8px; +} + +/* 暗色主题适配 */ +[data-color-mode="dark"] .cfspider-btn, +.dark .cfspider-btn { + box-shadow: 0 2px 8px rgba(0, 212, 255, 0.2); +} + +[data-color-mode="dark"] .cfspider-btn:hover, +.dark .cfspider-btn:hover { + box-shadow: 0 4px 12px rgba(0, 212, 255, 0.3); +} + diff --git a/browser-extension/content.js b/browser-extension/content.js new file mode 100644 index 0000000..efeb5f1 --- /dev/null +++ b/browser-extension/content.js @@ -0,0 +1,189 @@ +// CFspider GitHub 加速 - Content Script + +(function() { + 'use strict'; + + let config = { workersUrl: '', uuid: '', enabled: true }; + + // GitHub 下载链接匹配模式 + const GITHUB_DOWNLOAD_PATTERNS = [ + /https:\/\/github\.com\/[^\/]+\/[^\/]+\/releases\/download\/.+/, + /https:\/\/github\.com\/[^\/]+\/[^\/]+\/archive\/.+/, + /https:\/\/github\.com\/[^\/]+\/[^\/]+\/raw\/.+/, + /https:\/\/objects\.githubusercontent\.com\/.+/, + /https:\/\/raw\.githubusercontent\.com\/.+/, + /https:\/\/codeload\.github\.com\/.+/, + /https:\/\/github\.com\/[^\/]+\/[^\/]+\/suites\/\d+\/artifacts\/.+/ + ]; + + // 检查是否是 GitHub 下载链接 + function isGitHubDownloadLink(url) { + return GITHUB_DOWNLOAD_PATTERNS.some(pattern => pattern.test(url)); + } + + // 生成加速链接 + function generateAcceleratedUrl(originalUrl) { + if (!config.workersUrl || !config.uuid) return null; + + // 构建代理 URL + const workersHost = config.workersUrl.replace(/^https?:\/\//, '').replace(/\/$/, ''); + const encodedUrl = encodeURIComponent(originalUrl); + + // 使用 /proxy API + return `https://${workersHost}/proxy?url=${encodedUrl}&method=GET`; + } + + // 创建加速按钮 + function createAccelerateButton(link) { + // 检查是否已添加按钮 + if (link.nextElementSibling?.classList.contains('cfspider-btn')) return; + if (link.parentElement.querySelector('.cfspider-btn')) return; + + const btn = document.createElement('a'); + btn.className = 'cfspider-btn'; + btn.innerHTML = ` + + + + 加速 + `; + btn.title = 'CFspider 加速下载'; + btn.href = generateAcceleratedUrl(link.href) || '#'; + btn.target = '_blank'; + + // 点击事件 + btn.addEventListener('click', async (e) => { + e.preventDefault(); + e.stopPropagation(); + + if (!config.workersUrl || !config.uuid) { + alert('请先在 CFspider 扩展中配置 Workers 地址和 UUID'); + return; + } + + // 开始下载 + const acceleratedUrl = generateAcceleratedUrl(link.href); + if (acceleratedUrl) { + // 显示加载状态 + btn.classList.add('loading'); + btn.innerHTML = ` + + + + + 加速中... + `; + + try { + // 直接打开加速链接 + window.open(acceleratedUrl, '_blank'); + + setTimeout(() => { + btn.classList.remove('loading'); + btn.innerHTML = ` + + + + 加速 + `; + }, 1500); + } catch (err) { + console.error('CFspider 加速失败:', err); + btn.classList.remove('loading'); + btn.innerHTML = '失败'; + setTimeout(() => { + btn.innerHTML = ` + + + + 加速 + `; + }, 2000); + } + } + }); + + // 插入按钮 + if (link.parentElement.classList.contains('d-flex') || + link.closest('.Box-row') || + link.closest('.release-main-section')) { + link.parentElement.insertBefore(btn, link.nextSibling); + } else { + link.insertAdjacentElement('afterend', btn); + } + } + + // 扫描并处理下载链接 + function scanDownloadLinks() { + if (!config.enabled) return; + + const links = document.querySelectorAll('a[href]'); + + links.forEach(link => { + if (isGitHubDownloadLink(link.href)) { + createAccelerateButton(link); + } + }); + } + + // 加载配置 + async function loadConfig() { + try { + const result = await chrome.storage.sync.get(['workersUrl', 'uuid', 'enabled']); + config = { + workersUrl: result.workersUrl || '', + uuid: result.uuid || '', + enabled: result.enabled !== false + }; + } catch (e) { + console.error('CFspider: 加载配置失败', e); + } + } + + // 监听配置更新 + chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.type === 'CONFIG_UPDATED') { + config = message.config; + scanDownloadLinks(); + } + }); + + // 监听 DOM 变化 + const observer = new MutationObserver((mutations) => { + let shouldScan = false; + + mutations.forEach(mutation => { + if (mutation.addedNodes.length > 0) { + shouldScan = true; + } + }); + + if (shouldScan) { + setTimeout(scanDownloadLinks, 100); + } + }); + + // 初始化 + async function init() { + await loadConfig(); + scanDownloadLinks(); + + // 监听 DOM 变化 + observer.observe(document.body, { + childList: true, + subtree: true + }); + + // 页面导航时重新扫描(GitHub 使用 pjax) + document.addEventListener('pjax:end', scanDownloadLinks); + document.addEventListener('turbo:load', scanDownloadLinks); + } + + // 页面加载完成后初始化 + if (document.readyState === 'loading') { + document.addEventListener('DOMContentLoaded', init); + } else { + init(); + } +})(); + diff --git a/browser-extension/icons/icon.svg b/browser-extension/icons/icon.svg new file mode 100644 index 0000000..5160d06 --- /dev/null +++ b/browser-extension/icons/icon.svg @@ -0,0 +1,11 @@ + + + + + + + + + CF + + diff --git a/browser-extension/icons/icon128.png b/browser-extension/icons/icon128.png new file mode 100644 index 0000000..759300b Binary files /dev/null and b/browser-extension/icons/icon128.png differ diff --git a/browser-extension/icons/icon16.png b/browser-extension/icons/icon16.png new file mode 100644 index 0000000..52cde2a Binary files /dev/null and b/browser-extension/icons/icon16.png differ diff --git a/browser-extension/icons/icon48.png b/browser-extension/icons/icon48.png new file mode 100644 index 0000000..aaddab7 Binary files /dev/null and b/browser-extension/icons/icon48.png differ diff --git a/browser-extension/manifest.json b/browser-extension/manifest.json new file mode 100644 index 0000000..21b7d53 --- /dev/null +++ b/browser-extension/manifest.json @@ -0,0 +1,39 @@ +{ + "manifest_version": 3, + "name": "CFspider GitHub 加速", + "version": "1.0.0", + "description": "使用 CFspider Workers 加速 GitHub 文件下载", + "author": "CFspider", + "homepage_url": "https://github.com/violettoolssite/CFspider", + "icons": { + "16": "icons/icon16.png", + "48": "icons/icon48.png", + "128": "icons/icon128.png" + }, + "permissions": [ + "storage" + ], + "host_permissions": [ + "https://github.com/*", + "https://objects.githubusercontent.com/*", + "https://raw.githubusercontent.com/*", + "https://codeload.github.com/*" + ], + "action": { + "default_popup": "popup.html", + "default_icon": { + "16": "icons/icon16.png", + "48": "icons/icon48.png" + } + }, + "content_scripts": [ + { + "matches": [ + "https://github.com/*" + ], + "js": ["content.js"], + "css": ["content.css"] + } + ] +} + diff --git a/browser-extension/popup.js b/browser-extension/popup.js new file mode 100644 index 0000000..c2cfa79 --- /dev/null +++ b/browser-extension/popup.js @@ -0,0 +1,55 @@ +// 加载配置 +document.addEventListener('DOMContentLoaded', async () => { + const config = await chrome.storage.sync.get(['workersUrl', 'uuid', 'enabled']); + + document.getElementById('workersUrl').value = config.workersUrl || ''; + document.getElementById('uuid').value = config.uuid || ''; + document.getElementById('enabled').checked = config.enabled !== false; +}); + +// 保存配置 +document.getElementById('saveBtn').addEventListener('click', async () => { + const workersUrl = document.getElementById('workersUrl').value.trim(); + const uuid = document.getElementById('uuid').value.trim(); + const enabled = document.getElementById('enabled').checked; + + const statusEl = document.getElementById('status'); + + // 验证 + if (!workersUrl) { + statusEl.textContent = '请填写 Workers 地址'; + statusEl.className = 'status error'; + return; + } + + if (!uuid) { + statusEl.textContent = '请填写 UUID'; + statusEl.className = 'status error'; + return; + } + + // UUID 格式验证 + const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; + if (!uuidRegex.test(uuid)) { + statusEl.textContent = 'UUID 格式不正确'; + statusEl.className = 'status error'; + return; + } + + // 保存 + await chrome.storage.sync.set({ workersUrl, uuid, enabled }); + + statusEl.textContent = '配置已保存'; + statusEl.className = 'status success'; + + // 通知 content script 更新配置 + const tabs = await chrome.tabs.query({ active: true, currentWindow: true }); + if (tabs[0] && tabs[0].url.includes('github.com')) { + chrome.tabs.sendMessage(tabs[0].id, { type: 'CONFIG_UPDATED', config: { workersUrl, uuid, enabled } }); + } + + setTimeout(() => { + statusEl.className = 'status'; + }, 2000); +}); + diff --git a/test.py b/test.py index c3cafc9..4f04e5e 100644 --- a/test.py +++ b/test.py @@ -1,11 +1,16 @@ import cfspider +import os -# 直接使用海外代理 -response = cfspider.get( +# 禁用系统代理 +os.environ['NO_PROXY'] = '*' +os.environ['no_proxy'] = '*' + +# VLESS 模式测试(需要 UUID) +res = cfspider.get( "https://httpbin.org/ip", - proxies={ - "http": "http://us.cliproxy.io:3010", - "https": "http://2e75108689-region-JP:nf9ssu7a@us.cliproxy.io:3010" - } + cf_proxies="https://ip.kami666.xyz", + uuid="c373c80c-58e4-4e64-8db5-40096905ec58", ) -print(response.json()) \ No newline at end of file +print(f"状态码: {res.status_code}") +print(f"出口 IP: {res.text}") +print(f"CF 节点: {res.cf_colo}")