feat: 基于 cloudflare 的 worker 制作 dockerhub 代理

master
李建龙 2 months ago
parent afc5f86895
commit cd380fc312

2
.gitignore vendored

@ -170,3 +170,5 @@ dist
.dev.vars
.wrangler/
.idea/

@ -10,10 +10,10 @@
"cf-typegen": "wrangler types"
},
"devDependencies": {
"@cloudflare/vitest-pool-workers": "^0.5.2",
"@cloudflare/vitest-pool-workers": "^0.5.32",
"@cloudflare/workers-types": "^4.20241202.0",
"typescript": "^5.5.2",
"typescript": "^5.7.2",
"vitest": "2.0.5",
"wrangler": "^3.60.3"
"wrangler": "^3.91.0"
}
}

@ -6,20 +6,20 @@ settings:
devDependencies:
'@cloudflare/vitest-pool-workers':
specifier: ^0.5.2
version: 0.5.2(@cloudflare/workers-types@4.20241202.0)(@vitest/runner@2.0.5)(@vitest/snapshot@2.0.5)(vitest@2.0.5)
specifier: ^0.5.32
version: 0.5.32(@cloudflare/workers-types@4.20241202.0)(@vitest/runner@2.1.8)(@vitest/snapshot@2.1.8)(vitest@2.0.5)
'@cloudflare/workers-types':
specifier: ^4.20241202.0
version: 4.20241202.0
typescript:
specifier: ^5.5.2
version: 5.5.2
specifier: ^5.7.2
version: 5.7.2
vitest:
specifier: 2.0.5
version: 2.0.5
wrangler:
specifier: ^3.60.3
version: 3.60.3(@cloudflare/workers-types@4.20241202.0)
specifier: ^3.91.0
version: 3.91.0(@cloudflare/workers-types@4.20241202.0)
packages:
@ -31,13 +31,6 @@ packages:
'@jridgewell/trace-mapping': 0.3.25
dev: true
/@cloudflare/kv-asset-handler@0.3.2:
resolution: {integrity: sha512-EeEjMobfuJrwoctj7FA1y1KEbM0+Q1xSjobIEyie9k4haVEBB7vkDvsasw1pM3rO39mL2akxIAzLMUAtrMHZhA==}
engines: {node: '>=16.13'}
dependencies:
mime: 3.0.0
dev: true
/@cloudflare/kv-asset-handler@0.3.4:
resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==}
engines: {node: '>=16.13'}
@ -45,23 +38,23 @@ packages:
mime: 3.0.0
dev: true
/@cloudflare/vitest-pool-workers@0.5.2(@cloudflare/workers-types@4.20241202.0)(@vitest/runner@2.0.5)(@vitest/snapshot@2.0.5)(vitest@2.0.5):
resolution: {integrity: sha512-4VuIRDBQ1FJcFjoDYxlOPDeNtxYYjtz2TMPkm9bKnCssf+7K71VVuwkbV31PmLOclaenFcSLuyvygVXtZ9DgtA==}
/@cloudflare/vitest-pool-workers@0.5.32(@cloudflare/workers-types@4.20241202.0)(@vitest/runner@2.1.8)(@vitest/snapshot@2.1.8)(vitest@2.0.5):
resolution: {integrity: sha512-lJHwXq3VWKgzy7BzXs61O/QukT9QQ42hl27eRcqCV6P20OF4/bLH8rmUaYxdR8IxLlmNY7Q5h0wGN0nXBn8XKg==}
peerDependencies:
'@vitest/runner': 2.0.x
'@vitest/snapshot': 2.0.x
vitest: 2.0.x
'@vitest/runner': 2.0.x - 2.1.x
'@vitest/snapshot': 2.0.x - 2.1.x
vitest: 2.0.x - 2.1.x
dependencies:
'@vitest/runner': 2.0.5
'@vitest/snapshot': 2.0.5
'@vitest/runner': 2.1.8
'@vitest/snapshot': 2.1.8
birpc: 0.2.14
cjs-module-lexer: 1.4.1
devalue: 4.3.3
esbuild: 0.17.19
miniflare: 3.20240909.1
miniflare: 3.20241106.1
semver: 7.6.3
vitest: 2.0.5
wrangler: 3.78.2(@cloudflare/workers-types@4.20241202.0)
wrangler: 3.91.0(@cloudflare/workers-types@4.20241202.0)
zod: 3.23.8
transitivePeerDependencies:
- '@cloudflare/workers-types'
@ -70,8 +63,8 @@ packages:
- utf-8-validate
dev: true
/@cloudflare/workerd-darwin-64@1.20240610.1:
resolution: {integrity: sha512-YanZ1iXgMGaUWlleB5cswSE6qbzyjQ8O7ENWZcPAcZZ6BfuL7q3CWi0t9iM1cv2qx92rRztsRTyjcfq099++XQ==}
/@cloudflare/workerd-darwin-64@1.20241106.1:
resolution: {integrity: sha512-zxvaToi1m0qzAScrxFt7UvFVqU8DxrCO2CinM1yQkv5no7pA1HolpIrwZ0xOhR3ny64Is2s/J6BrRjpO5dM9Zw==}
engines: {node: '>=16'}
cpu: [x64]
os: [darwin]
@ -79,26 +72,8 @@ packages:
dev: true
optional: true
/@cloudflare/workerd-darwin-64@1.20240909.0:
resolution: {integrity: sha512-nJ8jm/6PR8DPzVb4QifNAfSdrFZXNblwIdOhLTU5FpSvFFocmzFX5WgzQagvtmcC9/ZAQyxuf7WynDNyBcoe0Q==}
engines: {node: '>=16'}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@cloudflare/workerd-darwin-arm64@1.20240610.1:
resolution: {integrity: sha512-bRe/y/LKjIgp3L2EHjc+CvoCzfHhf4aFTtOBkv2zW+VToNJ4KlXridndf7LvR9urfsFRRo9r4TXCssuKaU+ypQ==}
engines: {node: '>=16'}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@cloudflare/workerd-darwin-arm64@1.20240909.0:
resolution: {integrity: sha512-gJqKa811oSsoxy9xuoQn7bS0Hr1sY+o3EUORTcEnulG6Kz9NQ6nd8QNdp2Hrk2jmmSqwrNkn+a6PZkWzk6Q0Gw==}
/@cloudflare/workerd-darwin-arm64@1.20241106.1:
resolution: {integrity: sha512-j3dg/42D/bPgfNP3cRUBxF+4waCKO/5YKwXNj+lnVOwHxDu+ne5pFw9TIkKYcWTcwn0ZUkbNZNM5rhJqRn4xbg==}
engines: {node: '>=16'}
cpu: [arm64]
os: [darwin]
@ -106,8 +81,8 @@ packages:
dev: true
optional: true
/@cloudflare/workerd-linux-64@1.20240610.1:
resolution: {integrity: sha512-2zDcadR7+Gs9SjcMXmwsMji2Xs+yASGNA2cEHDuFc4NMUup+eL1mkzxc/QzvFjyBck98e92rBjMZt2dVscpGKg==}
/@cloudflare/workerd-linux-64@1.20241106.1:
resolution: {integrity: sha512-Ih+Ye8E1DMBXcKrJktGfGztFqHKaX1CeByqshmTbODnWKHt6O65ax3oTecUwyC0+abuyraOpAtdhHNpFMhUkmw==}
engines: {node: '>=16'}
cpu: [x64]
os: [linux]
@ -115,17 +90,8 @@ packages:
dev: true
optional: true
/@cloudflare/workerd-linux-64@1.20240909.0:
resolution: {integrity: sha512-sJrmtccfMg73sZljiBpe4R+lhF58TqzqhF2pQG8HRjyxkzkM1sjpZqfEFaIkNUDqd3/Ibji49fklhPCGXljKSg==}
engines: {node: '>=16'}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@cloudflare/workerd-linux-arm64@1.20240610.1:
resolution: {integrity: sha512-7y41rPi5xmIYJN8CY+t3RHnjLL0xx/WYmaTd/j552k1qSr02eTE2o/TGyWZmGUC+lWnwdPQJla0mXbvdqgRdQg==}
/@cloudflare/workerd-linux-arm64@1.20241106.1:
resolution: {integrity: sha512-mdQFPk4+14Yywn7n1xIzI+6olWM8Ybz10R7H3h+rk0XulMumCWUCy1CzIDauOx6GyIcSgKIibYMssVHZR30ObA==}
engines: {node: '>=16'}
cpu: [arm64]
os: [linux]
@ -133,26 +99,8 @@ packages:
dev: true
optional: true
/@cloudflare/workerd-linux-arm64@1.20240909.0:
resolution: {integrity: sha512-dTbSdceyRXPOSER+18AwYRbPQG0e/Dwl2trmfMMCETkfJhNLv1fU3FFMJPjfILijKnhTZHSnHCx0+xwHdon2fg==}
engines: {node: '>=16'}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@cloudflare/workerd-windows-64@1.20240610.1:
resolution: {integrity: sha512-B0LyT3DB6rXHWNptnntYHPaoJIy0rXnGfeDBM3nEVV8JIsQrx8MEFn2F2jYioH1FkUVavsaqKO/zUosY3tZXVA==}
engines: {node: '>=16'}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@cloudflare/workerd-windows-64@1.20240909.0:
resolution: {integrity: sha512-/d4BT0kcWFa7Qc0K4K9+cwVQ1qyPNKiO42JZUijlDlco+TYTPkLO3qGEohmwbfMq+BieK7JTMSgjO81ZHpA0HQ==}
/@cloudflare/workerd-windows-64@1.20241106.1:
resolution: {integrity: sha512-4rtcss31E/Rb/PeFocZfr+B9i1MdrkhsTBWizh8siNR4KMmkslU2xs2wPaH1z8+ErxkOsHrKRa5EPLh5rIiFeg==}
engines: {node: '>=16'}
cpu: [x64]
os: [win32]
@ -160,8 +108,8 @@ packages:
dev: true
optional: true
/@cloudflare/workers-shared@0.5.3:
resolution: {integrity: sha512-Yk5Im7zsyKbzd7qi+DrL7ZJR9+bdZwq9BqZWS4muDIWA8MCUeSLsUC+C9u+jdwfPSi5It2AcQG4f0iwZr6jkkQ==}
/@cloudflare/workers-shared@0.9.0:
resolution: {integrity: sha512-eP6Ir45uPbKnpADVzUCtkRUYxYxjB1Ew6n/whTJvHu8H4m93USHAceCMm736VBZdlxuhXXUjEP3fCUxKPn+cfw==}
engines: {node: '>=16.7.0'}
dependencies:
mime: 3.0.0
@ -832,6 +780,13 @@ packages:
pathe: 1.1.2
dev: true
/@vitest/runner@2.1.8:
resolution: {integrity: sha512-17ub8vQstRnRlIU5k50bG+QOMLHRhYPAna5tw8tYbj+jzjcspnwnwtPtiOlkuKC4+ixDPTuLZiqiWWQ2PSXHVg==}
dependencies:
'@vitest/utils': 2.1.8
pathe: 1.1.2
dev: true
/@vitest/snapshot@2.0.5:
resolution: {integrity: sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==}
dependencies:
@ -840,6 +795,14 @@ packages:
pathe: 1.1.2
dev: true
/@vitest/snapshot@2.1.8:
resolution: {integrity: sha512-20T7xRFbmnkfcmgVEz+z3AU/3b0cEzZOt/zmnvZEctg64/QZbSDJEVm9fLnnlSi74KibmRsO9/Qabi+t0vCRPg==}
dependencies:
'@vitest/pretty-format': 2.1.8
magic-string: 0.30.14
pathe: 1.1.2
dev: true
/@vitest/spy@2.0.5:
resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==}
dependencies:
@ -855,6 +818,14 @@ packages:
tinyrainbow: 1.2.0
dev: true
/@vitest/utils@2.1.8:
resolution: {integrity: sha512-dwSoui6djdwbfFmIgbIjX2ZhIoG7Ex/+xpxyiEgIGzjliY8xGkcpITKTlp6B4MgtGkF2ilvm97cPM96XZaAgcA==}
dependencies:
'@vitest/pretty-format': 2.1.8
loupe: 3.1.2
tinyrainbow: 1.2.0
dev: true
/acorn-walk@8.3.4:
resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==}
engines: {node: '>=0.4.0'}
@ -868,14 +839,6 @@ packages:
hasBin: true
dev: true
/anymatch@3.1.3:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
dependencies:
normalize-path: 3.0.0
picomatch: 2.3.1
dev: true
/as-table@1.0.55:
resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==}
dependencies:
@ -887,11 +850,6 @@ packages:
engines: {node: '>=12'}
dev: true
/binary-extensions@2.3.0:
resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
engines: {node: '>=8'}
dev: true
/birpc@0.2.14:
resolution: {integrity: sha512-37FHE8rqsYM5JEKCnXFyHpBCzvgHEExwVVTq+nUmloInU7l8ezD1TpOhKpS8oe1DTYFqEK27rFZVKG43oTqXRA==}
dev: true
@ -900,13 +858,6 @@ packages:
resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==}
dev: true
/braces@3.0.3:
resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
engines: {node: '>=8'}
dependencies:
fill-range: 7.1.1
dev: true
/cac@6.7.14:
resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==}
engines: {node: '>=8'}
@ -937,30 +888,17 @@ packages:
engines: {node: '>= 16'}
dev: true
/chokidar@3.6.0:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
/chokidar@4.0.1:
resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==}
engines: {node: '>= 14.16.0'}
dependencies:
anymatch: 3.1.3
braces: 3.0.3
glob-parent: 5.1.2
is-binary-path: 2.1.0
is-glob: 4.0.3
normalize-path: 3.0.0
readdirp: 3.6.0
optionalDependencies:
fsevents: 2.3.3
readdirp: 4.0.2
dev: true
/cjs-module-lexer@1.4.1:
resolution: {integrity: sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==}
dev: true
/consola@3.2.3:
resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==}
engines: {node: ^14.18.0 || >=16.10.0}
dev: true
/cookie@0.7.2:
resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==}
engines: {node: '>= 0.6'}
@ -979,8 +917,8 @@ packages:
resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==}
dev: true
/date-fns@3.6.0:
resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==}
/date-fns@4.1.0:
resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==}
dev: true
/debug@4.3.7:
@ -1104,13 +1042,6 @@ packages:
engines: {node: '>=6'}
dev: true
/fill-range@7.1.1:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
dependencies:
to-regex-range: 5.0.1
dev: true
/fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@ -1135,13 +1066,6 @@ packages:
engines: {node: '>=16'}
dev: true
/glob-parent@5.1.2:
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
engines: {node: '>= 6'}
dependencies:
is-glob: 4.0.3
dev: true
/glob-to-regexp@0.4.1:
resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==}
dev: true
@ -1158,13 +1082,6 @@ packages:
engines: {node: '>=16.17.0'}
dev: true
/is-binary-path@2.1.0:
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
engines: {node: '>=8'}
dependencies:
binary-extensions: 2.3.0
dev: true
/is-core-module@2.15.1:
resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==}
engines: {node: '>= 0.4'}
@ -1172,23 +1089,6 @@ packages:
hasown: 2.0.2
dev: true
/is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
dev: true
/is-glob@4.0.3:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
dependencies:
is-extglob: 2.1.1
dev: true
/is-number@7.0.0:
resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
engines: {node: '>=0.12.0'}
dev: true
/is-stream@3.0.0:
resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@ -1198,6 +1098,10 @@ packages:
resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
dev: true
/itty-time@1.0.6:
resolution: {integrity: sha512-+P8IZaLLBtFv8hCkIjcymZOp4UJ+xW6bSlQsXGqrkmJh7vSiMFSlNne0mCYagEE0N7HDNR5jJBRxwN0oYv61Rw==}
dev: true
/loupe@3.1.2:
resolution: {integrity: sha512-23I4pFZHmAemUnz8WZXbYRSKYj801VDaNv9ETuMh7IrMc7VuVVSo+Z9iLE3ni30+U48iDWfi30d3twAXBYmnCg==}
dev: true
@ -1229,31 +1133,8 @@ packages:
engines: {node: '>=12'}
dev: true
/miniflare@3.20240610.0:
resolution: {integrity: sha512-J6aXmkII5gcq+kC4TurxKiR4rC++apPST/K8P/YjqoQQgrJ+NRPacBhf6iVh8R3ujnXYXaq+Ae+gm+LM0XHK/w==}
engines: {node: '>=16.13'}
hasBin: true
dependencies:
'@cspotcode/source-map-support': 0.8.1
acorn: 8.14.0
acorn-walk: 8.3.4
capnp-ts: 0.7.0
exit-hook: 2.2.1
glob-to-regexp: 0.4.1
stoppable: 1.1.0
undici: 5.28.4
workerd: 1.20240610.1
ws: 8.18.0
youch: 3.3.4
zod: 3.23.8
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
dev: true
/miniflare@3.20240909.1:
resolution: {integrity: sha512-tdzJFApHmqFYlpjfpqBDnsE6dHUDLHejBrNgXftLfTf/ni5NySgXKnuntCCMdRtnTpjUKmkHiusGrBCf9b1rnA==}
/miniflare@3.20241106.1:
resolution: {integrity: sha512-dM3RBlJE8rUFxnqlPCaFCq0E7qQqEQvKbYX7W/APGCK+rLcyLmEBzC4GQR/niXdNM/oV6gdg9AA50ghnn2ALuw==}
engines: {node: '>=16.13'}
hasBin: true
dependencies:
@ -1265,7 +1146,7 @@ packages:
glob-to-regexp: 0.4.1
stoppable: 1.1.0
undici: 5.28.4
workerd: 1.20240909.0
workerd: 1.20241106.1
ws: 8.18.0
youch: 3.3.4
zod: 3.23.8
@ -1290,20 +1171,11 @@ packages:
hasBin: true
dev: true
/node-fetch-native@1.6.4:
resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==}
dev: true
/node-forge@1.3.1:
resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==}
engines: {node: '>= 6.13.0'}
dev: true
/normalize-path@3.0.0:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
dev: true
/npm-run-path@5.3.0:
resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@ -1353,11 +1225,6 @@ packages:
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
dev: true
/picomatch@2.3.1:
resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
engines: {node: '>=8.6'}
dev: true
/postcss@8.4.49:
resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==}
engines: {node: ^10 || ^12 || >=14}
@ -1371,11 +1238,9 @@ packages:
resolution: {integrity: sha512-dKp+C4iXWK4vVYZmYSd0KBH5F/h1HoZRsbJ82AVKRO3PEo8L4lBS/vLwhVtpwwuYcoIsVY+1JYKR268yn480uQ==}
dev: true
/readdirp@3.6.0:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
dependencies:
picomatch: 2.3.1
/readdirp@4.0.2:
resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==}
engines: {node: '>= 14.16.0'}
dev: true
/resolve.exports@2.0.3:
@ -1540,19 +1405,12 @@ packages:
engines: {node: '>=14.0.0'}
dev: true
/to-regex-range@5.0.1:
resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
engines: {node: '>=8.0'}
dependencies:
is-number: 7.0.0
dev: true
/tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
dev: true
/typescript@5.5.2:
resolution: {integrity: sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==}
/typescript@5.7.2:
resolution: {integrity: sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==}
engines: {node: '>=14.17'}
hasBin: true
dev: true
@ -1572,19 +1430,8 @@ packages:
'@fastify/busboy': 2.1.1
dev: true
/unenv-nightly@1.10.0-1717606461.a117952:
resolution: {integrity: sha512-u3TfBX02WzbHTpaEfWEKwDijDSFAHcgXkayUZ+MVDrjhLFvgAJzFGTSTmwlEhwWi2exyRQey23ah9wELMM6etg==}
dependencies:
consola: 3.2.3
defu: 6.1.4
mime: 3.0.0
node-fetch-native: 1.6.4
pathe: 1.1.2
ufo: 1.5.4
dev: true
/unenv-nightly@2.0.0-1724863496.70db6f1:
resolution: {integrity: sha512-r+VIl1gnsI4WQxluruSQhy8alpAf1AsLRLm4sEKp3otCyTIVD6I6wHEYzeQnwsyWgaD4+3BD4A/eqrgOpdTzhw==}
/unenv-nightly@2.0.0-20241121-161142-806b5c0:
resolution: {integrity: sha512-RnFOasE/O0Q55gBkNB1b84OgKttgLEijGO0JCWpbn+O4XxpyCQg89NmcqQ5RGUiy4y+rMIrKzePTquQcLQF5pQ==}
dependencies:
defu: 6.1.4
ohash: 1.1.4
@ -1724,94 +1571,48 @@ packages:
stackback: 0.0.2
dev: true
/workerd@1.20240610.1:
resolution: {integrity: sha512-Rtut5GrsODQMh6YU43b9WZ980Wd05Ov1/ds88pT/SoetmXFBvkBzdRfiHiATv+azmGX8KveE0i/Eqzk/yI01ug==}
/workerd@1.20241106.1:
resolution: {integrity: sha512-1GdKl0kDw8rrirr/ThcK66Kbl4/jd4h8uHx5g7YHBrnenY5SX1UPuop2cnCzYUxlg55kPjzIqqYslz1muRFgFw==}
engines: {node: '>=16'}
hasBin: true
requiresBuild: true
optionalDependencies:
'@cloudflare/workerd-darwin-64': 1.20240610.1
'@cloudflare/workerd-darwin-arm64': 1.20240610.1
'@cloudflare/workerd-linux-64': 1.20240610.1
'@cloudflare/workerd-linux-arm64': 1.20240610.1
'@cloudflare/workerd-windows-64': 1.20240610.1
dev: true
/workerd@1.20240909.0:
resolution: {integrity: sha512-NwuYh/Fgr/MK0H+Ht687sHl/f8tumwT5CWzYR0MZMHri8m3CIYu2IaY4tBFWoKE/tOU1Z5XjEXECa9zXY4+lwg==}
engines: {node: '>=16'}
hasBin: true
requiresBuild: true
optionalDependencies:
'@cloudflare/workerd-darwin-64': 1.20240909.0
'@cloudflare/workerd-darwin-arm64': 1.20240909.0
'@cloudflare/workerd-linux-64': 1.20240909.0
'@cloudflare/workerd-linux-arm64': 1.20240909.0
'@cloudflare/workerd-windows-64': 1.20240909.0
dev: true
/wrangler@3.60.3(@cloudflare/workers-types@4.20241202.0):
resolution: {integrity: sha512-a6zn/KFnYaYp3nxJR/aP0TeaBvJDkrrfI89KoxUtx28H7zpya/5/VLu3CxQ3PRspEojJGF0s6f3/pddRy3F+BQ==}
engines: {node: '>=16.17.0'}
hasBin: true
peerDependencies:
'@cloudflare/workers-types': ^4.20240605.0
peerDependenciesMeta:
'@cloudflare/workers-types':
optional: true
dependencies:
'@cloudflare/kv-asset-handler': 0.3.2
'@cloudflare/workers-types': 4.20241202.0
'@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19)
'@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19)
blake3-wasm: 2.1.5
chokidar: 3.6.0
esbuild: 0.17.19
miniflare: 3.20240610.0
nanoid: 3.3.8
path-to-regexp: 6.3.0
resolve: 1.22.8
resolve.exports: 2.0.3
selfsigned: 2.4.1
source-map: 0.6.1
unenv: /unenv-nightly@1.10.0-1717606461.a117952
xxhash-wasm: 1.1.0
optionalDependencies:
fsevents: 2.3.3
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
'@cloudflare/workerd-darwin-64': 1.20241106.1
'@cloudflare/workerd-darwin-arm64': 1.20241106.1
'@cloudflare/workerd-linux-64': 1.20241106.1
'@cloudflare/workerd-linux-arm64': 1.20241106.1
'@cloudflare/workerd-windows-64': 1.20241106.1
dev: true
/wrangler@3.78.2(@cloudflare/workers-types@4.20241202.0):
resolution: {integrity: sha512-PL7GchswGrNm2OvdSw5yG3ZAqNjpaQIO++p8E1TaCi63DSyssKFYeYqTvfFshsQPP2u1dox5JFXtLc6IE/m1xw==}
/wrangler@3.91.0(@cloudflare/workers-types@4.20241202.0):
resolution: {integrity: sha512-Hdzn6wbY9cz5kL85ZUvWLwLIH7nPaEVRblfms40jhRf4qQO/Zf74aFlku8rQFbe8/2aVZFaxJVfBd6JQMeMSBQ==}
engines: {node: '>=16.17.0'}
hasBin: true
peerDependencies:
'@cloudflare/workers-types': ^4.20240909.0
'@cloudflare/workers-types': ^4.20241106.0
peerDependenciesMeta:
'@cloudflare/workers-types':
optional: true
dependencies:
'@cloudflare/kv-asset-handler': 0.3.4
'@cloudflare/workers-shared': 0.5.3
'@cloudflare/workers-shared': 0.9.0
'@cloudflare/workers-types': 4.20241202.0
'@esbuild-plugins/node-globals-polyfill': 0.2.3(esbuild@0.17.19)
'@esbuild-plugins/node-modules-polyfill': 0.2.2(esbuild@0.17.19)
blake3-wasm: 2.1.5
chokidar: 3.6.0
date-fns: 3.6.0
chokidar: 4.0.1
date-fns: 4.1.0
esbuild: 0.17.19
miniflare: 3.20240909.1
itty-time: 1.0.6
miniflare: 3.20241106.1
nanoid: 3.3.8
path-to-regexp: 6.3.0
resolve: 1.22.8
resolve.exports: 2.0.3
selfsigned: 2.4.1
source-map: 0.6.1
unenv: /unenv-nightly@2.0.0-1724863496.70db6f1
workerd: 1.20240909.0
unenv: /unenv-nightly@2.0.0-20241121-161142-806b5c0
workerd: 1.20241106.1
xxhash-wasm: 1.1.0
optionalDependencies:
fsevents: 2.3.3

