From 3d4d2529a13cf86659ac3967b91736edace96968 Mon Sep 17 00:00:00 2001 From: Rhys Arkins <rhys@arkins.net> Date: Wed, 28 Jul 2021 08:07:20 +0200 Subject: [PATCH] refactor(docker): better url parsing (#10996) --- lib/datasource/docker/common.ts | 5 ++++- lib/datasource/docker/index.spec.ts | 1 + lib/datasource/docker/index.ts | 4 +++- lib/util/url.spec.ts | 13 +++++++++++++ lib/util/url.ts | 9 +++++++++ 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/datasource/docker/common.ts b/lib/datasource/docker/common.ts index b90cf21ea0..f50a1ae99d 100644 --- a/lib/datasource/docker/common.ts +++ b/lib/datasource/docker/common.ts @@ -196,7 +196,10 @@ export function getRegistryRepository( } let dockerRepository = split.join('/'); if (!registryHost) { - registryHost = registryUrl; + registryHost = registryUrl.replace( + 'https://docker.io', + 'https://index.docker.io' + ); } if (registryHost === 'docker.io') { registryHost = 'index.docker.io'; diff --git a/lib/datasource/docker/index.spec.ts b/lib/datasource/docker/index.spec.ts index 7be603c7cb..965c272c86 100644 --- a/lib/datasource/docker/index.spec.ts +++ b/lib/datasource/docker/index.spec.ts @@ -391,6 +391,7 @@ describe(getName(), () => { const res = await getPkgReleases({ datasource: id, depName: 'node', + registryUrls: ['https://docker.io'], }); expect(res).toBeNull(); expect(httpMock.getTrace()).toMatchSnapshot(); diff --git a/lib/datasource/docker/index.ts b/lib/datasource/docker/index.ts index 3c2739cdb3..f81fc9f8de 100644 --- a/lib/datasource/docker/index.ts +++ b/lib/datasource/docker/index.ts @@ -3,6 +3,7 @@ import parseLinkHeader from 'parse-link-header'; import { logger } from '../../logger'; import { ExternalHostError } from '../../types/errors/external-host-error'; import * as packageCache from '../../util/cache/package'; +import { ensurePathPrefix } from '../../util/url'; import { api as dockerVersioning, id as dockerVersioningId, @@ -65,7 +66,8 @@ async function getDockerApiTags( // AWS ECR limits the maximum number of results to 1000 // See https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_DescribeRepositories.html#ECR-DescribeRepositories-request-maxResults const limit = ecrRegex.test(registryHost) ? 1000 : 10000; - let url = `${registryHost}/v2/${dockerRepository}/tags/list?n=${limit}`; + let url = `${registryHost}/${dockerRepository}/tags/list?n=${limit}`; + url = ensurePathPrefix(url, '/v2'); const headers = await getAuthHeaders(registryHost, dockerRepository); if (!headers) { logger.debug('Failed to get authHeaders for getTags lookup'); diff --git a/lib/util/url.spec.ts b/lib/util/url.spec.ts index e6425b7a84..a3ed562d9a 100644 --- a/lib/util/url.spec.ts +++ b/lib/util/url.spec.ts @@ -1,5 +1,6 @@ import { getName } from '../../test/util'; import { + ensurePathPrefix, parseUrl, resolveBaseUrl, trimTrailingSlash, @@ -77,4 +78,16 @@ describe(getName(), () => { expect(trimTrailingSlash('foo/')).toBe('foo'); expect(trimTrailingSlash('foo//////')).toBe('foo'); }); + + it('ensures path prefix', () => { + expect(ensurePathPrefix('https://index.docker.io', '/v2')).toBe( + 'https://index.docker.io/v2' + ); + expect(ensurePathPrefix('https://index.docker.io/v2', '/v2')).toBe( + 'https://index.docker.io/v2' + ); + expect( + ensurePathPrefix('https://index.docker.io/v2/something', '/v2') + ).toBe('https://index.docker.io/v2/something'); + }); }); diff --git a/lib/util/url.ts b/lib/util/url.ts index 0c9b975f7e..b84548b241 100644 --- a/lib/util/url.ts +++ b/lib/util/url.ts @@ -1,5 +1,14 @@ import urlJoin from 'url-join'; +export function ensurePathPrefix(url: string, prefix: string): string { + const parsed = new URL(url); + const fullPath = url.replace(parsed.origin, ''); + if (fullPath.startsWith(prefix)) { + return url; + } + return parsed.origin + prefix + fullPath; +} + export function ensureTrailingSlash(url: string): string { return url.replace(/\/?$/, '/'); } -- GitLab