From 03ea6b654c1f7bd3901f7ee8d7ac274f778b8c5b Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Thu, 14 Jun 2018 19:44:33 -0400 Subject: [PATCH 1/6] Retries registry call with HTTP if HTTPS fails. --- .../jib/registry/RegistryEndpointCaller.java | 20 +++++++++++++------ .../registry/RegistryEndpointCallerTest.java | 20 +++++++++++++++++++ 2 files changed, 34 insertions(+), 6 deletions(-) create mode 100644 jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryEndpointCallerTest.java diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java index fe66fad40b..f85a824862 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java @@ -32,6 +32,7 @@ import javax.annotation.Nullable; import javax.net.ssl.SSLPeerUnverifiedException; import org.apache.http.NoHttpResponseException; +import org.apache.http.conn.HttpHostConnectException; /** * Makes requests to a registry endpoint. @@ -50,8 +51,7 @@ private static class RequestState { /** * @param authorization authentication credentials - * @param url the endpoint URL to call, or {@code null} to use default from {@code - * registryEndpointProvider} + * @param url the endpoint URL to call */ private RequestState(@Nullable Authorization authorization, URL url) { this.authorization = authorization; @@ -79,12 +79,11 @@ private RequestState(@Nullable Authorization authorization, URL url) { String apiRouteBase, RegistryEndpointProvider registryEndpointProvider, @Nullable Authorization authorization, - RegistryEndpointProperties registryEndpointProperties) - throws MalformedURLException { + RegistryEndpointProperties registryEndpointProperties) throws MalformedURLException { this.initialRequestState = new RequestState( authorization, - registryEndpointProvider.getApiRoute(DEFAULT_PROTOCOL + "://" + apiRouteBase)); + registryEndpointProvider.getApiRoute(apiRouteBase)); this.userAgent = userAgent; this.registryEndpointProvider = registryEndpointProvider; this.registryEndpointProperties = registryEndpointProperties; @@ -126,7 +125,7 @@ private T call(RequestState requestState) throws IOException, RegistryException if (httpResponseException.getStatusCode() == HttpStatusCodes.STATUS_CODE_BAD_REQUEST || httpResponseException.getStatusCode() == HttpStatusCodes.STATUS_CODE_NOT_FOUND || httpResponseException.getStatusCode() - == HttpStatusCodes.STATUS_CODE_METHOD_NOT_ALLOWED) { + == HttpStatusCodes.STATUS_CODE_METHOD_NOT_ALLOWED) { // The name or reference was invalid. ErrorResponseTemplate errorResponse = JsonTemplateMapper.readJson( @@ -161,6 +160,15 @@ private T call(RequestState requestState) throws IOException, RegistryException } } + } catch (HttpHostConnectException ex) { + // Tries to call with HTTP protocol if HTTPS failed to connect. + if (DEFAULT_PROTOCOL.equals(requestState.url.getProtocol())) { + URL urlWithHttpProtocol = new URL("http", requestState.url.getHost(), requestState.url.getPort(), requestState.url.getFile()); + return call(new RequestState(requestState.authorization, urlWithHttpProtocol)); + } + + throw ex; + } catch (NoHttpResponseException ex) { throw new RegistryNoResponseException(ex); diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryEndpointCallerTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryEndpointCallerTest.java new file mode 100644 index 0000000000..b43e96de58 --- /dev/null +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryEndpointCallerTest.java @@ -0,0 +1,20 @@ +/* + * Copyright 2018 Google LLC. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.google.cloud.tools.jib.registry; + +public class RegistryEndpointCallerTest { +} From 2a9335027b952ff25c7d5e223979171d468c6156 Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Fri, 15 Jun 2018 00:07:32 -0400 Subject: [PATCH 2/6] Adds tests. --- .../jib/registry/RegistryEndpointCaller.java | 51 +++- .../registry/RegistryEndpointProvider.java | 3 +- .../registry/RegistryEndpointCallerTest.java | 257 ++++++++++++++++++ 3 files changed, 297 insertions(+), 14 deletions(-) diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java index f85a824862..661f882fb5 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java @@ -26,9 +26,11 @@ import com.google.cloud.tools.jib.json.JsonTemplateMapper; import com.google.cloud.tools.jib.registry.json.ErrorEntryTemplate; import com.google.cloud.tools.jib.registry.json.ErrorResponseTemplate; +import com.google.common.annotations.VisibleForTesting; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import java.util.function.Function; import javax.annotation.Nullable; import javax.net.ssl.SSLPeerUnverifiedException; import org.apache.http.NoHttpResponseException; @@ -59,6 +61,16 @@ private RequestState(@Nullable Authorization authorization, URL url) { } } + /** Converts the {@link URL}'s protocol to HTTP. */ + private static URL urlWithHttp(URL url) { + GenericUrl httpUrl = new GenericUrl(url); + httpUrl.setScheme("http"); + return httpUrl.toURL(); + } + + /** Makes a {@link Connection} to the specified {@link URL}. */ + private final Function connectionFactory; + private final RequestState initialRequestState; private final String userAgent; private final RegistryEndpointProvider registryEndpointProvider; @@ -79,14 +91,34 @@ private RequestState(@Nullable Authorization authorization, URL url) { String apiRouteBase, RegistryEndpointProvider registryEndpointProvider, @Nullable Authorization authorization, - RegistryEndpointProperties registryEndpointProperties) throws MalformedURLException { + RegistryEndpointProperties registryEndpointProperties) + throws MalformedURLException { + this( + userAgent, + apiRouteBase, + registryEndpointProvider, + authorization, + registryEndpointProperties, + Connection::new); + } + + @VisibleForTesting + RegistryEndpointCaller( + String userAgent, + String apiRouteBase, + RegistryEndpointProvider registryEndpointProvider, + @Nullable Authorization authorization, + RegistryEndpointProperties registryEndpointProperties, + Function connectionFactory) + throws MalformedURLException { this.initialRequestState = new RequestState( authorization, - registryEndpointProvider.getApiRoute(apiRouteBase)); + registryEndpointProvider.getApiRoute(DEFAULT_PROTOCOL + "://" + apiRouteBase)); this.userAgent = userAgent; this.registryEndpointProvider = registryEndpointProvider; this.registryEndpointProperties = registryEndpointProperties; + this.connectionFactory = connectionFactory; } /** @@ -104,7 +136,7 @@ T call() throws IOException, RegistryException { /** Calls the registry endpoint with a certain {@link RequestState}. */ @Nullable private T call(RequestState requestState) throws IOException, RegistryException { - try (Connection connection = new Connection(requestState.url)) { + try (Connection connection = connectionFactory.apply(requestState.url)) { Request request = Request.builder() .setAuthorization(requestState.authorization) @@ -125,7 +157,7 @@ private T call(RequestState requestState) throws IOException, RegistryException if (httpResponseException.getStatusCode() == HttpStatusCodes.STATUS_CODE_BAD_REQUEST || httpResponseException.getStatusCode() == HttpStatusCodes.STATUS_CODE_NOT_FOUND || httpResponseException.getStatusCode() - == HttpStatusCodes.STATUS_CODE_METHOD_NOT_ALLOWED) { + == HttpStatusCodes.STATUS_CODE_METHOD_NOT_ALLOWED) { // The name or reference was invalid. ErrorResponseTemplate errorResponse = JsonTemplateMapper.readJson( @@ -160,23 +192,16 @@ private T call(RequestState requestState) throws IOException, RegistryException } } - } catch (HttpHostConnectException ex) { + } catch (HttpHostConnectException | SSLPeerUnverifiedException ex) { // Tries to call with HTTP protocol if HTTPS failed to connect. if (DEFAULT_PROTOCOL.equals(requestState.url.getProtocol())) { - URL urlWithHttpProtocol = new URL("http", requestState.url.getHost(), requestState.url.getPort(), requestState.url.getFile()); - return call(new RequestState(requestState.authorization, urlWithHttpProtocol)); + return call(new RequestState(requestState.authorization, urlWithHttp(requestState.url))); } throw ex; } catch (NoHttpResponseException ex) { throw new RegistryNoResponseException(ex); - - } catch (SSLPeerUnverifiedException ex) { - // Fall-back to HTTP - GenericUrl httpUrl = new GenericUrl(requestState.url); - httpUrl.setScheme("http"); - return call(new RequestState(requestState.authorization, httpUrl.toURL())); } } } diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointProvider.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointProvider.java index bd32592e74..e34201540f 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointProvider.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointProvider.java @@ -36,7 +36,8 @@ interface RegistryEndpointProvider { String getHttpMethod(); /** - * @param apiRouteBase the registry's base URL (for example, {@code https://gcr.io/v2/}) + * @param apiRouteBase the registry's base URL without the protocol (for example, {@code + * gcr.io/v2/}) * @return the registry endpoint URL */ URL getApiRoute(String apiRouteBase) throws MalformedURLException; diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryEndpointCallerTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryEndpointCallerTest.java index b43e96de58..eb6ab98347 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryEndpointCallerTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/registry/RegistryEndpointCallerTest.java @@ -16,5 +16,262 @@ package com.google.cloud.tools.jib.registry; +import com.google.api.client.http.HttpHeaders; +import com.google.api.client.http.HttpResponse; +import com.google.api.client.http.HttpResponseException; +import com.google.api.client.http.HttpStatusCodes; +import com.google.cloud.tools.jib.blob.Blobs; +import com.google.cloud.tools.jib.http.Authorizations; +import com.google.cloud.tools.jib.http.BlobHttpContent; +import com.google.cloud.tools.jib.http.Connection; +import com.google.cloud.tools.jib.http.Response; +import com.google.cloud.tools.jib.json.JsonTemplateMapper; +import com.google.cloud.tools.jib.registry.json.ErrorEntryTemplate; +import com.google.cloud.tools.jib.registry.json.ErrorResponseTemplate; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.List; +import java.util.function.Function; +import javax.annotation.Nullable; +import javax.net.ssl.SSLPeerUnverifiedException; +import org.apache.http.NoHttpResponseException; +import org.apache.http.conn.HttpHostConnectException; +import org.hamcrest.CoreMatchers; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.MockitoJUnitRunner; + +/** Tests for {@link RegistryEndpointCaller}. */ +@RunWith(MockitoJUnitRunner.class) public class RegistryEndpointCallerTest { + + /** Implementation of {@link RegistryEndpointProvider} for testing. */ + private static class TestRegistryEndpointProvider implements RegistryEndpointProvider { + + @Override + public String getHttpMethod() { + return "httpMethod"; + } + + @Override + public URL getApiRoute(String apiRouteBase) throws MalformedURLException { + return new URL(apiRouteBase + "/api"); + } + + @Nullable + @Override + public BlobHttpContent getContent() { + return null; + } + + @Override + public List getAccept() { + return Collections.emptyList(); + } + + @Nullable + @Override + public String handleResponse(Response response) throws IOException { + return Blobs.writeToString(response.getBody()); + } + + @Override + public String getActionDescription() { + return "actionDescription"; + } + } + + @Mock private Connection mockConnection; + @Mock private Response mockResponse; + @Mock private Function mockConnectionFactory; + @Mock private HttpResponse mockHttpResponse; + + private RegistryEndpointCaller testRegistryEndpointCaller; + + @Before + public void setUp() throws IOException { + testRegistryEndpointCaller = + new RegistryEndpointCaller<>( + "userAgent", + "apiRouteBase", + new TestRegistryEndpointProvider(), + Authorizations.withBasicToken("token"), + new RegistryEndpointProperties("serverUrl", "imageName"), + mockConnectionFactory); + + Mockito.when(mockConnectionFactory.apply(Mockito.any())).thenReturn(mockConnection); + Mockito.when(mockHttpResponse.parseAsString()).thenReturn(""); + Mockito.when(mockHttpResponse.getHeaders()).thenReturn(new HttpHeaders()); + } + + @Test + public void testCall_retryWithHttp() throws IOException, RegistryException { + verifyRetriesWithHttp(HttpHostConnectException.class); + } + + @Test + public void testCall_httpsPeerUnverified() throws IOException, RegistryException { + verifyRetriesWithHttp(SSLPeerUnverifiedException.class); + } + + @Test + public void testCall_noHttpResponse() throws IOException, RegistryException { + NoHttpResponseException mockNoHttpResponseException = + Mockito.mock(NoHttpResponseException.class); + Mockito.when(mockConnection.send(Mockito.eq("httpMethod"), Mockito.any())) + .thenThrow(mockNoHttpResponseException); + + try { + testRegistryEndpointCaller.call(); + Assert.fail("Call should have failed"); + + } catch (RegistryNoResponseException ex) { + Assert.assertSame(mockNoHttpResponseException, ex.getCause()); + } + } + + @Test + public void testCall_unauthorized() throws IOException, RegistryException { + verifyThrowsRegistryUnauthorizedException(HttpStatusCodes.STATUS_CODE_UNAUTHORIZED); + } + + @Test + public void testCall_forbidden() throws IOException, RegistryException { + verifyThrowsRegistryUnauthorizedException(HttpStatusCodes.STATUS_CODE_FORBIDDEN); + } + + @Test + public void testCall_badRequest() throws IOException, RegistryException { + verifyThrowsRegistryErrorException(HttpStatusCodes.STATUS_CODE_BAD_REQUEST); + } + + @Test + public void testCall_notFound() throws IOException, RegistryException { + verifyThrowsRegistryErrorException(HttpStatusCodes.STATUS_CODE_NOT_FOUND); + } + + @Test + public void testCall_methodNotAllowed() throws IOException, RegistryException { + verifyThrowsRegistryErrorException(HttpStatusCodes.STATUS_CODE_METHOD_NOT_ALLOWED); + } + + @Test + public void testCall_unknown() throws IOException, RegistryException { + Mockito.when(mockHttpResponse.getStatusCode()) + .thenReturn(HttpStatusCodes.STATUS_CODE_MOVED_PERMANENTLY); + HttpResponseException httpResponseException = new HttpResponseException(mockHttpResponse); + + Mockito.when(mockConnection.send(Mockito.eq("httpMethod"), Mockito.any())) + .thenThrow(httpResponseException); + + try { + testRegistryEndpointCaller.call(); + Assert.fail("Call should have failed"); + + } catch (HttpResponseException ex) { + Assert.assertSame(httpResponseException, ex); + } + } + + @Test + public void testCall_temporaryRedirect() throws IOException, RegistryException { + // Mocks a response for temporary redirect to a new location. + Mockito.when(mockHttpResponse.getStatusCode()) + .thenReturn(HttpStatusCodes.STATUS_CODE_TEMPORARY_REDIRECT); + Mockito.when(mockHttpResponse.getHeaders()) + .thenReturn(new HttpHeaders().setLocation("https://newlocation")); + + // Has mockConnection.send throw first, then succeed. + HttpResponseException httpResponseException = new HttpResponseException(mockHttpResponse); + Mockito.when(mockConnection.send(Mockito.eq("httpMethod"), Mockito.any())) + .thenThrow(httpResponseException) + .thenReturn(mockResponse); + Mockito.when(mockResponse.getBody()).thenReturn(Blobs.from("body")); + + Assert.assertEquals("body", testRegistryEndpointCaller.call()); + + // Checks that the URL was changed to the new location. + ArgumentCaptor urlArgumentCaptor = ArgumentCaptor.forClass(URL.class); + Mockito.verify(mockConnectionFactory, Mockito.times(2)).apply(urlArgumentCaptor.capture()); + Assert.assertEquals( + new URL("https://apiRouteBase/api"), urlArgumentCaptor.getAllValues().get(0)); + Assert.assertEquals(new URL("https://newlocation"), urlArgumentCaptor.getAllValues().get(1)); + } + + /** Verifies a request is retried with HTTP protocol if {@code exceptionClass} is thrown. */ + private void verifyRetriesWithHttp(Class exceptionClass) + throws IOException, RegistryException { + // Has mockConnection.send throw first, then succeed. + Mockito.when(mockConnection.send(Mockito.eq("httpMethod"), Mockito.any())) + .thenThrow(Mockito.mock(exceptionClass)) + .thenReturn(mockResponse); + Mockito.when(mockResponse.getBody()).thenReturn(Blobs.from("body")); + + Assert.assertEquals("body", testRegistryEndpointCaller.call()); + + // Checks that the URL protocol was first HTTPS, then HTTP. + ArgumentCaptor urlArgumentCaptor = ArgumentCaptor.forClass(URL.class); + Mockito.verify(mockConnectionFactory, Mockito.times(2)).apply(urlArgumentCaptor.capture()); + Assert.assertEquals("https", urlArgumentCaptor.getAllValues().get(0).getProtocol()); + Assert.assertEquals("http", urlArgumentCaptor.getAllValues().get(1).getProtocol()); + } + + /** + * Verifies that a response with {@code httpStatusCode} throws {@link + * RegistryUnauthorizedException}. + */ + private void verifyThrowsRegistryUnauthorizedException(int httpStatusCode) + throws IOException, RegistryException { + Mockito.when(mockHttpResponse.getStatusCode()).thenReturn(httpStatusCode); + HttpResponseException httpResponseException = new HttpResponseException(mockHttpResponse); + + Mockito.when(mockConnection.send(Mockito.eq("httpMethod"), Mockito.any())) + .thenThrow(httpResponseException); + + try { + testRegistryEndpointCaller.call(); + Assert.fail("Call should have failed"); + + } catch (RegistryUnauthorizedException ex) { + Assert.assertEquals("serverUrl", ex.getRegistry()); + Assert.assertEquals("imageName", ex.getRepository()); + Assert.assertSame(httpResponseException, ex.getHttpResponseException()); + } + } + + /** + * Verifies that a response with {@code httpStatusCode} throws {@link + * RegistryUnauthorizedException}. + */ + private void verifyThrowsRegistryErrorException(int httpStatusCode) + throws IOException, RegistryException { + ErrorResponseTemplate errorResponseTemplate = + new ErrorResponseTemplate().addError(new ErrorEntryTemplate("code", "message")); + + Mockito.when(mockHttpResponse.getStatusCode()).thenReturn(httpStatusCode); + Mockito.when(mockHttpResponse.parseAsString()) + .thenReturn(Blobs.writeToString(JsonTemplateMapper.toBlob(errorResponseTemplate))); + HttpResponseException httpResponseException = new HttpResponseException(mockHttpResponse); + + Mockito.when(mockConnection.send(Mockito.eq("httpMethod"), Mockito.any())) + .thenThrow(httpResponseException); + + try { + testRegistryEndpointCaller.call(); + Assert.fail("Call should have failed"); + + } catch (RegistryErrorException ex) { + Assert.assertThat( + ex.getMessage(), + CoreMatchers.containsString( + "Tried to actionDescription but failed because: unknown: message")); + } + } } From 107904a7d3e5cd449d225da193266cdf347656d2 Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Fri, 15 Jun 2018 00:23:48 -0400 Subject: [PATCH 3/6] Updates CHANGELOG. --- jib-gradle-plugin/CHANGELOG.md | 2 ++ jib-maven-plugin/CHANGELOG.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/jib-gradle-plugin/CHANGELOG.md b/jib-gradle-plugin/CHANGELOG.md index 68bb96b473..c4451a1b15 100644 --- a/jib-gradle-plugin/CHANGELOG.md +++ b/jib-gradle-plugin/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. ### Fixed +- Registries without TLS now supported ([#388](https://github.com/GoogleContainerTools/jib/issues/388)) + ## 0.9.0 ### Added diff --git a/jib-maven-plugin/CHANGELOG.md b/jib-maven-plugin/CHANGELOG.md index ac935342d0..68a88defbf 100644 --- a/jib-maven-plugin/CHANGELOG.md +++ b/jib-maven-plugin/CHANGELOG.md @@ -8,6 +8,8 @@ All notable changes to this project will be documented in this file. ### Fixed +- Registries without TLS now supported ([#388](https://github.com/GoogleContainerTools/jib/issues/388)) + ## 0.9.0 ### Added - Better feedback for build failures ([#197](https://github.com/google/jib/pull/197)) From 764d91e3506a74ec82d1246f422bac0ddf63f7d9 Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Fri, 15 Jun 2018 13:21:43 -0400 Subject: [PATCH 4/6] Fixes javadocs. --- .../jib/registry/RegistryEndpointCaller.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java index 661f882fb5..583beb2977 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java @@ -61,7 +61,12 @@ private RequestState(@Nullable Authorization authorization, URL url) { } } - /** Converts the {@link URL}'s protocol to HTTP. */ + /** + * Converts the {@link URL}'s protocol to HTTP. + * + * @param url the URL to conver to HTTP + * @return the URL with protocol set to HTTP + */ private static URL urlWithHttp(URL url) { GenericUrl httpUrl = new GenericUrl(url); httpUrl.setScheme("http"); @@ -133,7 +138,15 @@ T call() throws IOException, RegistryException { return call(initialRequestState); } - /** Calls the registry endpoint with a certain {@link RequestState}. */ + /** + * Calls the registry endpoint with a certain {@link RequestState}. + * + * @param requestState the state of the request - determines how to make the request and how to + * process the response + * @return an object representing the response, or {@code null} + * @throws IOException for most I/O exceptions when making the request + * @throws RegistryException for known exceptions when interacting with the registry + */ @Nullable private T call(RequestState requestState) throws IOException, RegistryException { try (Connection connection = connectionFactory.apply(requestState.url)) { From d2b78e6e6b533826d3f1f444d755b0b740b072aa Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Fri, 15 Jun 2018 13:22:59 -0400 Subject: [PATCH 5/6] Fixes javadoc. --- .../cloud/tools/jib/registry/RegistryEndpointProvider.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointProvider.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointProvider.java index e34201540f..bd32592e74 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointProvider.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointProvider.java @@ -36,8 +36,7 @@ interface RegistryEndpointProvider { String getHttpMethod(); /** - * @param apiRouteBase the registry's base URL without the protocol (for example, {@code - * gcr.io/v2/}) + * @param apiRouteBase the registry's base URL (for example, {@code https://gcr.io/v2/}) * @return the registry endpoint URL */ URL getApiRoute(String apiRouteBase) throws MalformedURLException; From 23580e3233ea5275e81c606fa2770b7660d48365 Mon Sep 17 00:00:00 2001 From: Qingyang Chen Date: Fri, 15 Jun 2018 19:15:43 -0400 Subject: [PATCH 6/6] Changes to explicit https. --- .../google/cloud/tools/jib/registry/RegistryEndpointCaller.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java index 583beb2977..ee228555dc 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/registry/RegistryEndpointCaller.java @@ -207,7 +207,7 @@ private T call(RequestState requestState) throws IOException, RegistryException } catch (HttpHostConnectException | SSLPeerUnverifiedException ex) { // Tries to call with HTTP protocol if HTTPS failed to connect. - if (DEFAULT_PROTOCOL.equals(requestState.url.getProtocol())) { + if ("https".equals(requestState.url.getProtocol())) { return call(new RequestState(requestState.authorization, urlWithHttp(requestState.url))); }