@ -1,18 +1,159 @@
/**
* Welcome to Cloudflare Workers! This is your first worker.
*
* - Run `npm run dev` in your terminal to start a development server
* - Open a browser tab at http://localhost:8787/ to see your worker in action
* - Run `npm run deploy` to publish your worker
*
* Bind resources to your worker in `wrangler.toml`. After adding bindings, a type definition for the
* `Env` object can be regenerated with `npm run cf-typegen`.
*
* Learn more at https://developers.cloudflare.com/workers/
*/
const DOCKER_HUB = 'https://registry-1.docker.io';
const PROXY_MAP: Record<string, string> = {
[`docker.`]: DOCKER_HUB,
[`quay.`]: 'https://quay.io',
[`gcr.`]: 'https://gcr.io',
[`k8s-gcr.`]: 'https://k8s.gcr.io',
[`k8s.`]: 'https://registry.k8s.io',
[`ghcr.`]: 'https://ghcr.io',
[`cloudsmith.`]: 'https://docker.cloudsmith.io',
[`ecr.`]: 'https://public.ecr.aws'
};
function getUpstream(hostname: string): string {
for (const [prefix, upstream] of Object.entries(PROXY_MAP)) {
if (hostname.startsWith(prefix)) {
return upstream;
}
}
throw new Error(`No upstream found for ${hostname}`);
}
async function upstream_v2(url: URL, authorization: string | null): Promise<Response> {
const newUrl = URL.parse('/v2/', getUpstream(url.hostname));
if (!newUrl) {
return new Response('Invalid upstream', { status: 500 });
}
const headers = new Headers();
if (authorization) {
headers.set('Authorization', authorization);
}
const res = await fetch(newUrl.toString(), { method: 'GET', headers, redirect: 'follow' });
if (res.status === 401) {
return new Response(res.statusText, {
status: res.status,
headers: { 'WWW-Authenticate': `Bearer realm="https://${url.hostname}/v2/auth",service="cloudflare-docker-proxy` }
});
}
return res;
}
async function upstream_v2_auth(url: URL, authorization: string | null): Promise<Response> {
const upstream = getUpstream(url.hostname);
const newUrl = URL.parse('/v2/', upstream);
if (!newUrl) {
return new Response('Invalid upstream', { status: 500 });
}
const res = await fetch(newUrl.toString(), { method: 'GET', redirect: 'follow' });
if (res.status !== 401) {
return res;
}
const wwwAuthenticate = res.headers.get('WWW-Authenticate');
if (!wwwAuthenticate) {
return res;
}
const authenticate = parseAuthenticate(wwwAuthenticate);
const isDockerHub = upstream === DOCKER_HUB;
let scope = url.searchParams.get('scope');
if (!!scope && isDockerHub) {
let scopeParts = scope.split(':');
if (scopeParts.length === 3 && !scopeParts[1].includes('/')) {
scopeParts[1] = 'library/' + scopeParts[1];
scope = scopeParts.join(':');
}
}
const realmUrl = new URL(authenticate.realm);
if (authenticate.service.length) {
realmUrl.searchParams.set('service', authenticate.service);
}
if (scope) {
realmUrl.searchParams.set('scope', scope);
}
const headers = new Headers();
if (authorization) {
headers.set('Authorization', authorization);
}
return await fetch(realmUrl, { method: 'GET', headers });
}
function parseAuthenticate(authenticate: string) {
// sample: Bearer realm="https://auth.ipv6.docker.com/token",service="registry.docker.io"
// match strings after =" and before "
const reg = /(?<==")(?:\\.|[^"\\])*(?=")/g;
const matches = authenticate.match(reg);
if (matches == null || matches.length < 2) {
throw new Error(`invalid Www-Authenticate Header: ${authenticate}`);
}
return {
realm: matches[0],
service: matches[1]
};
}
export default {
async fetch(request, env, ctx): Promise<Response> {
return new Response('Hello World!');
},
try {
const url = new URL(request.url);
const authorization = request.headers.get('Authorization');
if (url.pathname === '/v2/') {
return await upstream_v2(url, authorization);
}
if (url.pathname === '/v2/auth') {
return await upstream_v2_auth(url, authorization);
}
const upstream = getUpstream(url.hostname);
const isDockerHub = upstream === DOCKER_HUB;
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.toString(), 302);
}
}
const proxyUrl = URL.parse(url.pathname, upstream);
if (!proxyUrl) {
return new Response('Invalid upstream', { status: 500 });
}
const req = new Request(proxyUrl, {
method: request.method,
headers: request.headers,
redirect: 'follow'
});
const res = await fetch(req);
if (res.status === 401) {
return new Response(res.statusText, {
status: res.status,
headers: { 'WWW-Authenticate': `Bearer realm="https://${url.hostname}/v2/auth",service="cloudflare-docker-proxy` }
});
}
return res;
} catch (e: any) {
return new Response(e.message, { status: 500 });
}
}
} satisfies ExportedHandler<Env>;

