Skip to content

Commit 7ed7267

Browse files
committed
Refactor index.js for improved readability and consistency
- Standardized indentation and formatting in the request configuration object. - Enhanced comments for clarity in the ProtocolOverWSHandler and HandleTCPOutBound functions. - Minor updates to README.md for better structure and clarity in usage examples and configuration notes.
1 parent 0b68970 commit 7ed7267

File tree

3 files changed

+140
-44
lines changed

3 files changed

+140
-44
lines changed

CLAUDE.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
EDtunnel is a Cloudflare Worker/Pages-based VLESS proxy tool that implements WebSocket transport protocol for tunneling traffic. It runs on Cloudflare's serverless infrastructure and provides a web-based proxy service with multi-protocol support.
8+
9+
## Core Architecture
10+
11+
### Main Files
12+
13+
- **`index.js`** - Main source code (1517 lines) containing all functionality
14+
- **`_worker.js`** - Obfuscated production version for deployment (462KB)
15+
- **`wrangler.toml`** - Cloudflare Worker deployment configuration
16+
17+
### Key Components
18+
19+
- **Request routing system** with path-based dispatch (`/cf`, `/{userID}`, `/sub/{userID}`, etc.)
20+
- **VLESS protocol over WebSocket** transport implementation
21+
- **Multi-UUID authentication** with comma-separated configuration
22+
- **SOCKS5 proxy integration** with authentication support
23+
- **Subscription generation** for VLESS links and Clash configurations
24+
- **DNS query handling** over UDP with outbound TCP connections
25+
26+
## Development Commands
27+
28+
```bash
29+
# Local development
30+
npm run dev # Development with Wrangler
31+
npm run dev-local # Local development with index.js
32+
33+
# Production deployment
34+
npm run build # Dry-run deployment check
35+
npm run deploy # Deploy to Cloudflare Workers
36+
npm run obfuscate # Obfuscate index.js → _worker.js
37+
```
38+
39+
## Configuration
40+
41+
The application uses environment variables for configuration:
42+
43+
- **UUID** - User authentication (supports comma-separated multiple UUIDs)
44+
- **PROXYIP** - Proxy server addresses (comma-separated)
45+
- **SOCKS5** - SOCKS5 proxy configuration with auth
46+
- **SOCKS5_RELAY** - SOCKS5 relay endpoints
47+
48+
Configuration can be overridden via URL query parameters: `proxyip`, `socks5`, `socks5_relay`.
49+
50+
## Architecture Patterns
51+
52+
### Request Flow
53+
54+
1. **Main handler** processes all incoming requests
55+
2. **Route dispatch** based on URL path patterns
56+
3. **WebSocket upgrade** for protocol tunneling
57+
4. **Environment/query parameter** configuration resolution
58+
5. **Multi-proxy load balancing** with random selection
59+
60+
### Protocol Implementation
61+
62+
- **VLESS over WebSocket** as primary transport
63+
- **Base64 encoding/decoding** for parameter handling
64+
- **UUID validation** and multi-user support
65+
- **DNS resolution** with fallback mechanisms
66+
- **TCP connection management** with retry logic
67+
68+
## Deployment Options
69+
70+
1. **Cloudflare Workers** - Direct serverless deployment
71+
2. **Cloudflare Pages** - Static site with Functions integration
72+
3. **GitHub integration** - One-click deployment support
73+
74+
## Security Features
75+
76+
- **JavaScript obfuscation** pipeline using `javascript-obfuscator`
77+
- **UUID-based authentication** system
78+
- **TLS encryption** through Cloudflare infrastructure
79+
- **Environment variable protection** for sensitive configuration

README.md

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,24 +72,27 @@ You can use URL query parameters to directly override environment variable confi
7272
> **安全说明**: UUID 必须通过环境变量或配置文件设置,不能通过 URL 参数设置,以防止未授权修改用户身份。
7373
> **Security Note**: UUID must be set via environment variables or configuration files, not through URL parameters, to prevent unauthorized identity modifications.
7474
75-
#### 使用示例 | Usage Examples:
75+
#### 使用示例 | Usage Examples
7676

7777
1. 临时更改代理IP | Temporarily change proxy IP:
78+
7879
```
7980
https://your-domain.workers.dev/?proxyip=another-proxy-ip:port
8081
```
8182

8283
2. 组合多个参数 | Combine multiple parameters:
84+
8385
```
8486
https://your-domain.workers.dev/?proxyip=1.1.1.1:443&socks5_relay=true
8587
```
8688

8789
3. 应用于特定路径 | Apply to specific paths:
90+
8891
```
8992
https://your-domain.workers.dev/sub/your-uuid?proxyip=1.1.1.1:443
9093
```
9194

92-
#### 特性说明 | Feature Notes:
95+
#### 特性说明 | Feature Notes
9396

9497
- 优先级:URL参数 > 环境变量 > 默认值
9598
- 临时性:这些更改仅对当前请求有效,不会永久修改配置
@@ -101,7 +104,7 @@ You can use URL query parameters to directly override environment variable confi
101104
- Combinable: Multiple parameters can be combined for complex configuration adjustments
102105
- Use cases: Quick testing, temporary configuration switching, dynamic calls from third-party systems
103106

