@@ -24,6 +24,10 @@ type AuthContext = {
2424 scope : string ;
2525} ;
2626
27+ function isDockerDotIO ( url : URL ) : boolean {
28+ return url . host . endsWith ( "docker.io" ) ;
29+ }
30+
2731type HTTPContext = {
2832 // The auth context for this request
2933 authContext : AuthContext ;
@@ -149,14 +153,35 @@ export class RegistryHTTPClient implements Registry {
149153 }
150154
151155 authBase64 ( ) : string {
156+ const configuration = this . configuration ;
157+ if ( configuration . username === undefined ) {
158+ return "" ;
159+ }
160+
152161 return btoa ( this . configuration . username + ":" + this . password ( ) ) ;
153162 }
154163
155164 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 ] ?? "" ;
157171 }
158172
159173 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+
160185 const res = await fetch ( `${ this . url . protocol } //${ this . url . host } /v2/` , {
161186 headers : {
162187 "User-Agent" : "Docker-Client/24.0.5 (linux)" ,
@@ -165,16 +190,7 @@ export class RegistryHTTPClient implements Registry {
165190 } ) ;
166191
167192 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 ;
178194 }
179195
180196 if ( res . status !== 401 ) {
@@ -212,11 +228,12 @@ export class RegistryHTTPClient implements Registry {
212228 async authenticateBearerSimple ( ctx : AuthContext , params : URLSearchParams ) : Promise < Response > {
213229 params . delete ( "password" ) ;
214230 console . log ( "sending authentication parameters:" , ctx . realm + "?" + params . toString ( ) ) ;
231+
215232 return await fetch ( ctx . realm + "?" + params . toString ( ) , {
216233 headers : {
217- "Authorization" : "Basic " + this . authBase64 ( ) ,
218234 "Accept" : "application/json" ,
219235 "User-Agent" : "Docker-Client/24.0.5 (linux)" ,
236+ ...( this . configuration . username !== undefined ? { Authorization : "Basic " + this . authBase64 ( ) } : { } ) ,
220237 } ,
221238 } ) ;
222239 }
@@ -227,8 +244,8 @@ export class RegistryHTTPClient implements Registry {
227244 // explicitely include that we don't want an offline_token.
228245 scope : `repository:${ ctx . scope } :pull,push` ,
229246 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 ( ) ,
232249 } ) ;
233250 let response = await fetch ( ctx . realm , {
234251 headers : {
@@ -313,7 +330,7 @@ export class RegistryHTTPClient implements Registry {
313330 }
314331
315332 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 } ` ;
317334 try {
318335 const ctx = await this . authenticate ( namespace ) ;
319336 const req = ctxIntoRequest ( ctx , this . url , "HEAD" , `${ namespace } /manifests/${ tag } ` ) ;
@@ -342,7 +359,7 @@ export class RegistryHTTPClient implements Registry {
342359 }
343360
344361 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 } ` ;
346363 try {
347364 const ctx = await this . authenticate ( namespace ) ;
348365 const req = ctxIntoRequest ( ctx , this . url , "GET" , `${ namespace } /manifests/${ digest } ` ) ;
@@ -374,7 +391,7 @@ export class RegistryHTTPClient implements Registry {
374391 }
375392
376393 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 } ` ;
378395 try {
379396 const ctx = await this . authenticate ( namespace ) ;
380397 const res = await fetch ( ctxIntoRequest ( ctx , this . url , "HEAD" , `${ namespace } /blobs/${ digest } ` ) ) ;
@@ -414,7 +431,7 @@ export class RegistryHTTPClient implements Registry {
414431 }
415432
416433 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 } ` ;
418435 try {
419436 const ctx = await this . authenticate ( namespace ) ;
420437 const req = ctxIntoRequest ( ctx , this . url , "GET" , `${ namespace } /blobs/${ digest } ` ) ;
@@ -468,7 +485,7 @@ export class RegistryHTTPClient implements Registry {
468485 _namespace : string ,
469486 _reference : string ,
470487 _readableStream : ReadableStream < any > ,
471- _contentType : string ,
488+ { } : { } ,
472489 ) : Promise < PutManifestResponse | RegistryError > {
473490 throw new Error ( "unimplemented" ) ;
474491 }
0 commit comments