add PROPERTY_PROXY_FOR_SOCKETS constant to allow ssh connections to bypass HTTP proxies

This commit is contained in:
Dies Koper 2013-03-18 16:11:14 +11:00
parent e93b79d145
commit 7a5cc9e2af
3 changed files with 170 additions and 1 deletions

View File

@ -145,6 +145,14 @@ public interface Constants {
*/
public static final String PROPERTY_PROXY_PASSWORD = "jclouds.proxy-password";
/**
* Boolean property. Default true.
* <p/>
* If a proxy server is configured, it will be used for all types of schemes.
* Set to false to not use a proxy server for sockets (such as ssh access).
*/
public static final String PROPERTY_PROXY_FOR_SOCKETS = "jclouds.proxy-for-sockets";
/**
* Integer property.
* <p/>

View File

@ -20,6 +20,7 @@ package org.jclouds.proxy;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.getLast;
import static org.jclouds.Constants.PROPERTY_PROXY_FOR_SOCKETS;
import java.net.Authenticator;
import java.net.InetSocketAddress;
@ -29,6 +30,7 @@ import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
import javax.inject.Named;
import javax.inject.Singleton;
import org.jclouds.domain.Credentials;
@ -45,6 +47,10 @@ import com.google.inject.Inject;
public class ProxyForURI implements Function<URI, Proxy> {
private final ProxyConfig config;
@Inject(optional = true)
@Named(PROPERTY_PROXY_FOR_SOCKETS)
private boolean useProxyForSockets = true;
@VisibleForTesting
@Inject
ProxyForURI(ProxyConfig config) {
@ -62,7 +68,9 @@ public class ProxyForURI implements Function<URI, Proxy> {
*/
@Override
public Proxy apply(URI endpoint) {
if (config.useSystem()) {
if (!useProxyForSockets && "socket".equals(endpoint.getScheme())) {
return Proxy.NO_PROXY;
} else if (config.useSystem()) {
System.setProperty("java.net.useSystemProxies", "true");
Iterable<Proxy> proxies = ProxySelector.getDefault().select(endpoint);
return getLast(proxies);

View File

@ -0,0 +1,153 @@
/**
* Licensed to jclouds, Inc. (jclouds) under one or more
* contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. jclouds licenses this file
* to you 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 org.jclouds.proxy;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import java.net.URI;
import java.net.URISyntaxException;
import org.jclouds.domain.Credentials;
import org.testng.annotations.Test;
import com.google.common.base.Optional;
import com.google.common.net.HostAndPort;
public class ProxyForURITest {
private Optional<HostAndPort> noHostAndPort = Optional.absent();
private Optional<Credentials> noCreds = Optional.absent();
private Optional<HostAndPort> hostAndPort = Optional.of(HostAndPort.fromParts("proxy.example.com", 8080));
private Optional<Credentials> creds = Optional.of(new Credentials("user", "pwd"));
private class MyProxyConfig implements ProxyConfig {
private boolean useSystem;
private Type type;
private Optional<HostAndPort> proxy;
private Optional<Credentials> credentials;
MyProxyConfig(boolean useSystem, Type type, Optional<HostAndPort> proxy, Optional<Credentials> credentials) {
this.useSystem = useSystem;
this.type = type;
this.proxy = proxy;
this.credentials = credentials;
}
@Override
public boolean useSystem() {
return useSystem;
}
@Override
public Type getType() {
return type;
}
@Override
public Optional<HostAndPort> getProxy() {
return proxy;
}
@Override
public Optional<Credentials> getCredentials() {
return credentials;
}
}
@Test
public void testDontUseProxyForSockets() throws Exception {
ProxyConfig config = new MyProxyConfig(false, Proxy.Type.HTTP, hostAndPort, creds);
ProxyForURI proxy = new ProxyForURI(config);
Field useProxyForSockets = proxy.getClass().getDeclaredField("useProxyForSockets");
useProxyForSockets.setAccessible(true);
useProxyForSockets.setBoolean(proxy, false);
URI uri = new URI("socket://ssh.example.com:22");
assertEquals(proxy.apply(uri), Proxy.NO_PROXY);
}
@Test
public void testUseProxyForSockets() throws Exception {
ProxyConfig config = new MyProxyConfig(false, Proxy.Type.HTTP, hostAndPort, creds);
ProxyForURI proxy = new ProxyForURI(config);
URI uri = new URI("socket://ssh.example.com:22");
assertEquals(proxy.apply(uri), new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.example.com", 8080)));
}
@Test
public void testUseProxyForSocketsSettingShouldntAffectHTTP() throws Exception {
ProxyConfig config = new MyProxyConfig(false, Proxy.Type.HTTP, hostAndPort, creds);
ProxyForURI proxy = new ProxyForURI(config);
Field useProxyForSockets = proxy.getClass().getDeclaredField("useProxyForSockets");
useProxyForSockets.setAccessible(true);
useProxyForSockets.setBoolean(proxy, false);
URI uri = new URI("http://example.com/file");
assertEquals(proxy.apply(uri), new Proxy(Proxy.Type.HTTP, new InetSocketAddress("proxy.example.com", 8080)));
}
@Test
public void testHTTPDirect() throws URISyntaxException {
ProxyConfig config = new MyProxyConfig(false, Proxy.Type.DIRECT, noHostAndPort, noCreds);
URI uri = new URI("http://example.com/file");
assertEquals(new ProxyForURI(config).apply(uri), Proxy.NO_PROXY);
}
@Test
public void testHTTPSDirect() throws URISyntaxException {
ProxyConfig config = new MyProxyConfig(false, Proxy.Type.DIRECT, noHostAndPort, noCreds);
URI uri = new URI("https://example.com/file");
assertEquals(new ProxyForURI(config).apply(uri), Proxy.NO_PROXY);
}
@Test
public void testFTPDirect() throws URISyntaxException {
ProxyConfig config = new MyProxyConfig(false, Proxy.Type.DIRECT, noHostAndPort, noCreds);
URI uri = new URI("ftp://ftp.example.com/file");
assertEquals(new ProxyForURI(config).apply(uri), Proxy.NO_PROXY);
}
@Test
public void testSocketDirect() throws URISyntaxException {
ProxyConfig config = new MyProxyConfig(false, Proxy.Type.DIRECT, noHostAndPort, noCreds);
URI uri = new URI("socket://ssh.example.com:22");
assertEquals(new ProxyForURI(config).apply(uri), Proxy.NO_PROXY);
}
@Test
public void testHTTPThroughHTTPProxy() throws URISyntaxException {
ProxyConfig config = new MyProxyConfig(false, Proxy.Type.HTTP, hostAndPort, creds);
URI uri = new URI("http://example.com/file");
assertEquals(new ProxyForURI(config).apply(uri), new Proxy(Proxy.Type.HTTP, new InetSocketAddress(
"proxy.example.com", 8080)));
}
@Test
public void testHTTPThroughSystemProxy() throws URISyntaxException {
ProxyConfig config = new MyProxyConfig(true, Proxy.Type.DIRECT, noHostAndPort, noCreds);
URI uri = new URI("http://example.com/file");
// could return a proxy, could return NO_PROXY, depends on the tester's
// environment
assertNotNull(new ProxyForURI(config).apply(uri));
}
}