104-
#### URL格式注意事项 | URL Format Notes:
107+
#### URL格式注意事项 | URL Format Notes
105108

106109
- 确保查询参数使用正确的格式: `?参数名=值`。问号 `?` 不应被URL编码(`%3F`)。
107110
- 如果您看到像 `/%3Fproxyip=value` 这样的URL,这不会正确工作,应改为 `/?proxyip=value`
@@ -124,6 +127,7 @@ Note: Proxy IPs with ports may not work on HTTP-only Cloudflare sites.
124127
### UUID 配置方法 | UUID Configuration
125128

126129
#### 方法一 | Method 1
130+
127131
`wrangler.toml` 文件中设置(不推荐在公共仓库中使用)
128132
Set in `wrangler.toml` file (not recommended for public repositories)
129133

@@ -133,6 +137,7 @@ UUID = "your-uuid-here"
133137
```
134138

135139
#### 方法二 | Method 2
140+
136141
在 Cloudflare Dashboard 的环境变量中设置(推荐方式)
137142
Set in Cloudflare Dashboard environment variables (recommended method)
138143

@@ -142,6 +147,7 @@ Set in Cloudflare Dashboard environment variables (recommended method)
142147
All multiple configurations MUST use English comma(,) as separator, NOT Chinese comma(,)
143148

144149
✅ 正确示例 | Correct Examples:
150+
145151
```bash
146152
# UUID多个配置 | Multiple UUID
147153
UUID=uuid1,uuid2,uuid3
@@ -154,6 +160,7 @@ PROXYIP=1.1.1.1:443,2.2.2.2:443
154160
```
155161

156162
❌ 错误示例 | Wrong Examples:
163+
157164
```bash
158165
# 错误:使用中文逗号 | Wrong: Using Chinese comma
159166
UUID=uuid1,uuid2,uuid3
@@ -167,6 +174,7 @@ SOCKS5=192.168.1.1:1080,192.168.1.2:1080
167174
### 自动配置订阅 | Auto Configuration Subscribe
168175

169176
使用以下链接获取自动配置 | Use the following link for auto configuration:
177+
170178
```
171179
https://sub.xf.free.hr/auto
172180
```
@@ -185,11 +193,13 @@ https://sub.xf.free.hr/auto
185193
您可以通过以下方式配置多个UUID | You can configure multiple UUIDs in these ways:
186194

187195
1. 环境变量方式 | Via environment variables:
196+
188197
```
189198
UUID=uuid1,uuid2,uuid3
190199
```
191200

192201
2. 配置文件方式 | Via configuration file:
202+
193203
```toml
194204
[vars]
195205
UUID = "uuid1,uuid2,uuid3"
@@ -198,13 +208,15 @@ https://sub.xf.free.hr/auto
198208
### SOCKS5代理配置 | SOCKS5 Proxy Configuration
199209

200210
支持以下格式 | Supports the following formats:
211+
201212
- 基础格式 | Basic format: `host:port`
202213
- 认证格式 | Authentication format: `username:password@host:port`
203214
- 多代理格式(使用英文逗号分隔)| Multiple proxies (separated by English comma): `proxy1,proxy2,proxy3`
204215

205-
#### 配置示例 | Configuration Examples:
216+
#### 配置示例 | Configuration Examples
206217

207218
1. 单个代理 | Single Proxy:
219+
208220
```bash
209221
# 基础格式 | Basic format
210222
SOCKS5=192.168.1.1:1080
@@ -214,6 +226,7 @@ SOCKS5=user:pass@192.168.1.1:1080
214226
```
215227

216228
2. 多个代理(使用英文逗号分隔)| Multiple Proxies (separated by English comma):
229+
217230
```bash
218231
# 多个基础代理 | Multiple basic proxies
219232
SOCKS5=192.168.1.1:1080,192.168.1.2:1080,192.168.1.3:1080
@@ -237,11 +250,13 @@ When multiple proxies are configured, the system will automatically perform load
237250
#### SOCKS5_RELAY 设置 | SOCKS5_RELAY Settings
238251

239252
启用 SOCKS5 全局转发 | Enable SOCKS5 global relay:
253+
240254
```bash
241255
SOCKS5_RELAY=true
242256
```
243257

244258
注意事项 | Notes:
259+
245260
- 确保代理服务器稳定可用 | Ensure proxy servers are stable and available
246261
- 建议使用私有代理以提高安全性 | Recommend using private proxies for better security
247262
- 多代理配置时使用英文逗号分隔 | Use commas to separate multiple proxies
@@ -262,10 +277,12 @@ SOCKS5_RELAY=true
262277
## 🔧 环境变量设置 | Environment Variable Settings
263278

264279
### Workers.dev 设置 | Workers.dev Settings
280+
265281
在 Workers 设置页面配置环境变量 | Configure environment variables in Workers settings page
266282
![workers](image/image-1.png)
267283

268284
### Pages.dev 设置 | Pages.dev Settings
285+
269286
在 Pages 设置页面配置环境变量 | Configure environment variables in Pages settings page
270287
![pages](image/image-2.png)
271288

