From b3a256700f4215f3dbf9d54ef033bd3e3c26f486 Mon Sep 17 00:00:00 2001 From: Zach Willard <zach.willard@gmail.com> Date: Sun, 3 Nov 2019 01:38:17 -0600 Subject: [PATCH] fix(docker): added a workaround for ports not being set correctly during a redirect to S3 (#4733) --- lib/datasource/docker/index.ts | 46 ++++++++++++++--------- test/util/got.spec.ts | 69 ++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 17 deletions(-) create mode 100644 test/util/got.spec.ts diff --git a/lib/datasource/docker/index.ts b/lib/datasource/docker/index.ts index 260db1131f..65fe046632 100644 --- a/lib/datasource/docker/index.ts +++ b/lib/datasource/docker/index.ts @@ -434,23 +434,7 @@ async function getLabels( return {}; } const url = `${registry}/v2/${repository}/blobs/${configDigest}`; - const configResponse = await got(url, { - headers, - hooks: { - beforeRedirect: [ - (options: any) => { - if ( - options.search && - options.search.indexOf('X-Amz-Algorithm') !== -1 - ) { - // docker registry is hosted on amazon, redirect url includes authentication. - // eslint-disable-next-line no-param-reassign - delete options.headers.authorization; - } - }, - ], - }, - }); + const configResponse = await getConfigResponse(url, headers); labels = JSON.parse(configResponse.body).config.Labels; if (labels) { @@ -509,6 +493,34 @@ async function getLabels( } } +export function getConfigResponse(url: string, headers: OutgoingHttpHeaders) { + return got(url, { + headers, + hooks: { + beforeRedirect: [ + (options: any) => { + if ( + options.search && + options.search.indexOf('X-Amz-Algorithm') !== -1 + ) { + // if there is no port in the redirect URL string, then delete it from the redirect options. + // This can be evaluated for removal after upgrading to Got v10 + const portInUrl = options.href.split('/')[2].split(':')[1]; + if (!portInUrl) { + // eslint-disable-next-line no-param-reassign + delete options.port; // Redirect will instead use 80 or 443 for HTTP or HTTPS respectively + } + + // docker registry is hosted on amazon, redirect url includes authentication. + // eslint-disable-next-line no-param-reassign + delete options.headers.authorization; + } + }, + ], + }, + }); +} + /** * docker.getPkgReleases * diff --git a/test/util/got.spec.ts b/test/util/got.spec.ts new file mode 100644 index 0000000000..9ccc40c6d9 --- /dev/null +++ b/test/util/got.spec.ts @@ -0,0 +1,69 @@ +import nock from 'nock'; +import { getConfigResponse } from '../../lib/datasource/docker'; + +describe('getConfigResponse', () => { + beforeEach(() => { + nock.disableNetConnect(); + }); + + afterEach(() => { + nock.cleanAll(); + nock.enableNetConnect(); + }); + + it('redirects correctly when the original and redirect url both have a port', async () => { + const url = + 'http://docker.registry.com:5000/v2/image:latest/blobs/some-digest'; + const redirectURL = + 'https://s3.aws.amazon.com:3000/docker/registry/v2/blobs/sha256/d4/some-digest/data?X-Amz-Algorithm=AWS4-HMAC-SHA256'; + nock('http://docker.registry.com:5000') + .get('/v2/image:latest/blobs/some-digest') + .reply(307, undefined, { + location: redirectURL, + }); + nock('https://s3.aws.amazon.com:3000') + .get( + '/docker/registry/v2/blobs/sha256/d4/some-digest/data?X-Amz-Algorithm=AWS4-HMAC-SHA256' + ) + .reply(200, 'test body'); + const response = await getConfigResponse(url, {}); + expect(response.body).toEqual('test body'); + }); + + it('redirects correctly when original url has a port, but the redirect url does not', async () => { + const url = + 'http://docker.registry.com:5001/v2/image:latest/blobs/some-digest'; + const redirectURL = + 'https://s3.aws.amazon.com/docker/registry/v2/blobs/sha256/d4/some-digest/data?X-Amz-Algorithm=AWS4-HMAC-SHA256'; + nock('http://docker.registry.com:5001') + .get('/v2/image:latest/blobs/some-digest') + .reply(307, undefined, { + location: redirectURL, + }); + nock('https://s3.aws.amazon.com') + .get( + '/docker/registry/v2/blobs/sha256/d4/some-digest/data?X-Amz-Algorithm=AWS4-HMAC-SHA256' + ) + .reply(200, 'test body'); + const response = await getConfigResponse(url, {}); + expect(response.body).toEqual('test body'); + }); + + it('redirects correctly when the original url does not have a port, but the redirect to url does', async () => { + const url = 'http://docker.registry.com/v2/image:latest/blobs/some-digest'; + const redirectURL = + 'https://s3.aws.amazon.com:3001/docker/registry/v2/blobs/sha256/d4/some-digest/data?X-Amz-Algorithm=AWS4-HMAC-SHA256'; + nock('http://docker.registry.com') + .get('/v2/image:latest/blobs/some-digest') + .reply(307, undefined, { + location: redirectURL, + }); + nock('https://s3.aws.amazon.com:3001') + .get( + '/docker/registry/v2/blobs/sha256/d4/some-digest/data?X-Amz-Algorithm=AWS4-HMAC-SHA256' + ) + .reply(200, 'test body'); + const response = await getConfigResponse(url, {}); + expect(response.body).toEqual('test body'); + }); +}); -- GitLab