Skip to content

Commit c58698d

Browse files
committed
Add HTTP proxy for snapshot repo to forbid downloading JUnit artifacts
1 parent 9f6ad01 commit c58698d

File tree

5 files changed

+136
-4
lines changed

5 files changed

+136
-4
lines changed

platform-tooling-support-tests/projects/maven-starter/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@
9090
</releases>
9191
</repository>
9292
<repository>
93-
<id>sonatype-oss-snapshots</id>
94-
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
93+
<id>snapshots-repo</id>
94+
<url>${snapshot.repo.url}</url>
9595
<snapshots>
9696
<enabled>true</enabled>
9797
</snapshots>

platform-tooling-support-tests/projects/multi-release-jar/default/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@
6969
</releases>
7070
</repository>
7171
<repository>
72-
<id>sonatype-oss-snapshots</id>
73-
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
72+
<id>snapshots-repo</id>
73+
<url>${snapshot.repo.url}</url>
7474
<snapshots>
7575
<enabled>true</enabled>
7676
</snapshots>
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
/*
2+
* Copyright 2015-2024 the original author or authors.
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License v2.0 which
6+
* accompanies this distribution and is available at
7+
*
8+
* https://www.eclipse.org/legal/epl-v20.html
9+
*/
10+
11+
package platform.tooling.support.tests;
12+
13+
import static java.net.http.HttpRequest.BodyPublishers.noBody;
14+
import static org.junit.jupiter.api.Assertions.assertAll;
15+
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
16+
17+
import java.io.IOException;
18+
import java.io.InputStream;
19+
import java.net.InetAddress;
20+
import java.net.InetSocketAddress;
21+
import java.net.URI;
22+
import java.net.http.HttpClient;
23+
import java.net.http.HttpRequest;
24+
import java.net.http.HttpResponse;
25+
import java.util.List;
26+
27+
import com.sun.net.httpserver.HttpExchange;
28+
import com.sun.net.httpserver.HttpServer;
29+
30+
public class MavenRepoProxy implements AutoCloseable {
31+
32+
// Forbid downloading JUnit artifacts since we want to use the local ones
33+
private static final List<String> FORBIDDEN_PATHS = List.of("/org/junit");
34+
35+
private static final List<String> RESTRICTED_HEADER_NAMES = List.of("Connection", "Host");
36+
37+
private final HttpServer httpServer;
38+
private final HttpClient httpClient;
39+
40+
@SuppressWarnings("unused")
41+
public MavenRepoProxy() throws IOException {
42+
this(0);
43+
}
44+
45+
@SuppressWarnings("unused")
46+
public MavenRepoProxy(int port) throws IOException {
47+
this("https://oss.sonatype.org/content/repositories/snapshots", port);
48+
}
49+
50+
private MavenRepoProxy(String proxiedUrl, int port) throws IOException {
51+
httpClient = HttpClient.newBuilder().followRedirects(HttpClient.Redirect.ALWAYS).build();
52+
httpServer = HttpServer.create(new InetSocketAddress(InetAddress.getLoopbackAddress(), port), 0);
53+
httpServer.createContext("/", exchange -> {
54+
try (exchange) {
55+
switch (exchange.getRequestMethod()) {
56+
case "HEAD":
57+
case "GET":
58+
if (FORBIDDEN_PATHS.stream().anyMatch(
59+
it -> exchange.getRequestURI().getPath().startsWith(it))) {
60+
exchange.sendResponseHeaders(404, 0);
61+
break;
62+
}
63+
var request = mapRequest(proxiedUrl, exchange);
64+
try {
65+
var response = httpClient.send(request, HttpResponse.BodyHandlers.ofInputStream());
66+
mapResponse(response, exchange);
67+
}
68+
catch (InterruptedException e) {
69+
Thread.currentThread().interrupt();
70+
}
71+
break;
72+
default:
73+
exchange.sendResponseHeaders(405, -1);
74+
}
75+
}
76+
catch (Exception e) {
77+
e.printStackTrace();
78+
}
79+
});
80+
httpServer.start();
81+
}
82+
83+
URI getBaseUri() {
84+
var address = httpServer.getAddress();
85+
return URI.create("http://" + address.getAddress().getHostName() + ":" + address.getPort());
86+
}
87+
88+
private static void mapResponse(HttpResponse<InputStream> response, HttpExchange exchange) throws IOException {
89+
exchange.sendResponseHeaders(response.statusCode(),
90+
response.headers().firstValueAsLong("Content-Length").orElse(0));
91+
response.headers().map().forEach((key, values) -> exchange.getResponseHeaders().put(key, values));
92+
try (InputStream body = response.body()) {
93+
body.transferTo(exchange.getResponseBody());
94+
}
95+
}
96+
97+
private static HttpRequest mapRequest(String proxiedUrl, HttpExchange exchange) {
98+
var request = HttpRequest.newBuilder().method(exchange.getRequestMethod(), noBody()) //
99+
.uri(URI.create(proxiedUrl + exchange.getRequestURI().getPath()));
100+
exchange.getRequestHeaders().entrySet().stream() //
101+
.filter(entry -> RESTRICTED_HEADER_NAMES.stream().noneMatch(it -> it.equalsIgnoreCase(entry.getKey()))) //
102+
.forEach(entry -> entry.getValue() //
103+
.forEach(value -> request.header(entry.getKey(), value)));
104+
return request.build();
105+
}
106+
107+
@Override
108+
public void close() {
109+
assertAll( //
110+
() -> assertDoesNotThrow(() -> httpServer.stop(0)), //
111+
() -> assertDoesNotThrow(httpClient::close) //
112+
);
113+
}
114+
115+
@SuppressWarnings("unused")
116+
public static void main(String[] args) throws Exception {
117+
try (var proxy = new MavenRepoProxy(12345)) {
118+
System.out.println("Started proxy: " + proxy.getBaseUri());
119+
while (!Thread.interrupted()) {
120+
Thread.onSpinWait();
121+
}
122+
}
123+
}
124+
}

