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