1 Commits

Author SHA1 Message Date
ciiiii
c737c70c48 Fix DockerHub library images default pulling case 2024-06-14 01:44:53 +08:00

View File

@@ -3,8 +3,10 @@ addEventListener("fetch", (event) => {
event.respondWith(handleRequest(event.request)); event.respondWith(handleRequest(event.request));
}); });
const dockerHub = "https://registry-1.docker.io";
const routes = { const routes = {
"docker.libcuda.so": "https://registry-1.docker.io", "docker.libcuda.so": dockerHub,
"quay.libcuda.so": "https://quay.io", "quay.libcuda.so": "https://quay.io",
"gcr.libcuda.so": "https://gcr.io", "gcr.libcuda.so": "https://gcr.io",
"k8s-gcr.libcuda.so": "https://k8s.gcr.io", "k8s-gcr.libcuda.so": "https://k8s.gcr.io",
@@ -36,6 +38,7 @@ async function handleRequest(request) {
} }
); );
} }
const isDockerHub = upstream == dockerHub;
const authorization = request.headers.get("Authorization"); const authorization = request.headers.get("Authorization");
if (url.pathname == "/v2/") { if (url.pathname == "/v2/") {
const newUrl = new URL(upstream + "/v2/"); const newUrl = new URL(upstream + "/v2/");
@@ -84,7 +87,28 @@ async function handleRequest(request) {
return resp; return resp;
} }
const wwwAuthenticate = parseAuthenticate(authenticateStr); const wwwAuthenticate = parseAuthenticate(authenticateStr);
return await fetchToken(wwwAuthenticate, url.searchParams, authorization); let scope = url.searchParams.get("scope");
// autocomplete repo part into scope for DockerHub library images
// Example: repository:busybox:pull => repository:library/busybox:pull
if (scope && isDockerHub) {
let scopeParts = scope.split(":");
if (scopeParts.length == 3 && !scopeParts[1].includes("/")) {
scopeParts[1] = "library/" + scopeParts[1];
scope = scopeParts.join(":");
}
}
return await fetchToken(wwwAuthenticate, scope, authorization);
}
// redirect for DockerHub library images
// Example: /v2/busybox/manifests/latest => /v2/library/busybox/manifests/latest
if (isDockerHub) {
const pathParts = url.pathname.split("/");
if (pathParts.length == 5) {
pathParts.splice(2, 0, "library");
const redirectUrl = new URL(url);
redirectUrl.pathname = pathParts.join("/");
return Response.redirect(redirectUrl, 301);
}
} }
// foward requests // foward requests
const newUrl = new URL(upstream + url.pathname); const newUrl = new URL(upstream + url.pathname);
@@ -101,7 +125,7 @@ function parseAuthenticate(authenticateStr) {
// match strings after =" and before " // match strings after =" and before "
const re = /(?<=\=")(?:\\.|[^"\\])*(?=")/g; const re = /(?<=\=")(?:\\.|[^"\\])*(?=")/g;
const matches = authenticateStr.match(re); const matches = authenticateStr.match(re);
if (matches === null || matches.length < 2) { if (matches == null || matches.length < 2) {
throw new Error(`invalid Www-Authenticate Header: ${authenticateStr}`); throw new Error(`invalid Www-Authenticate Header: ${authenticateStr}`);
} }
return { return {
@@ -110,13 +134,13 @@ function parseAuthenticate(authenticateStr) {
}; };
} }
async function fetchToken(wwwAuthenticate, searchParams, authorization) { async function fetchToken(wwwAuthenticate, scope, authorization) {
const url = new URL(wwwAuthenticate.realm); const url = new URL(wwwAuthenticate.realm);
if (wwwAuthenticate.service.length) { if (wwwAuthenticate.service.length) {
url.searchParams.set("service", wwwAuthenticate.service); url.searchParams.set("service", wwwAuthenticate.service);
} }
if (searchParams.get("scope")) { if (scope) {
url.searchParams.set("scope", searchParams.get("scope")); url.searchParams.set("scope", scope);
} }
headers = new Headers(); headers = new Headers();
if (authorization) { if (authorization) {