index.js

Lines changed: 40 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -67,17 +67,17 @@ export default {
6767
try {
6868
const { UUID, PROXYIP, SOCKS5, SOCKS5_RELAY } = env;
6969
const url = new URL(request.url);
70-
71-
// 为当前请求创建配置副本,避免修改全局变量
72-
const requestConfig = {
73-
userID: UUID || userID,
74-
socks5Address: SOCKS5 || socks5Address,
75-
socks5Relay: SOCKS5_RELAY === 'true' || socks5Relay,
76-
proxyIP: null,
77-
proxyPort: null,
78-
enableSocks: false,
79-
parsedSocks5Address: {}
80-
};
70+
71+
// 为当前请求创建配置副本,避免修改全局变量
72+
const requestConfig = {
73+
userID: UUID || userID,
74+
socks5Address: SOCKS5 || socks5Address,
75+
socks5Relay: SOCKS5_RELAY === 'true' || socks5Relay,
76+
proxyIP: null,
77+
proxyPort: null,
78+
enableSocks: false,
79+
parsedSocks5Address: {}
80+
};
8181

8282
// 获取正常URL参数
8383
let urlPROXYIP = url.searchParams.get('proxyip');
@@ -146,9 +146,9 @@ export default {
146146
const host = request.headers.get('Host');
147147
const requestedPath = url.pathname.substring(1); // Remove leading slash
148148
const matchingUserID = userIDs.length === 1 ?
149-
(requestedPath === userIDs[0] ||
150-
requestedPath === `sub/${userIDs[0]}` ||
151-
requestedPath === `bestip/${userIDs[0]}` ? userIDs[0] : null) :
149+
(requestedPath === userIDs[0] ||
150+
requestedPath === `sub/${userIDs[0]}` ||
151+
requestedPath === `bestip/${userIDs[0]}` ? userIDs[0] : null) :
152152
userIDs.find(id => {
153153
const patterns = [id, `sub/${id}`, `bestip/${id}`];
154154
return patterns.some(pattern => requestedPath.startsWith(pattern));
@@ -454,18 +454,18 @@ async function handleDefaultPath(url, request) {
454454
* @returns {Promise<Response>} WebSocket response
455455
*/
456456
async function ProtocolOverWSHandler(request, config = null) {
457-
// 如果没有传入配置,使用全局配置
458-
if (!config) {
459-
config = {
460-
userID,
461-
socks5Address,
462-
socks5Relay,
463-
proxyIP,
464-
proxyPort,
465-
enableSocks,
466-
parsedSocks5Address
467-
};
468-
}
457+
// 如果没有传入配置,使用全局配置
458+
if (!config) {
459+
config = {
460+
userID,
461+
socks5Address,
462+
socks5Relay,
463+
proxyIP,
464+
proxyPort,
465+
enableSocks,
466+
parsedSocks5Address
467+
};
468+
}
469469

470470
/** @type {import("@cloudflare/workers-types").WebSocket[]} */
471471
// @ts-ignore
@@ -568,18 +568,18 @@ async function ProtocolOverWSHandler(request, config = null) {
568568
* @param {Object} config - The configuration for this request
569569
*/
570570
async function HandleTCPOutBound(remoteSocket, addressType, addressRemote, portRemote, rawClientData, webSocket, protocolResponseHeader, log, config = null) {
571-
// 如果没有传入配置,使用全局配置
572-
if (!config) {
573-
config = {
574-
userID,
575-
socks5Address,
576-
socks5Relay,
577-
proxyIP,
578-
proxyPort,
579-
enableSocks,
580-
parsedSocks5Address
581-
};
582-
}
571+
// 如果没有传入配置,使用全局配置
572+
if (!config) {
573+
config = {
574+
userID,
575+
socks5Address,
576+
socks5Relay,
577+
proxyIP,
578+
proxyPort,
579+
enableSocks,
580+
parsedSocks5Address
581+
};
582+
}
583583

584584
async function connectAndWrite(address, port, socks = false) {
585585
/** @type {import("@cloudflare/workers-types").Socket} */
@@ -960,7 +960,7 @@ async function handleDNSQuery(udpChunk, webSocket, protocolResponseHeader, log)
960960
async function socks5Connect(addressType, addressRemote, portRemote, log, parsedSocks5Addr = null) {
961961
// 如果没有传入解析的SOCKS5地址,使用全局的
962962
const { username, password, hostname, port } = parsedSocks5Addr || parsedSocks5Address;
963-
963+
964964
// Connect to the SOCKS server
965965
const socket = connect({
966966
hostname,
@@ -1506,7 +1506,7 @@ function parseEncodedQueryParams(pathname) {
15061506
if (encodedParamsMatch) {
15071507
const encodedParams = encodedParamsMatch[1];
15081508
const paramPairs = encodedParams.split('&');
1509-
1509+
15101510
for (const pair of paramPairs) {
15111511
const [key, value] = pair.split('=');
15121512
if (value) params[key] = decodeURIComponent(value);

0 commit comments

Comments
 (0)