@@ -24,6 +24,11 @@ type AuthContext = {
24
24
scope : string ;
25
25
} ;
26
26
27
+ export function isDockerDotIO ( url : URL ) : boolean {
28
+ const regex = / ^ h t t p s : \/ \/ ( [ \w \d ] + \. ) ? d o c k e r \. i o $ / ;
29
+ return regex . test ( url . origin ) ;
30
+ }
31
+
27
32
type HTTPContext = {
28
33
// The auth context for this request
29
34
authContext : AuthContext ;
@@ -149,14 +154,35 @@ export class RegistryHTTPClient implements Registry {
149
154
}
150
155
151
156
authBase64 ( ) : string {
157
+ const configuration = this . configuration ;
158
+ if ( configuration . username === undefined ) {
159
+ return "" ;
160
+ }
161
+
152
162
return btoa ( this . configuration . username + ":" + this . password ( ) ) ;
153
163
}
154
164
155
165
password ( ) : string {
156
- return ( this . env as unknown as Record < string , string > ) [ this . configuration . password_env ] ?? "" ;
166
+ const configuration = this . configuration ;
167
+ if ( configuration . username === undefined ) {
168
+ return "" ;
169
+ }
170
+
171
+ return ( this . env as unknown as Record < string , string > ) [ configuration . password_env ] ?? "" ;
157
172
}
158
173
159
174
async authenticate ( namespace : string ) : Promise < HTTPContext > {
175
+ const emptyAuthentication = {
176
+ authContext : {
177
+ authType : "none" ,
178
+ realm : "" ,
179
+ scope : "" ,
180
+ service : this . url . host ,
181
+ } ,
182
+ repository : this . url . pathname ,
183
+ accessToken : "" ,
184
+ } as const ;
185
+
160
186
const res = await fetch ( `${ this . url . protocol } //${ this . url . host } /v2/` , {
161
187
headers : {
162
188
"User-Agent" : "Docker-Client/24.0.5 (linux)" ,
@@ -165,16 +191,7 @@ export class RegistryHTTPClient implements Registry {
165
191
} ) ;
166
192
167
193
if ( res . ok ) {
168
- return {
169
- authContext : {
170
- authType : "none" ,
171
- realm : "" ,
172
- scope : "" ,
173
- service : this . url . host ,
174
- } ,
175
- repository : this . url . pathname ,
176
- accessToken : "" ,
177
- } ;
194
+ return emptyAuthentication ;
178
195
}
179
196
180
197
if ( res . status !== 401 ) {
@@ -212,11 +229,12 @@ export class RegistryHTTPClient implements Registry {
212
229
async authenticateBearerSimple ( ctx : AuthContext , params : URLSearchParams ) : Promise < Response > {
213
230
params . delete ( "password" ) ;
214
231
console . log ( "sending authentication parameters:" , ctx . realm + "?" + params . toString ( ) ) ;
232
+
215
233
return await fetch ( ctx . realm + "?" + params . toString ( ) , {
216
234
headers : {
217
- "Authorization" : "Basic " + this . authBase64 ( ) ,
218
235
"Accept" : "application/json" ,
219
236
"User-Agent" : "Docker-Client/24.0.5 (linux)" ,
237
+ ...( this . configuration . username !== undefined ? { Authorization : "Basic " + this . authBase64 ( ) } : { } ) ,
220
238
} ,
221
239
} ) ;
222
240
}
@@ -227,8 +245,8 @@ export class RegistryHTTPClient implements Registry {
227
245
// explicitely include that we don't want an offline_token.
228
246
scope : `repository:${ ctx . scope } :pull,push` ,
229
247
client_id : "r2registry" ,
230
- grant_type : "password" ,
231
- password : this . password ( ) ,
248
+ grant_type : this . configuration . username === undefined ? "none" : "password" ,
249
+ password : this . configuration . username === undefined ? "" : this . password ( ) ,
232
250
} ) ;
233
251
let response = await fetch ( ctx . realm , {
234
252
headers : {
@@ -313,7 +331,7 @@ export class RegistryHTTPClient implements Registry {
313
331
}
314
332
315
333
async manifestExists ( name : string , tag : string ) : Promise < CheckManifestResponse | RegistryError > {
316
- const namespace = name . includes ( "/" ) ? name : `library/${ name } ` ;
334
+ const namespace = name . includes ( "/" ) || ! isDockerDotIO ( this . url ) ? name : `library/${ name } ` ;
317
335
try {
318
336
const ctx = await this . authenticate ( namespace ) ;
319
337
const req = ctxIntoRequest ( ctx , this . url , "HEAD" , `${ namespace } /manifests/${ tag } ` ) ;
@@ -342,7 +360,7 @@ export class RegistryHTTPClient implements Registry {
342
360
}
343
361
344
362
async getManifest ( name : string , digest : string ) : Promise < GetManifestResponse | RegistryError > {
345
- const namespace = name . includes ( "/" ) ? name : `library/${ name } ` ;
363
+ const namespace = name . includes ( "/" ) || ! isDockerDotIO ( this . url ) ? name : `library/${ name } ` ;
346
364
try {
347
365
const ctx = await this . authenticate ( namespace ) ;
348
366
const req = ctxIntoRequest ( ctx , this . url , "GET" , `${ namespace } /manifests/${ digest } ` ) ;
@@ -374,7 +392,7 @@ export class RegistryHTTPClient implements Registry {
374
392
}
375
393
376
394
async layerExists ( name : string , digest : string ) : Promise < CheckLayerResponse | RegistryError > {
377
- const namespace = name . includes ( "/" ) ? name : `library/${ name } ` ;
395
+ const namespace = name . includes ( "/" ) || ! isDockerDotIO ( this . url ) ? name : `library/${ name } ` ;
378
396
try {
379
397
const ctx = await this . authenticate ( namespace ) ;
380
398
const res = await fetch ( ctxIntoRequest ( ctx , this . url , "HEAD" , `${ namespace } /blobs/${ digest } ` ) ) ;
@@ -414,7 +432,7 @@ export class RegistryHTTPClient implements Registry {
414
432
}
415
433
416
434
async getLayer ( name : string , digest : string ) : Promise < GetLayerResponse | RegistryError > {
417
- const namespace = name . includes ( "/" ) ? name : `library/${ name } ` ;
435
+ const namespace = name . includes ( "/" ) || ! isDockerDotIO ( this . url ) ? name : `library/${ name } ` ;
418
436
try {
419
437
const ctx = await this . authenticate ( namespace ) ;
420
438
const req = ctxIntoRequest ( ctx , this . url , "GET" , `${ namespace } /blobs/${ digest } ` ) ;
@@ -468,7 +486,7 @@ export class RegistryHTTPClient implements Registry {
468
486
_namespace : string ,
469
487
_reference : string ,
470
488
_readableStream : ReadableStream < any > ,
471
- _contentType : string ,
489
+ { } : { } ,
472
490
) : Promise < PutManifestResponse | RegistryError > {
473
491
throw new Error ( "unimplemented" ) ;
474
492
}
0 commit comments