@skydiveai/git-cache 0.1.0-beta.1642 → 0.1.0-beta.2411
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/cli.mjs +1 -1
- package/dist/index.d.mts +1 -0
- package/dist/index.mjs +1 -1
- package/dist/{server-B4o5hA96.mjs → server-DDcKo4yG.mjs} +30 -17
- package/package.json +1 -10
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as isProtocolV2Request, c as parseAdvertisement, d as shouldBackfillAfterPassthrough, f as startServer, i as explainRejection, l as parseUpstream, n as classifyUploadRequest, o as metricsSnapshot, r as copyRequestHeaders, s as mirrorHasObjects, t as SidebandPackExtractor, u as recordColdBuildOutcome } from "./server-
|
|
1
|
+
import { a as isProtocolV2Request, c as parseAdvertisement, d as shouldBackfillAfterPassthrough, f as startServer, i as explainRejection, l as parseUpstream, n as classifyUploadRequest, o as metricsSnapshot, r as copyRequestHeaders, s as mirrorHasObjects, t as SidebandPackExtractor, u as recordColdBuildOutcome } from "./server-DDcKo4yG.mjs";
|
|
2
2
|
export { SidebandPackExtractor, classifyUploadRequest, copyRequestHeaders, explainRejection, isProtocolV2Request, metricsSnapshot, mirrorHasObjects, parseAdvertisement, parseUpstream, recordColdBuildOutcome, shouldBackfillAfterPassthrough, startServer };
|
|
@@ -298,12 +298,12 @@ function evictAuthCache() {
|
|
|
298
298
|
}
|
|
299
299
|
function validateUpstream(credHeader, upstreamUrl) {
|
|
300
300
|
return new Promise((resolve) => {
|
|
301
|
-
const
|
|
301
|
+
const target = new URL(`${upstreamUrl}/info/refs?service=git-upload-pack`);
|
|
302
|
+
const headers = { "user-agent": "git/git-cache-authz" };
|
|
303
|
+
if (credHeader !== null) headers["authorization"] = credHeader;
|
|
304
|
+
const request = requestUpstream(target, {
|
|
302
305
|
method: "GET",
|
|
303
|
-
headers
|
|
304
|
-
authorization: credHeader,
|
|
305
|
-
"user-agent": "git/git-cache-authz"
|
|
306
|
-
}
|
|
306
|
+
headers
|
|
307
307
|
}, (res) => {
|
|
308
308
|
res.resume();
|
|
309
309
|
const status = res.statusCode ?? 502;
|
|
@@ -341,7 +341,7 @@ function validateUpstream(credHeader, upstreamUrl) {
|
|
|
341
341
|
});
|
|
342
342
|
}
|
|
343
343
|
async function authorizeCheckThrough(credHeader, repo, upstreamUrl) {
|
|
344
|
-
const key = authMemoKey(credHeader, repo);
|
|
344
|
+
const key = authMemoKey(credHeader ?? "", repo);
|
|
345
345
|
const cached = authCache.get(key);
|
|
346
346
|
if (cached) {
|
|
347
347
|
const ttl = cached.allowed ? AUTH_ALLOW_TTL_MS : AUTH_DENY_TTL_MS;
|
|
@@ -1679,6 +1679,16 @@ async function proxyInfoRefs(req, res, repo, upstreamUrl, host, credHeader) {
|
|
|
1679
1679
|
}, cred);
|
|
1680
1680
|
});
|
|
1681
1681
|
}
|
|
1682
|
+
function requestErrorContext(req) {
|
|
1683
|
+
const rawTarget = req.url ?? "";
|
|
1684
|
+
const target = (rawTarget.split("?", 1)[0] ?? "").replace(/^\/[^/?#@]+@/, "/[redacted]@").replace(/^(https?:\/\/)[^/?#@]+@/, "$1[redacted]@");
|
|
1685
|
+
return {
|
|
1686
|
+
method: req.method ?? null,
|
|
1687
|
+
target,
|
|
1688
|
+
targetLength: rawTarget.length,
|
|
1689
|
+
peer: req.socket?.remoteAddress ?? null
|
|
1690
|
+
};
|
|
1691
|
+
}
|
|
1682
1692
|
async function handle(req, res) {
|
|
1683
1693
|
const parsed = new URL(req.url, "http://git-cache.local");
|
|
1684
1694
|
if (parsed.pathname === "/healthz") {
|
|
@@ -1735,16 +1745,15 @@ async function handle(req, res) {
|
|
|
1735
1745
|
if (config.authMode === "check-through") {
|
|
1736
1746
|
const header = req.headers["authorization"];
|
|
1737
1747
|
const raw = Array.isArray(header) ? header[0] : header;
|
|
1738
|
-
|
|
1739
|
-
metrics.auth_denials++;
|
|
1740
|
-
res.writeHead(401, {
|
|
1741
|
-
"Content-Type": "text/plain",
|
|
1742
|
-
"WWW-Authenticate": "Basic realm=\"git-cache\""
|
|
1743
|
-
});
|
|
1744
|
-
return res.end("authentication required\n");
|
|
1745
|
-
}
|
|
1746
|
-
const verdict = await authorizeCheckThrough(raw, up.repo, up.upstreamUrl);
|
|
1748
|
+
const verdict = await authorizeCheckThrough(raw ?? null, up.repo, up.upstreamUrl);
|
|
1747
1749
|
if (!verdict.allowed) {
|
|
1750
|
+
if (!raw && (verdict.status === 401 || verdict.status === 403)) {
|
|
1751
|
+
res.writeHead(401, {
|
|
1752
|
+
"Content-Type": "text/plain",
|
|
1753
|
+
"WWW-Authenticate": "Basic realm=\"git-cache\""
|
|
1754
|
+
});
|
|
1755
|
+
return res.end("authentication required\n");
|
|
1756
|
+
}
|
|
1748
1757
|
log("info", "auth_denied", {
|
|
1749
1758
|
repo: up.repo,
|
|
1750
1759
|
status: verdict.status
|
|
@@ -1752,7 +1761,7 @@ async function handle(req, res) {
|
|
|
1752
1761
|
res.writeHead(verdict.status, { "Content-Type": "text/plain" });
|
|
1753
1762
|
return res.end("not authorized for this repository\n");
|
|
1754
1763
|
}
|
|
1755
|
-
clientCred = raw;
|
|
1764
|
+
clientCred = raw ?? null;
|
|
1756
1765
|
}
|
|
1757
1766
|
const host = up.repo.split("/")[0] ?? "";
|
|
1758
1767
|
let uploadBody = null;
|
|
@@ -1850,7 +1859,11 @@ async function startServer(options = {}) {
|
|
|
1850
1859
|
await cleanupQuarantine();
|
|
1851
1860
|
const server = http.createServer((req, res) => {
|
|
1852
1861
|
handle(req, res).catch((error) => {
|
|
1853
|
-
log("error", "unhandled", {
|
|
1862
|
+
log("error", "unhandled", {
|
|
1863
|
+
error: String(error),
|
|
1864
|
+
stack: error instanceof Error ? error.stack : null,
|
|
1865
|
+
...requestErrorContext(req)
|
|
1866
|
+
});
|
|
1854
1867
|
if (!res.headersSent) res.writeHead(500);
|
|
1855
1868
|
res.end();
|
|
1856
1869
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skydiveai/git-cache",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.2411",
|
|
4
4
|
"description": "Sandbox-local Git smart-HTTP clone/fetch cache: a loopback daemon that transparently mirrors HTTPS git reads so repeated clone/fetch/ls-remote skip the origin round-trip. Runs inside an agent sandbox; pushes stay direct.",
|
|
5
5
|
"homepage": "https://skydive.com",
|
|
6
6
|
"license": "MIT",
|
|
@@ -20,15 +20,6 @@
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"publishConfig": {
|
|
23
|
-
"bin": {
|
|
24
|
-
"git-cache-daemon": "./dist/cli.mjs"
|
|
25
|
-
},
|
|
26
|
-
"exports": {
|
|
27
|
-
".": {
|
|
28
|
-
"types": "./dist/index.d.mts",
|
|
29
|
-
"default": "./dist/index.mjs"
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
23
|
"access": "public",
|
|
33
24
|
"registry": "https://registry.npmjs.org"
|
|
34
25
|
},
|