@rogatio/cli 6.16.2 → 6.16.4
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/dist/editor/index.js +5 -1
- package/dist/node/index.js +249 -59
- package/package.json +1 -1
package/dist/editor/index.js
CHANGED
|
@@ -531,7 +531,11 @@ function createAIAssistPanel(_container, _editor, onApply, onClose, onSend) {
|
|
|
531
531
|
`;
|
|
532
532
|
const addDetail = (label, value) => {
|
|
533
533
|
const detail = document.createElement("div");
|
|
534
|
-
|
|
534
|
+
const labelEl = document.createElement("span");
|
|
535
|
+
labelEl.style.color = "#666";
|
|
536
|
+
labelEl.textContent = `${label}:`;
|
|
537
|
+
detail.appendChild(labelEl);
|
|
538
|
+
detail.appendChild(document.createTextNode(` ${value}`));
|
|
535
539
|
ruleDetails.appendChild(detail);
|
|
536
540
|
};
|
|
537
541
|
if (rule.source) {
|
package/dist/node/index.js
CHANGED
|
@@ -2301,6 +2301,7 @@ import { isAbsolute as isAbsolute3 } from "node:path";
|
|
|
2301
2301
|
import { Buffer as Buffer2 } from "node:buffer";
|
|
2302
2302
|
import { existsSync as existsSync2 } from "node:fs";
|
|
2303
2303
|
import { join as join6 } from "node:path";
|
|
2304
|
+
import { lookup as dnsLookup2 } from "node:dns/promises";
|
|
2304
2305
|
import {
|
|
2305
2306
|
createServer as createServer2
|
|
2306
2307
|
} from "node:http";
|
|
@@ -20072,7 +20073,7 @@ var require_x509_cjs = __commonJS({
|
|
|
20072
20073
|
var _X509Certificate_signature;
|
|
20073
20074
|
var _X509Certificate_extensions;
|
|
20074
20075
|
var _X509Certificate_publicKey;
|
|
20075
|
-
var
|
|
20076
|
+
var X509Certificate4 = class extends PemData {
|
|
20076
20077
|
get publicKey() {
|
|
20077
20078
|
if (!tslib.__classPrivateFieldGet(this, _X509Certificate_publicKey, "f")) {
|
|
20078
20079
|
tslib.__classPrivateFieldSet(this, _X509Certificate_publicKey, new PublicKey(this.asn.tbsCertificate.subjectPublicKeyInfo, this.parseOptions), "f");
|
|
@@ -20315,7 +20316,7 @@ var require_x509_cjs = __commonJS({
|
|
|
20315
20316
|
}
|
|
20316
20317
|
};
|
|
20317
20318
|
_X509Certificate_tbs = /* @__PURE__ */ new WeakMap(), _X509Certificate_serialNumber = /* @__PURE__ */ new WeakMap(), _X509Certificate_subjectName = /* @__PURE__ */ new WeakMap(), _X509Certificate_subject = /* @__PURE__ */ new WeakMap(), _X509Certificate_issuerName = /* @__PURE__ */ new WeakMap(), _X509Certificate_issuer = /* @__PURE__ */ new WeakMap(), _X509Certificate_notBefore = /* @__PURE__ */ new WeakMap(), _X509Certificate_notAfter = /* @__PURE__ */ new WeakMap(), _X509Certificate_signatureAlgorithm = /* @__PURE__ */ new WeakMap(), _X509Certificate_signature = /* @__PURE__ */ new WeakMap(), _X509Certificate_extensions = /* @__PURE__ */ new WeakMap(), _X509Certificate_publicKey = /* @__PURE__ */ new WeakMap();
|
|
20318
|
-
|
|
20319
|
+
X509Certificate4.NAME = "Certificate";
|
|
20319
20320
|
var _X509Certificates_options;
|
|
20320
20321
|
var X509Certificates = class extends Array {
|
|
20321
20322
|
constructor(param, options) {
|
|
@@ -20323,7 +20324,7 @@ var require_x509_cjs = __commonJS({
|
|
|
20323
20324
|
_X509Certificates_options.set(this, void 0);
|
|
20324
20325
|
if (PemData.isAsnEncoded(param)) {
|
|
20325
20326
|
this.import(param, options);
|
|
20326
|
-
} else if (param instanceof
|
|
20327
|
+
} else if (param instanceof X509Certificate4) {
|
|
20327
20328
|
this.push(param);
|
|
20328
20329
|
} else if (Array.isArray(param)) {
|
|
20329
20330
|
for (const item of param) {
|
|
@@ -20361,7 +20362,7 @@ var require_x509_cjs = __commonJS({
|
|
|
20361
20362
|
const certificates = [];
|
|
20362
20363
|
for (const item of signedData.certificates || []) {
|
|
20363
20364
|
if (item.certificate) {
|
|
20364
|
-
certificates.push(new
|
|
20365
|
+
certificates.push(new X509Certificate4(item.certificate, options));
|
|
20365
20366
|
}
|
|
20366
20367
|
}
|
|
20367
20368
|
this.clear();
|
|
@@ -20553,7 +20554,7 @@ var require_x509_cjs = __commonJS({
|
|
|
20553
20554
|
throw Error("Cannot convert ASN.1 signature value to WebCrypto format");
|
|
20554
20555
|
}
|
|
20555
20556
|
asnX509.signatureValue = asnSignature;
|
|
20556
|
-
return new
|
|
20557
|
+
return new X509Certificate4(asn1Schema.AsnConvert.serialize(asnX509));
|
|
20557
20558
|
}
|
|
20558
20559
|
};
|
|
20559
20560
|
var _X509CrlEntry_serialNumber;
|
|
@@ -20774,7 +20775,7 @@ var require_x509_cjs = __commonJS({
|
|
|
20774
20775
|
let publicKey;
|
|
20775
20776
|
const paramsKey = params.publicKey;
|
|
20776
20777
|
try {
|
|
20777
|
-
if (paramsKey instanceof
|
|
20778
|
+
if (paramsKey instanceof X509Certificate4) {
|
|
20778
20779
|
keyAlgorithm = {
|
|
20779
20780
|
...paramsKey.publicKey.algorithm,
|
|
20780
20781
|
...paramsKey.signatureAlgorithm
|
|
@@ -20978,7 +20979,7 @@ var require_x509_cjs = __commonJS({
|
|
|
20978
20979
|
exports.TextObject = TextObject;
|
|
20979
20980
|
exports.UPN = UPN;
|
|
20980
20981
|
exports.URL = URL2;
|
|
20981
|
-
exports.X509Certificate =
|
|
20982
|
+
exports.X509Certificate = X509Certificate4;
|
|
20982
20983
|
exports.X509CertificateGenerator = X509CertificateGenerator2;
|
|
20983
20984
|
exports.X509Certificates = X509Certificates;
|
|
20984
20985
|
exports.X509ChainBuilder = X509ChainBuilder;
|
|
@@ -24441,11 +24442,6 @@ function parseMockRedirect(rawUrl) {
|
|
|
24441
24442
|
if (!isSingleSegment(token) || !isSingleSegment(digest)) return null;
|
|
24442
24443
|
return { token, digest };
|
|
24443
24444
|
}
|
|
24444
|
-
function supportedContentType(value) {
|
|
24445
|
-
if (value === void 0) return false;
|
|
24446
|
-
const mediaType = value.split(";", 1)[0]?.trim().toLowerCase() ?? "";
|
|
24447
|
-
return mediaType === "application/json" || mediaType.startsWith("application/") && mediaType.endsWith("+json") || mediaType === "application/x-www-form-urlencoded" || mediaType.startsWith("text/");
|
|
24448
|
-
}
|
|
24449
24445
|
var REGEX_WORKER_SOURCE = `
|
|
24450
24446
|
const workerThreads =
|
|
24451
24447
|
typeof process.getBuiltinModule === "function"
|
|
@@ -24603,6 +24599,11 @@ function runRegexReplace(text, pattern, replacement, deadlineMs) {
|
|
|
24603
24599
|
}
|
|
24604
24600
|
);
|
|
24605
24601
|
}
|
|
24602
|
+
function supportedContentType(value) {
|
|
24603
|
+
if (value === void 0) return false;
|
|
24604
|
+
const mediaType = value.split(";", 1)[0]?.trim().toLowerCase() ?? "";
|
|
24605
|
+
return mediaType === "application/json" || mediaType.startsWith("application/") && mediaType.endsWith("+json") || mediaType === "application/x-www-form-urlencoded" || mediaType.startsWith("text/");
|
|
24606
|
+
}
|
|
24606
24607
|
async function rewriteRequestBody(input, action, captureContext) {
|
|
24607
24608
|
if (!supportedContentType(input.contentType)) {
|
|
24608
24609
|
return failure("runtime.request-body-unsupported-mime-type");
|
|
@@ -24881,8 +24882,12 @@ async function rewriteResponseBody(input, replacements, replaceAction, captureCo
|
|
|
24881
24882
|
for (const entry of replacements) {
|
|
24882
24883
|
if (entry.pattern.length === 0 || entry.pattern.length > LIMITS.maxResponseBodyPatternLength || entry.replacement.length > LIMITS.maxResponseBodyReplacementLength)
|
|
24883
24884
|
return failure("runtime.size-limit");
|
|
24884
|
-
|
|
24885
|
-
|
|
24885
|
+
text = await runRegexReplace(
|
|
24886
|
+
text,
|
|
24887
|
+
entry.pattern,
|
|
24888
|
+
entry.replacement,
|
|
24889
|
+
RUNTIME_LIMITS.maxRegexDeadlineMs
|
|
24890
|
+
);
|
|
24886
24891
|
if (new TextEncoder().encode(text).byteLength > RUNTIME_LIMITS.maxResponseBodyBytes)
|
|
24887
24892
|
return failure("runtime.size-limit");
|
|
24888
24893
|
}
|
|
@@ -25131,6 +25136,133 @@ function forwardRequestHeaders(headers, host, contentLength) {
|
|
|
25131
25136
|
}
|
|
25132
25137
|
return out;
|
|
25133
25138
|
}
|
|
25139
|
+
var defaultResolver2 = {
|
|
25140
|
+
async lookup(hostname, signal) {
|
|
25141
|
+
if (signal?.aborted) throw new Error("aborted");
|
|
25142
|
+
const addresses = await dnsLookup2(hostname, { all: true });
|
|
25143
|
+
return addresses.map((address) => ({
|
|
25144
|
+
address: address.address,
|
|
25145
|
+
family: address.family === 6 ? 6 : 4
|
|
25146
|
+
}));
|
|
25147
|
+
}
|
|
25148
|
+
};
|
|
25149
|
+
var defaultDial = (port, address) => connect(port, address);
|
|
25150
|
+
function localOriginsFromProject(project) {
|
|
25151
|
+
if (project === null || typeof project !== "object") return [];
|
|
25152
|
+
const policy = project.requestBodyPolicy;
|
|
25153
|
+
if (policy === null || typeof policy !== "object") return [];
|
|
25154
|
+
const origins = policy.localOrigins;
|
|
25155
|
+
if (!Array.isArray(origins)) return [];
|
|
25156
|
+
return origins.filter(
|
|
25157
|
+
(origin) => typeof origin === "string"
|
|
25158
|
+
);
|
|
25159
|
+
}
|
|
25160
|
+
function effectiveLocalOrigins(policy) {
|
|
25161
|
+
if (policy === null) return /* @__PURE__ */ new Set();
|
|
25162
|
+
const raw = policy.localOrigins ?? localOriginsFromProject(policy.project);
|
|
25163
|
+
const origins = /* @__PURE__ */ new Set();
|
|
25164
|
+
for (const origin of raw) {
|
|
25165
|
+
const normalized = normalizeSiteOrigin(origin);
|
|
25166
|
+
if (normalized !== null) origins.add(normalized);
|
|
25167
|
+
}
|
|
25168
|
+
return origins;
|
|
25169
|
+
}
|
|
25170
|
+
function compareAddresses(left, right) {
|
|
25171
|
+
return left.family - right.family || (left.address < right.address ? -1 : left.address > right.address ? 1 : 0);
|
|
25172
|
+
}
|
|
25173
|
+
function selectPinnedAddress(addresses, allowNonPublic) {
|
|
25174
|
+
const publicOnly = validateResolvedAddresses(
|
|
25175
|
+
addresses,
|
|
25176
|
+
RUNTIME_LIMITS.maxDnsAddresses
|
|
25177
|
+
);
|
|
25178
|
+
if (publicOnly !== null) return publicOnly[0] ?? null;
|
|
25179
|
+
if (!allowNonPublic) return null;
|
|
25180
|
+
if (addresses.length === 0 || addresses.length > RUNTIME_LIMITS.maxDnsAddresses) {
|
|
25181
|
+
return null;
|
|
25182
|
+
}
|
|
25183
|
+
const checked = [];
|
|
25184
|
+
for (const address of addresses) {
|
|
25185
|
+
if (address.family !== 4 && address.family !== 6) return null;
|
|
25186
|
+
const classification = classifyAddress(address.address);
|
|
25187
|
+
if (classification === "invalid" || classification === "public") {
|
|
25188
|
+
return null;
|
|
25189
|
+
}
|
|
25190
|
+
checked.push({ address: address.address, family: address.family });
|
|
25191
|
+
}
|
|
25192
|
+
checked.sort(compareAddresses);
|
|
25193
|
+
return checked[0] ?? null;
|
|
25194
|
+
}
|
|
25195
|
+
async function pinHostname(hostname, origin, deps) {
|
|
25196
|
+
if (hostname.length === 0) return null;
|
|
25197
|
+
let resolved;
|
|
25198
|
+
try {
|
|
25199
|
+
resolved = await deps.resolver.lookup(hostname);
|
|
25200
|
+
} catch {
|
|
25201
|
+
return null;
|
|
25202
|
+
}
|
|
25203
|
+
const normalized = normalizeSiteOrigin(origin);
|
|
25204
|
+
const allowNonPublic = normalized !== null && deps.localOrigins.has(normalized);
|
|
25205
|
+
return selectPinnedAddress(resolved, allowNonPublic);
|
|
25206
|
+
}
|
|
25207
|
+
function httpUpstreamPort(target) {
|
|
25208
|
+
if (target.protocol !== "http:") return null;
|
|
25209
|
+
if (target.username.length > 0 || target.password.length > 0) return null;
|
|
25210
|
+
if (target.port.length === 0 || target.port === "80") return 80;
|
|
25211
|
+
return null;
|
|
25212
|
+
}
|
|
25213
|
+
function formatUpstreamRequest(method, path2, headers) {
|
|
25214
|
+
const lines = [];
|
|
25215
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
25216
|
+
if (name.includes("\r") || name.includes("\n") || value.includes("\r") || value.includes("\n")) {
|
|
25217
|
+
return null;
|
|
25218
|
+
}
|
|
25219
|
+
lines.push(`${name}: ${value}`);
|
|
25220
|
+
}
|
|
25221
|
+
return `${method} ${path2} HTTP/1.1\r
|
|
25222
|
+
${lines.join("\r\n")}\r
|
|
25223
|
+
\r
|
|
25224
|
+
`;
|
|
25225
|
+
}
|
|
25226
|
+
function httpsOrigin(host) {
|
|
25227
|
+
const authority = host.includes(":") && !host.startsWith("[") ? `[${host}]` : host;
|
|
25228
|
+
try {
|
|
25229
|
+
return new URL(`https://${authority}`).origin;
|
|
25230
|
+
} catch {
|
|
25231
|
+
return null;
|
|
25232
|
+
}
|
|
25233
|
+
}
|
|
25234
|
+
function parseConnectAuthority(authority) {
|
|
25235
|
+
if (authority.length === 0) return null;
|
|
25236
|
+
let host;
|
|
25237
|
+
let portText;
|
|
25238
|
+
if (authority.startsWith("[")) {
|
|
25239
|
+
const end = authority.indexOf("]");
|
|
25240
|
+
if (end <= 1) return null;
|
|
25241
|
+
host = authority.slice(1, end);
|
|
25242
|
+
const rest = authority.slice(end + 1);
|
|
25243
|
+
if (!rest.startsWith(":")) return null;
|
|
25244
|
+
portText = rest.slice(1);
|
|
25245
|
+
} else {
|
|
25246
|
+
const colon = authority.lastIndexOf(":");
|
|
25247
|
+
if (colon <= 0) return null;
|
|
25248
|
+
host = authority.slice(0, colon);
|
|
25249
|
+
portText = authority.slice(colon + 1);
|
|
25250
|
+
}
|
|
25251
|
+
if (host.length === 0 || !/^\d+$/.test(portText)) return null;
|
|
25252
|
+
const port = Number(portText);
|
|
25253
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535) return null;
|
|
25254
|
+
return { host, port };
|
|
25255
|
+
}
|
|
25256
|
+
function endConnect(socket, status, reason) {
|
|
25257
|
+
if (socket.destroyed || socket.writableEnded) return;
|
|
25258
|
+
socket.end(
|
|
25259
|
+
`HTTP/1.1 ${status} ${reason}\r
|
|
25260
|
+
Content-Length: 0\r
|
|
25261
|
+
Connection: close\r
|
|
25262
|
+
\r
|
|
25263
|
+
`
|
|
25264
|
+
);
|
|
25265
|
+
}
|
|
25134
25266
|
function pipeSockets(a, b) {
|
|
25135
25267
|
a.pipe(b);
|
|
25136
25268
|
b.pipe(a);
|
|
@@ -25143,11 +25275,16 @@ function pipeSockets(a, b) {
|
|
|
25143
25275
|
a.on("close", () => b.destroy());
|
|
25144
25276
|
b.on("close", () => a.destroy());
|
|
25145
25277
|
}
|
|
25146
|
-
async function upstreamHttp(method, target, headers, body) {
|
|
25147
|
-
const port =
|
|
25278
|
+
async function upstreamHttp(method, target, headers, body, deps) {
|
|
25279
|
+
const port = httpUpstreamPort(target);
|
|
25280
|
+
if (port === null) return { ok: false, status: 403 };
|
|
25148
25281
|
const path2 = `${target.pathname}${target.search}`;
|
|
25282
|
+
const head = formatUpstreamRequest(method, path2, headers);
|
|
25283
|
+
if (head === null) return { ok: false, status: 403 };
|
|
25284
|
+
const pinned = await pinHostname(target.hostname, target.origin, deps);
|
|
25285
|
+
if (pinned === null) return { ok: false, status: 403 };
|
|
25149
25286
|
return new Promise((resolve12, reject) => {
|
|
25150
|
-
const socket =
|
|
25287
|
+
const socket = deps.dial(port, pinned.address);
|
|
25151
25288
|
let buf = Buffer.alloc(0);
|
|
25152
25289
|
let settled = false;
|
|
25153
25290
|
const fail2 = (err) => {
|
|
@@ -25160,11 +25297,7 @@ async function upstreamHttp(method, target, headers, body) {
|
|
|
25160
25297
|
socket.on("timeout", () => fail2(new Error("upstream timeout")));
|
|
25161
25298
|
socket.on("error", (err) => fail2(err));
|
|
25162
25299
|
socket.on("connect", () => {
|
|
25163
|
-
|
|
25164
|
-
socket.write(`${method} ${path2} HTTP/1.1\r
|
|
25165
|
-
${lines}\r
|
|
25166
|
-
\r
|
|
25167
|
-
`);
|
|
25300
|
+
socket.write(head);
|
|
25168
25301
|
if (body.byteLength > 0) socket.write(body);
|
|
25169
25302
|
});
|
|
25170
25303
|
socket.on("data", (chunk) => {
|
|
@@ -25172,9 +25305,9 @@ ${lines}\r
|
|
|
25172
25305
|
buf = Buffer.concat([buf, piece]);
|
|
25173
25306
|
const sep = buf.indexOf("\r\n\r\n");
|
|
25174
25307
|
if (sep < 0) return;
|
|
25175
|
-
const
|
|
25308
|
+
const head2 = buf.subarray(0, sep).toString("latin1");
|
|
25176
25309
|
const statusMatch = /^HTTP\/1\.[01] (\d+)(?: (.*))?/.exec(
|
|
25177
|
-
|
|
25310
|
+
head2.split("\r\n")[0] ?? ""
|
|
25178
25311
|
);
|
|
25179
25312
|
if (!statusMatch) {
|
|
25180
25313
|
fail2(new Error("bad upstream status"));
|
|
@@ -25183,7 +25316,7 @@ ${lines}\r
|
|
|
25183
25316
|
const status = Number(statusMatch[1]);
|
|
25184
25317
|
const statusMessage = statusMatch[2]?.trim() ?? "";
|
|
25185
25318
|
const headerMap = {};
|
|
25186
|
-
for (const line of
|
|
25319
|
+
for (const line of head2.split("\r\n").slice(1)) {
|
|
25187
25320
|
const i = line.indexOf(":");
|
|
25188
25321
|
if (i <= 0) continue;
|
|
25189
25322
|
const name = line.slice(0, i).trim().toLowerCase();
|
|
@@ -25203,6 +25336,7 @@ ${lines}\r
|
|
|
25203
25336
|
settled = true;
|
|
25204
25337
|
socket.destroy();
|
|
25205
25338
|
resolve12({
|
|
25339
|
+
ok: true,
|
|
25206
25340
|
status,
|
|
25207
25341
|
statusMessage,
|
|
25208
25342
|
headers: headerMap,
|
|
@@ -25218,16 +25352,16 @@ ${lines}\r
|
|
|
25218
25352
|
fail2(new Error("upstream closed early"));
|
|
25219
25353
|
return;
|
|
25220
25354
|
}
|
|
25221
|
-
const
|
|
25355
|
+
const head2 = buf.subarray(0, sep).toString("latin1");
|
|
25222
25356
|
const statusMatch = /^HTTP\/1\.[01] (\d+)(?: (.*))?/.exec(
|
|
25223
|
-
|
|
25357
|
+
head2.split("\r\n")[0] ?? ""
|
|
25224
25358
|
);
|
|
25225
25359
|
if (!statusMatch) {
|
|
25226
25360
|
fail2(new Error("bad upstream status"));
|
|
25227
25361
|
return;
|
|
25228
25362
|
}
|
|
25229
25363
|
const headerMap = {};
|
|
25230
|
-
for (const line of
|
|
25364
|
+
for (const line of head2.split("\r\n").slice(1)) {
|
|
25231
25365
|
const i = line.indexOf(":");
|
|
25232
25366
|
if (i <= 0) continue;
|
|
25233
25367
|
headerMap[line.slice(0, i).trim().toLowerCase()] = line.slice(i + 1).trim();
|
|
@@ -25242,6 +25376,7 @@ ${lines}\r
|
|
|
25242
25376
|
}
|
|
25243
25377
|
settled = true;
|
|
25244
25378
|
resolve12({
|
|
25379
|
+
ok: true,
|
|
25245
25380
|
status: Number(statusMatch[1]),
|
|
25246
25381
|
statusMessage: statusMatch[2]?.trim() ?? "",
|
|
25247
25382
|
headers: headerMap,
|
|
@@ -25317,6 +25452,8 @@ function authorizeOp(policy, op, url, method, headers) {
|
|
|
25317
25452
|
async function startInterceptProxy(options = {}) {
|
|
25318
25453
|
let policy = options.policy ?? null;
|
|
25319
25454
|
const serveMock = options.serveMock;
|
|
25455
|
+
const resolver = options.resolver ?? defaultResolver2;
|
|
25456
|
+
const dial = options.dial ?? defaultDial;
|
|
25320
25457
|
let activeMocks = 0;
|
|
25321
25458
|
const mockAborts = /* @__PURE__ */ new Set();
|
|
25322
25459
|
let stopped = false;
|
|
@@ -25411,8 +25548,24 @@ async function startInterceptProxy(options = {}) {
|
|
|
25411
25548
|
method,
|
|
25412
25549
|
target,
|
|
25413
25550
|
forwardHeaders,
|
|
25414
|
-
requestBody
|
|
25551
|
+
requestBody,
|
|
25552
|
+
{
|
|
25553
|
+
resolver,
|
|
25554
|
+
dial,
|
|
25555
|
+
localOrigins: effectiveLocalOrigins(active)
|
|
25556
|
+
}
|
|
25415
25557
|
);
|
|
25558
|
+
if (!upstream.ok) {
|
|
25559
|
+
if (!res.headersSent) {
|
|
25560
|
+
res.writeHead(upstream.status, {
|
|
25561
|
+
"cache-control": "no-store",
|
|
25562
|
+
"content-length": "0",
|
|
25563
|
+
connection: "close"
|
|
25564
|
+
});
|
|
25565
|
+
res.end();
|
|
25566
|
+
}
|
|
25567
|
+
return;
|
|
25568
|
+
}
|
|
25416
25569
|
let responseBody = upstream.body;
|
|
25417
25570
|
if (responseOp !== null && active !== null) {
|
|
25418
25571
|
if (responseBody.byteLength > RUNTIME_LIMITS.maxResponseBodyBytes) {
|
|
@@ -25608,25 +25761,52 @@ async function startInterceptProxy(options = {}) {
|
|
|
25608
25761
|
);
|
|
25609
25762
|
}
|
|
25610
25763
|
function handleConnect(req, clientSocket, head) {
|
|
25611
|
-
|
|
25612
|
-
|
|
25613
|
-
|
|
25614
|
-
|
|
25615
|
-
|
|
25616
|
-
|
|
25764
|
+
void tunnelConnect(req, clientSocket, head);
|
|
25765
|
+
}
|
|
25766
|
+
async function tunnelConnect(req, clientSocket, head) {
|
|
25767
|
+
let upstream;
|
|
25768
|
+
clientSocket.on("error", () => upstream?.destroy());
|
|
25769
|
+
const parsed = parseConnectAuthority(req.url ?? "");
|
|
25770
|
+
if (parsed === null) {
|
|
25771
|
+
endConnect(clientSocket, 400, "Bad Request");
|
|
25772
|
+
return;
|
|
25773
|
+
}
|
|
25774
|
+
if (parsed.port !== 443) {
|
|
25775
|
+
endConnect(clientSocket, 403, "Forbidden");
|
|
25617
25776
|
return;
|
|
25618
25777
|
}
|
|
25619
|
-
const
|
|
25620
|
-
|
|
25778
|
+
const pinned = await pinHostname(
|
|
25779
|
+
parsed.host,
|
|
25780
|
+
httpsOrigin(parsed.host) ?? "",
|
|
25781
|
+
{
|
|
25782
|
+
resolver,
|
|
25783
|
+
dial,
|
|
25784
|
+
localOrigins: effectiveLocalOrigins(policy)
|
|
25785
|
+
}
|
|
25786
|
+
);
|
|
25787
|
+
if (pinned === null || clientSocket.destroyed) {
|
|
25788
|
+
endConnect(clientSocket, 403, "Forbidden");
|
|
25789
|
+
return;
|
|
25790
|
+
}
|
|
25791
|
+
let upstreamSocket;
|
|
25792
|
+
try {
|
|
25793
|
+
upstreamSocket = dial(443, pinned.address);
|
|
25794
|
+
} catch {
|
|
25795
|
+
endConnect(clientSocket, 502, "Bad Gateway");
|
|
25796
|
+
return;
|
|
25797
|
+
}
|
|
25798
|
+
upstream = upstreamSocket;
|
|
25799
|
+
upstreamSocket.on("connect", () => {
|
|
25621
25800
|
clientSocket.write("HTTP/1.1 200 Connection Established\r\n\r\n");
|
|
25622
|
-
if (head.byteLength > 0)
|
|
25623
|
-
pipeSockets(clientSocket,
|
|
25801
|
+
if (head.byteLength > 0) upstreamSocket.write(head);
|
|
25802
|
+
pipeSockets(clientSocket, upstreamSocket);
|
|
25624
25803
|
});
|
|
25625
|
-
|
|
25626
|
-
clientSocket.
|
|
25627
|
-
|
|
25804
|
+
upstreamSocket.on("error", () => {
|
|
25805
|
+
if (!clientSocket.destroyed && !clientSocket.writableEnded) {
|
|
25806
|
+
endConnect(clientSocket, 502, "Bad Gateway");
|
|
25807
|
+
}
|
|
25808
|
+
upstreamSocket.destroy();
|
|
25628
25809
|
});
|
|
25629
|
-
clientSocket.on("error", () => upstream.destroy());
|
|
25630
25810
|
}
|
|
25631
25811
|
const endpoint = await new Promise((resolve12, reject) => {
|
|
25632
25812
|
server.once("error", reject);
|
|
@@ -25677,7 +25857,10 @@ async function startInterception(activation, policyDigest, extensionId, pacRoute
|
|
|
25677
25857
|
const sessionId = `session-${activation.startedAt}-${Math.random().toString(36).slice(2)}`;
|
|
25678
25858
|
let proxy;
|
|
25679
25859
|
try {
|
|
25680
|
-
const started = await registeredProvider.start(
|
|
25860
|
+
const started = await registeredProvider.start({
|
|
25861
|
+
...activation,
|
|
25862
|
+
localOrigins: targetPolicy.localOrigins
|
|
25863
|
+
});
|
|
25681
25864
|
if (started && typeof started === "object" && typeof started.host === "string" && typeof started.port === "number") {
|
|
25682
25865
|
proxy = started;
|
|
25683
25866
|
} else if (activation.proxy) {
|
|
@@ -27414,6 +27597,25 @@ function createNativeHost(options) {
|
|
|
27414
27597
|
...options.clock ? { clock: options.clock } : {}
|
|
27415
27598
|
});
|
|
27416
27599
|
let interceptProxy = null;
|
|
27600
|
+
function policyForProxy(activation) {
|
|
27601
|
+
const policy = controller.getActivePolicy();
|
|
27602
|
+
if (!policy) return null;
|
|
27603
|
+
const fromProject = localOriginsFromProject(policy.project);
|
|
27604
|
+
const fromSession = activation.localOrigins ?? [];
|
|
27605
|
+
const localOrigins = [];
|
|
27606
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27607
|
+
for (const origin of [...fromProject, ...fromSession]) {
|
|
27608
|
+
if (seen.has(origin)) continue;
|
|
27609
|
+
seen.add(origin);
|
|
27610
|
+
localOrigins.push(origin);
|
|
27611
|
+
}
|
|
27612
|
+
return {
|
|
27613
|
+
project: policy.project,
|
|
27614
|
+
operations: policy.operations,
|
|
27615
|
+
presetDigest: policy.presetDigest,
|
|
27616
|
+
localOrigins
|
|
27617
|
+
};
|
|
27618
|
+
}
|
|
27417
27619
|
let outboundWrite = null;
|
|
27418
27620
|
let hostRequestCounter = 0;
|
|
27419
27621
|
const pendingHost = /* @__PURE__ */ new Map();
|
|
@@ -27482,18 +27684,13 @@ function createNativeHost(options) {
|
|
|
27482
27684
|
} catch {
|
|
27483
27685
|
}
|
|
27484
27686
|
},
|
|
27485
|
-
async startTlsProxy() {
|
|
27687
|
+
async startTlsProxy(activation) {
|
|
27486
27688
|
if (interceptProxy) {
|
|
27487
27689
|
await interceptProxy.stop();
|
|
27488
27690
|
interceptProxy = null;
|
|
27489
27691
|
}
|
|
27490
|
-
const policy = controller.getActivePolicy();
|
|
27491
27692
|
interceptProxy = await startInterceptProxy({
|
|
27492
|
-
policy:
|
|
27493
|
-
project: policy.project,
|
|
27494
|
-
operations: policy.operations,
|
|
27495
|
-
presetDigest: policy.presetDigest
|
|
27496
|
-
} : null,
|
|
27693
|
+
policy: policyForProxy(activation),
|
|
27497
27694
|
serveMock: (request) => controller.serveMock(request.token, {
|
|
27498
27695
|
method: request.method,
|
|
27499
27696
|
signal: request.signal
|
|
@@ -27516,14 +27713,7 @@ function createNativeHost(options) {
|
|
|
27516
27713
|
async start(activation) {
|
|
27517
27714
|
const routes = pendingRoutes.length > 0 ? pendingRoutes : activation.pacRoutes;
|
|
27518
27715
|
const endpoint = await platformProvider.start(activation, routes);
|
|
27519
|
-
|
|
27520
|
-
interceptProxy?.setPolicy(
|
|
27521
|
-
policy ? {
|
|
27522
|
-
project: policy.project,
|
|
27523
|
-
operations: policy.operations,
|
|
27524
|
-
presetDigest: policy.presetDigest
|
|
27525
|
-
} : null
|
|
27526
|
-
);
|
|
27716
|
+
interceptProxy?.setPolicy(policyForProxy(activation));
|
|
27527
27717
|
return endpoint;
|
|
27528
27718
|
},
|
|
27529
27719
|
async stop() {
|
package/package.json
CHANGED