platform-tooling-support-tests/src/test/java/platform/tooling/support/tests/MavenStarterTests.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,17 @@ class MavenStarterTests {
3333
@GlobalResource
3434
LocalMavenRepo localMavenRepo;
3535

36+
@GlobalResource
37+
MavenRepoProxy mavenRepoProxy;
38+
3639
@ResourceLock(Projects.MAVEN_STARTER)
3740
@Test
3841
void verifyMavenStarterProject() {
3942
var request = Request.builder() //
4043
.setTool(Request.maven()) //
4144
.setProject(Projects.MAVEN_STARTER) //
4245
.addArguments(localMavenRepo.toCliArgument(), "-Dmaven.repo=" + MavenRepo.dir()) //
46+
.addArguments("-Dsnapshot.repo.url=" + mavenRepoProxy.getBaseUri()) //
4347
.addArguments("--update-snapshots", "--batch-mode", "verify") //
4448
.setTimeout(TOOL_TIMEOUT) //
4549
.setJavaHome(Helper.getJavaHome("8").orElseThrow(TestAbortedException::new)) //

platform-tooling-support-tests/src/test/java/platform/tooling/support/tests/MultiReleaseJarTests.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ class MultiReleaseJarTests {
3737
@GlobalResource
3838
LocalMavenRepo localMavenRepo;
3939

40+
@GlobalResource
41+
MavenRepoProxy mavenRepoProxy;
42+
4043
@ResourceLock(Projects.MULTI_RELEASE_JAR)
4144
@Test
4245
void checkDefault() throws Exception {
@@ -92,6 +95,7 @@ private Result mvn(String variant) {
9295
.setTool(Request.maven()) //
9396
.setProject(Projects.MULTI_RELEASE_JAR) //
9497
.addArguments(localMavenRepo.toCliArgument(), "-Dmaven.repo=" + MavenRepo.dir()) //
98+
.addArguments("-Dsnapshot.repo.url=" + mavenRepoProxy.getBaseUri()) //
9599
.addArguments("--update-snapshots", "--show-version", "--errors", "--batch-mode", "--file", variant,
96100
"test") //
97101
.setTimeout(TOOL_TIMEOUT);

0 commit comments

Comments
 (0)