maven-proxy 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +466 -420
- package/bin/maven-proxy.js +585 -573
- package/package.json +54 -54
- package/scripts/truststore.js +96 -96
- package/src/cache/cache-path.js +50 -50
- package/src/cache/downloader.js +350 -350
- package/src/cert/cert-manager.js +194 -194
- package/src/cert/truststore-utils.js +383 -289
- package/src/common/console-log-file.js +61 -61
- package/src/common/daily-log-file.js +78 -78
- package/src/common/domain-match.js +39 -39
- package/src/common/download-log-writer.js +26 -26
- package/src/common/ecosystem.js +63 -63
- package/src/common/java-home.js +327 -327
- package/src/config/config.js +224 -213
- package/src/index.js +93 -93
- package/src/proxy/proxy-connect-handler.js +173 -173
- package/src/proxy/proxy-http-handler.js +187 -187
- package/src/proxy/proxy-server.js +35 -35
- package/src/proxy/upstream-proxy.js +236 -236
- package/src/repo/repo-server.js +120 -120
|
@@ -1,173 +1,173 @@
|
|
|
1
|
-
import net from "node:net";
|
|
2
|
-
import tls from "node:tls";
|
|
3
|
-
|
|
4
|
-
function parseConnectTarget(rawUrl) {
|
|
5
|
-
const [host, portText] = String(rawUrl || "").split(":");
|
|
6
|
-
const port = Number.parseInt(portText || "443", 10);
|
|
7
|
-
return {
|
|
8
|
-
host,
|
|
9
|
-
port: Number.isFinite(port) ? port : 443,
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function writeTunnelResponse(socket, statusLine, callback) {
|
|
14
|
-
socket.write(`${statusLine}\r\n\r\n`, callback);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async function openConnectUpstreamSocket(targetHost, targetPort, timeoutMs, upstreamProxyManager = null) {
|
|
18
|
-
const useUpstreamProxy =
|
|
19
|
-
upstreamProxyManager &&
|
|
20
|
-
upstreamProxyManager.hasProxyFor("https:", targetHost);
|
|
21
|
-
|
|
22
|
-
if (useUpstreamProxy) {
|
|
23
|
-
console.log(`[proxy] CONNECT via upstream target=${targetHost}:${targetPort}`);
|
|
24
|
-
const tunnel = await upstreamProxyManager.createConnectTunnel(targetHost, targetPort, timeoutMs);
|
|
25
|
-
return {
|
|
26
|
-
upstreamSocket: tunnel.socket,
|
|
27
|
-
bufferedData: tunnel.bufferedData || Buffer.alloc(0),
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const upstreamSocket = await new Promise((resolve, reject) => {
|
|
32
|
-
const socket = net.connect(targetPort, targetHost, () => resolve(socket));
|
|
33
|
-
socket.once("error", reject);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
return {
|
|
37
|
-
upstreamSocket,
|
|
38
|
-
bufferedData: Buffer.alloc(0),
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
async function handlePassThroughConnect(clientSocket, head, targetHost, targetPort, timeoutMs, upstreamProxyManager = null) {
|
|
43
|
-
const { upstreamSocket, bufferedData } = await openConnectUpstreamSocket(
|
|
44
|
-
targetHost,
|
|
45
|
-
targetPort,
|
|
46
|
-
timeoutMs,
|
|
47
|
-
upstreamProxyManager,
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
await new Promise((resolve, reject) => {
|
|
51
|
-
writeTunnelResponse(clientSocket, "HTTP/1.1 200 Connection Established", (error) => {
|
|
52
|
-
if (error) {
|
|
53
|
-
reject(error);
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
resolve();
|
|
57
|
-
});
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
if (head && head.length > 0) {
|
|
61
|
-
upstreamSocket.write(head);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (bufferedData.length > 0) {
|
|
65
|
-
clientSocket.write(bufferedData);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
upstreamSocket.pipe(clientSocket);
|
|
69
|
-
clientSocket.pipe(upstreamSocket);
|
|
70
|
-
|
|
71
|
-
upstreamSocket.on("error", (error) => {
|
|
72
|
-
if (!clientSocket.destroyed) {
|
|
73
|
-
writeTunnelResponse(clientSocket, "HTTP/1.1 502 Bad Gateway");
|
|
74
|
-
clientSocket.destroy(error);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
clientSocket.on("error", () => {
|
|
79
|
-
upstreamSocket.destroy();
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async function handleMitmConnect(clientSocket, head, targetHost, certManager, mitmHttpServer) {
|
|
84
|
-
console.log(`[proxy] MITM prepare ${targetHost}`);
|
|
85
|
-
const leaf = await certManager.getOrCreateLeaf(targetHost);
|
|
86
|
-
console.log(`[proxy] MITM cert ready ${targetHost}`);
|
|
87
|
-
|
|
88
|
-
await new Promise((resolve, reject) => {
|
|
89
|
-
writeTunnelResponse(clientSocket, "HTTP/1.1 200 Connection Established", (error) => {
|
|
90
|
-
if (error) {
|
|
91
|
-
reject(error);
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
resolve();
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
console.log(`[proxy] MITM tunnel established ${targetHost}`);
|
|
98
|
-
|
|
99
|
-
const tlsSocket = new tls.TLSSocket(clientSocket, {
|
|
100
|
-
isServer: true,
|
|
101
|
-
secureContext: tls.createSecureContext({
|
|
102
|
-
key: leaf.keyPem,
|
|
103
|
-
cert: leaf.certPem,
|
|
104
|
-
}),
|
|
105
|
-
ALPNProtocols: ["http/1.1"],
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
tlsSocket.__mitmHost = targetHost;
|
|
109
|
-
|
|
110
|
-
if (head && head.length > 0) {
|
|
111
|
-
tlsSocket.unshift(head);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
tlsSocket.on("error", () => {
|
|
115
|
-
tlsSocket.destroy();
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
mitmHttpServer.emit("connection", tlsSocket);
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function attachConnectHandler(server, {
|
|
122
|
-
config,
|
|
123
|
-
certManager,
|
|
124
|
-
matchesDomain,
|
|
125
|
-
upstreamProxyManager = null,
|
|
126
|
-
mitmHttpServer,
|
|
127
|
-
}) {
|
|
128
|
-
server.on("connect", (req, clientSocket, head) => {
|
|
129
|
-
const { host, port } = parseConnectTarget(req.url);
|
|
130
|
-
|
|
131
|
-
if (!host) {
|
|
132
|
-
writeTunnelResponse(clientSocket, "HTTP/1.1 400 Bad Request");
|
|
133
|
-
clientSocket.destroy();
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const mitmEnabled =
|
|
138
|
-
config.enableHttpsProxy &&
|
|
139
|
-
matchesDomain(host, config.httpsMitmDomains);
|
|
140
|
-
|
|
141
|
-
console.log(`[proxy] CONNECT ${host}:${port} mitm=${mitmEnabled}`);
|
|
142
|
-
|
|
143
|
-
if (!mitmEnabled) {
|
|
144
|
-
if (!config.httpsPassthroughForUnmatched) {
|
|
145
|
-
writeTunnelResponse(clientSocket, "HTTP/1.1 403 Forbidden");
|
|
146
|
-
clientSocket.destroy();
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
handlePassThroughConnect(
|
|
151
|
-
clientSocket,
|
|
152
|
-
head,
|
|
153
|
-
host,
|
|
154
|
-
port,
|
|
155
|
-
config.downloadTimeoutMs,
|
|
156
|
-
upstreamProxyManager,
|
|
157
|
-
).catch((error) => {
|
|
158
|
-
if (!clientSocket.destroyed) {
|
|
159
|
-
writeTunnelResponse(clientSocket, "HTTP/1.1 502 Bad Gateway");
|
|
160
|
-
clientSocket.destroy(error);
|
|
161
|
-
}
|
|
162
|
-
});
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
handleMitmConnect(clientSocket, head, host, certManager, mitmHttpServer).catch((error) => {
|
|
167
|
-
if (!clientSocket.destroyed) {
|
|
168
|
-
writeTunnelResponse(clientSocket, "HTTP/1.1 502 Bad Gateway");
|
|
169
|
-
}
|
|
170
|
-
clientSocket.destroy(error);
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
}
|
|
1
|
+
import net from "node:net";
|
|
2
|
+
import tls from "node:tls";
|
|
3
|
+
|
|
4
|
+
function parseConnectTarget(rawUrl) {
|
|
5
|
+
const [host, portText] = String(rawUrl || "").split(":");
|
|
6
|
+
const port = Number.parseInt(portText || "443", 10);
|
|
7
|
+
return {
|
|
8
|
+
host,
|
|
9
|
+
port: Number.isFinite(port) ? port : 443,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function writeTunnelResponse(socket, statusLine, callback) {
|
|
14
|
+
socket.write(`${statusLine}\r\n\r\n`, callback);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function openConnectUpstreamSocket(targetHost, targetPort, timeoutMs, upstreamProxyManager = null) {
|
|
18
|
+
const useUpstreamProxy =
|
|
19
|
+
upstreamProxyManager &&
|
|
20
|
+
upstreamProxyManager.hasProxyFor("https:", targetHost);
|
|
21
|
+
|
|
22
|
+
if (useUpstreamProxy) {
|
|
23
|
+
console.log(`[proxy] CONNECT via upstream target=${targetHost}:${targetPort}`);
|
|
24
|
+
const tunnel = await upstreamProxyManager.createConnectTunnel(targetHost, targetPort, timeoutMs);
|
|
25
|
+
return {
|
|
26
|
+
upstreamSocket: tunnel.socket,
|
|
27
|
+
bufferedData: tunnel.bufferedData || Buffer.alloc(0),
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const upstreamSocket = await new Promise((resolve, reject) => {
|
|
32
|
+
const socket = net.connect(targetPort, targetHost, () => resolve(socket));
|
|
33
|
+
socket.once("error", reject);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
upstreamSocket,
|
|
38
|
+
bufferedData: Buffer.alloc(0),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
async function handlePassThroughConnect(clientSocket, head, targetHost, targetPort, timeoutMs, upstreamProxyManager = null) {
|
|
43
|
+
const { upstreamSocket, bufferedData } = await openConnectUpstreamSocket(
|
|
44
|
+
targetHost,
|
|
45
|
+
targetPort,
|
|
46
|
+
timeoutMs,
|
|
47
|
+
upstreamProxyManager,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
await new Promise((resolve, reject) => {
|
|
51
|
+
writeTunnelResponse(clientSocket, "HTTP/1.1 200 Connection Established", (error) => {
|
|
52
|
+
if (error) {
|
|
53
|
+
reject(error);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
resolve();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (head && head.length > 0) {
|
|
61
|
+
upstreamSocket.write(head);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (bufferedData.length > 0) {
|
|
65
|
+
clientSocket.write(bufferedData);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
upstreamSocket.pipe(clientSocket);
|
|
69
|
+
clientSocket.pipe(upstreamSocket);
|
|
70
|
+
|
|
71
|
+
upstreamSocket.on("error", (error) => {
|
|
72
|
+
if (!clientSocket.destroyed) {
|
|
73
|
+
writeTunnelResponse(clientSocket, "HTTP/1.1 502 Bad Gateway");
|
|
74
|
+
clientSocket.destroy(error);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
clientSocket.on("error", () => {
|
|
79
|
+
upstreamSocket.destroy();
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function handleMitmConnect(clientSocket, head, targetHost, certManager, mitmHttpServer) {
|
|
84
|
+
console.log(`[proxy] MITM prepare ${targetHost}`);
|
|
85
|
+
const leaf = await certManager.getOrCreateLeaf(targetHost);
|
|
86
|
+
console.log(`[proxy] MITM cert ready ${targetHost}`);
|
|
87
|
+
|
|
88
|
+
await new Promise((resolve, reject) => {
|
|
89
|
+
writeTunnelResponse(clientSocket, "HTTP/1.1 200 Connection Established", (error) => {
|
|
90
|
+
if (error) {
|
|
91
|
+
reject(error);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
resolve();
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
console.log(`[proxy] MITM tunnel established ${targetHost}`);
|
|
98
|
+
|
|
99
|
+
const tlsSocket = new tls.TLSSocket(clientSocket, {
|
|
100
|
+
isServer: true,
|
|
101
|
+
secureContext: tls.createSecureContext({
|
|
102
|
+
key: leaf.keyPem,
|
|
103
|
+
cert: leaf.certPem,
|
|
104
|
+
}),
|
|
105
|
+
ALPNProtocols: ["http/1.1"],
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
tlsSocket.__mitmHost = targetHost;
|
|
109
|
+
|
|
110
|
+
if (head && head.length > 0) {
|
|
111
|
+
tlsSocket.unshift(head);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
tlsSocket.on("error", () => {
|
|
115
|
+
tlsSocket.destroy();
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
mitmHttpServer.emit("connection", tlsSocket);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function attachConnectHandler(server, {
|
|
122
|
+
config,
|
|
123
|
+
certManager,
|
|
124
|
+
matchesDomain,
|
|
125
|
+
upstreamProxyManager = null,
|
|
126
|
+
mitmHttpServer,
|
|
127
|
+
}) {
|
|
128
|
+
server.on("connect", (req, clientSocket, head) => {
|
|
129
|
+
const { host, port } = parseConnectTarget(req.url);
|
|
130
|
+
|
|
131
|
+
if (!host) {
|
|
132
|
+
writeTunnelResponse(clientSocket, "HTTP/1.1 400 Bad Request");
|
|
133
|
+
clientSocket.destroy();
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const mitmEnabled =
|
|
138
|
+
config.enableHttpsProxy &&
|
|
139
|
+
matchesDomain(host, config.httpsMitmDomains);
|
|
140
|
+
|
|
141
|
+
console.log(`[proxy] CONNECT ${host}:${port} mitm=${mitmEnabled}`);
|
|
142
|
+
|
|
143
|
+
if (!mitmEnabled) {
|
|
144
|
+
if (!config.httpsPassthroughForUnmatched) {
|
|
145
|
+
writeTunnelResponse(clientSocket, "HTTP/1.1 403 Forbidden");
|
|
146
|
+
clientSocket.destroy();
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
handlePassThroughConnect(
|
|
151
|
+
clientSocket,
|
|
152
|
+
head,
|
|
153
|
+
host,
|
|
154
|
+
port,
|
|
155
|
+
config.downloadTimeoutMs,
|
|
156
|
+
upstreamProxyManager,
|
|
157
|
+
).catch((error) => {
|
|
158
|
+
if (!clientSocket.destroyed) {
|
|
159
|
+
writeTunnelResponse(clientSocket, "HTTP/1.1 502 Bad Gateway");
|
|
160
|
+
clientSocket.destroy(error);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
handleMitmConnect(clientSocket, head, host, certManager, mitmHttpServer).catch((error) => {
|
|
167
|
+
if (!clientSocket.destroyed) {
|
|
168
|
+
writeTunnelResponse(clientSocket, "HTTP/1.1 502 Bad Gateway");
|
|
169
|
+
}
|
|
170
|
+
clientSocket.destroy(error);
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
}
|