Skip to content

Commit 7f36d34

Browse files
authored
noProxy setting with wildcard char support (#1496)
Signed-off-by: aboyko <[email protected]>
1 parent c90a25b commit 7f36d34

File tree

3 files changed

+106
-3
lines changed

3 files changed

+106
-3
lines changed

eclipse-language-servers/org.springframework.tooling.boot.ls/src/org/springframework/tooling/boot/ls/DelegatingStreamConnectionProvider.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ private static void fillProxyData(Map<String, Object> proxy, IProxyData data, St
277277
proxy.put("proxy-user", data.getUserId());
278278
proxy.put("proxy-password", data.getPassword());
279279
}
280-
proxy.put("proxy-exclusions", exclusions);
280+
proxy.put("noProxy", exclusions);
281281
}
282282

283283
private void putValidationPreferences(Map<String, Object> settings) {

headless-services/spring-boot-language-server/src/main/java/org/springframework/ide/vscode/boot/app/RestTemplateFactory.java

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,14 @@
2222
import java.net.URL;
2323
import java.net.http.HttpClient;
2424
import java.net.http.HttpClient.Builder;
25+
import java.util.ArrayList;
26+
import java.util.Collection;
2527
import java.util.Collections;
28+
import java.util.HashSet;
2629
import java.util.List;
2730
import java.util.Set;
31+
import java.util.regex.Pattern;
32+
import java.util.regex.PatternSyntaxException;
2833

2934
import org.slf4j.Logger;
3035
import org.slf4j.LoggerFactory;
@@ -38,11 +43,59 @@ public class RestTemplateFactory {
3843
private static final Logger log = LoggerFactory.getLogger(RestTemplateFactory.class);
3944

4045
private BootJavaConfig config;
46+
47+
private HostExclusions proxyExclusions;
4148

4249
public RestTemplateFactory(BootJavaConfig config) {
4350
this.config = config;
51+
this.proxyExclusions = null;
52+
config.addListener(v -> {
53+
synchronized(RestTemplateFactory.this) {
54+
proxyExclusions = null;
55+
}
56+
});
4457
}
4558

59+
record HostExclusions(Set<String> hosts, List<Pattern> regexs) {
60+
61+
public HostExclusions(Collection<String> exclusions) {
62+
this(new HashSet<>(), new ArrayList<>());
63+
for (String s : exclusions) {
64+
if (s.contains("*")) {
65+
// Regex
66+
String regexStr = s.replace(".", "\\.").replace("*", ".*");
67+
try {
68+
regexs.add(Pattern.compile(regexStr));
69+
} catch (PatternSyntaxException e) {
70+
log.error("Unnable to compile Regular Expression for %s".formatted(s), e);
71+
}
72+
} else {
73+
// Exact host string
74+
hosts.add(s);
75+
}
76+
}
77+
}
78+
79+
boolean contains(String host) {
80+
if (hosts.contains(host)) {
81+
return true;
82+
}
83+
for (Pattern p : regexs) {
84+
if (p.matcher(host).matches()) {
85+
return true;
86+
}
87+
}
88+
return false;
89+
}
90+
}
91+
92+
private synchronized HostExclusions getProxyExclusions() {
93+
if (proxyExclusions == null) {
94+
proxyExclusions = new HostExclusions(config.getRawSettings().getStringSet("http", "noProxy"));
95+
}
96+
return proxyExclusions;
97+
}
98+
4699
public RestTemplate createRestTemplate(String host) {
47100
String proxyUrlStr = config.getRawSettings().getString("http", "proxy");
48101
if (proxyUrlStr == null || proxyUrlStr.isBlank()) {
@@ -51,8 +104,7 @@ public RestTemplate createRestTemplate(String host) {
51104

52105
Builder clientBuilder = HttpClient.newBuilder();
53106
if (proxyUrlStr != null && !proxyUrlStr.isBlank()) {
54-
Set<String> exclusions = config.getRawSettings().getStringSet("http", "proxy-exclusions");
55-
if (!"localhost".equals(host) && !"127.0.0.1".equals(host) && !exclusions.contains(host)) {
107+
if (!"localhost".equals(host) && !"127.0.0.1".equals(host) && !getProxyExclusions().contains(host)) {
56108
try {
57109
URL proxyUrl = new URL(proxyUrlStr);
58110
clientBuilder.proxy(new ProxySelector() {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2025 Broadcom, Inc.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* https://www.eclipse.org/legal/epl-v10.html
7+
*
8+
* Contributors:
9+
* Broadcom, Inc. - initial API and implementation
10+
*******************************************************************************/
11+
package org.springframework.ide.vscode.boot.app;
12+
13+
import static org.junit.Assert.assertFalse;
14+
import static org.junit.Assert.assertTrue;
15+
import static org.junit.jupiter.api.Assertions.assertEquals;
16+
17+
import java.util.List;
18+
import java.util.Set;
19+
import java.util.stream.Collectors;
20+
21+
import org.junit.jupiter.api.Test;
22+
import org.springframework.ide.vscode.boot.app.RestTemplateFactory.HostExclusions;
23+
24+
public class RestTemplateFactoryTest {
25+
26+
@Test
27+
void testHostExclusionSet() {
28+
HostExclusions exclusions = new RestTemplateFactory.HostExclusions(List.of("my-host", "foo-*", "*.bar"));
29+
assertEquals(exclusions.hosts(), Set.of("my-host"));
30+
assertEquals(exclusions.regexs().stream().map(r -> r.pattern()).collect(Collectors.toList()), List.of("foo-.*", ".*\\.bar"));
31+
32+
assertTrue(exclusions.contains("my-host"));
33+
assertFalse(exclusions.contains("my_host"));
34+
35+
assertTrue(exclusions.contains("foo-bar"));
36+
assertTrue(exclusions.contains("foo-bar-baz"));
37+
assertFalse(exclusions.contains("bar-foo"));
38+
39+
assertTrue(exclusions.contains("foo.bar"));
40+
assertTrue(exclusions.contains(".bar"));
41+
assertFalse(exclusions.contains("foo.bar.baz"));
42+
assertFalse(exclusions.contains("bar.foo"));
43+
44+
exclusions = new RestTemplateFactory.HostExclusions(List.of("*"));
45+
assertTrue(exclusions.contains("my_host"));
46+
assertTrue(exclusions.contains("foo.bar.baz"));
47+
assertTrue(exclusions.contains("bar.foo"));
48+
49+
}
50+
51+
}

0 commit comments

Comments
 (0)