diff --git a/src/main/java/me/itzg/helpers/get/GetCommand.java b/src/main/java/me/itzg/helpers/get/GetCommand.java index 557f6368..a75e2713 100644 --- a/src/main/java/me/itzg/helpers/get/GetCommand.java +++ b/src/main/java/me/itzg/helpers/get/GetCommand.java @@ -6,6 +6,7 @@ import java.io.PrintWriter; import java.net.URI; import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; @@ -14,6 +15,7 @@ import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.ArrayList; +import java.util.Base64; import java.util.Collection; import java.util.Collections; import java.util.HashSet; @@ -375,12 +377,26 @@ private void pruneOtherFiles(Set outputs) throws IOException { private Path processSingleUri(URI uri, CloseableHttpClient client, Path modifiedSinceFile, OutputResponseHandler handler) throws URISyntaxException, IOException { - final URI requestUri = uri.getPath().startsWith("//") ? + URI requestUri = uri.getPath().startsWith("//") ? alterUriPath(uri, uri.getPath().substring(1)) : uri; + final String authHeader; + if (requestUri.getUserInfo() != null) { + authHeader = "Basic " + + Base64.getEncoder().withoutPadding() + .encodeToString(requestUri.getUserInfo().getBytes(StandardCharsets.UTF_8)); + requestUri = removeUserInfo(requestUri); + } + else { + authHeader = null; + } + log.debug("Getting uri={}", requestUri); final HttpGet request = new HttpGet(requestUri); + if (authHeader != null) { + request.addHeader(HttpHeaders.AUTHORIZATION, authHeader); + } if (acceptContentTypes != null) { for (String acceptContentType : acceptContentTypes) { request.addHeader(HttpHeaders.ACCEPT, acceptContentType); @@ -431,4 +447,17 @@ private static URI alterUriPath(URI uri, String path) throws URISyntaxException ); } + private static URI removeUserInfo(URI uri) throws URISyntaxException { + return new URI( + uri.getScheme(), + null, + uri.getHost(), + uri.getPort(), + uri.getPath(), + uri.getQuery(), + uri.getFragment() + ); + } + + } diff --git a/src/test/java/me/itzg/helpers/get/GetCommandTest.java b/src/test/java/me/itzg/helpers/get/GetCommandTest.java index 180ab964..639d3b53 100644 --- a/src/test/java/me/itzg/helpers/get/GetCommandTest.java +++ b/src/test/java/me/itzg/helpers/get/GetCommandTest.java @@ -7,6 +7,7 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.net.MalformedURLException; +import java.net.URISyntaxException; import me.itzg.helpers.TestLoggingAppender; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -52,6 +53,26 @@ void outputsDownload() throws MalformedURLException { assertThat(output.toString()).isEqualTo("Response content"); } + @Test + void usesBasicAuth() throws MalformedURLException, URISyntaxException { + mock.expectRequest("GET","/", + request -> request.withHeader("Authorization", "Basic dXNlcjpwYXNz"), + response() + .withBody("You're in", MediaType.TEXT_PLAIN) + ); + + final StringWriter output = new StringWriter(); + final int status = + new CommandLine(new GetCommand()) + .setOut(new PrintWriter(output)) + .execute( + mock.buildMockedUrl("/", "user:pass").toString() + ); + + assertThat(status).isEqualTo(0); + assertThat(output.toString()).isEqualTo("You're in"); + } + @Test void handlesExtraSlashAtStartOfPath() throws MalformedURLException { mock.expectRequest("GET","/handlesExtraSlashAtStartOfPath.txt", diff --git a/src/test/java/me/itzg/helpers/get/MockServerSupport.java b/src/test/java/me/itzg/helpers/get/MockServerSupport.java index 06497b5f..81441f6c 100644 --- a/src/test/java/me/itzg/helpers/get/MockServerSupport.java +++ b/src/test/java/me/itzg/helpers/get/MockServerSupport.java @@ -3,6 +3,8 @@ import static org.mockserver.model.HttpRequest.request; import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import org.mockserver.integration.ClientAndServer; import org.mockserver.matchers.Times; @@ -11,15 +13,28 @@ class MockServerSupport { - private ClientAndServer client; + private final ClientAndServer client; public MockServerSupport(ClientAndServer client) { this.client = client; } - URL buildMockedUrl(String s) throws MalformedURLException { - return new URL("http", "localhost", client.getLocalPort(), s); + URL buildMockedUrl(String path) throws MalformedURLException { + return new URL("http", "localhost", client.getLocalPort(), path); + } + + @SuppressWarnings("SameParameterValue") + URL buildMockedUrl(String path, String userInfo) throws URISyntaxException, MalformedURLException { + return new URI( + "http", + userInfo, + "localhost", + client.getLocalPort(), + path, + null, + null + ).toURL(); } @FunctionalInterface @@ -31,6 +46,7 @@ void expectRequest(String method, String path, HttpResponse httpResponse) { expectRequest(method, path, request -> request, httpResponse); } + @SuppressWarnings("SameParameterValue") void expectRequest(String method, String path, HttpResponse httpResponse, int responseTimes) { expectRequest(method, path, request -> request, httpResponse, responseTimes); }