@ -1,4 +1,5 @@
// Generated by Wrangler
// After adding bindings to `wrangler.toml`, regenerate this interface via `npm run cf-typegen`
// Generated by Wrangler by running `wrangler types`
// eslint-disable-next-line @typescript-eslint/no-empty-interface,@typescript-eslint/no-empty-object-type
interface Env {
}

@ -4,11 +4,23 @@ main = "src/index.ts"
compatibility_date = "2024-12-02"
compatibility_flags = ["nodejs_compat"]
# 发布时配置自己的域名前缀
routes = [
{ pattern = "docker.xxx.com", custom_domain = true },
{ pattern = "k8s.xxx.com", custom_domain = true }
]
workers_dev = false
# Workers Logs
# Docs: https://developers.cloudflare.com/workers/observability/logs/workers-logs/
# Configuration: https://developers.cloudflare.com/workers/observability/logs/workers-logs/#enable-workers-logs
[observability]
enabled = false
[observability.logs]
enabled = true
head_sampling_rate = 1
invocation_logs = true
# Automatically place your workloads in an optimal location to minimize latency.
# If you are running back-end logic in a Worker, running it closer to your back-end infrastructure
@ -22,8 +34,8 @@ enabled = true
# - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables
# Note: Use secrets to store sensitive data.
# - https://developers.cloudflare.com/workers/configuration/secrets/
# [vars]
# MY_VARIABLE = "production_value"
#[vars]
#CUSTOM_DOMAIN = ""
# Bind the Workers AI model catalog. Run machine learning models, powered by serverless GPUs, on Cloudflares global network
# Docs: https://developers.cloudflare.com/workers/wrangler/configuration/#workers-ai

Loading…
Cancel
Save