/** * Copyright (c) 2008-2016, XebiaLabs B.V., All rights reserved. * * * Overthere is licensed under the terms of the GPLv2 * <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most XebiaLabs Libraries. * There are special exceptions to the terms and conditions of the GPLv2 as it is applied to * this software, see the FLOSS License Exception * <http://github.com/xebialabs/overthere/blob/master/LICENSE>. * * This program is free software; you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Foundation; version 2 * of the License. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this * program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth * Floor, Boston, MA 02110-1301 USA */ package com.xebialabs.overthere.proxy; import com.xebialabs.overthere.*; import com.xebialabs.overthere.spi.AddressPortMapper; import com.xebialabs.overthere.spi.BaseOverthereConnection; import com.xebialabs.overthere.spi.OverthereConnectionBuilder; import com.xebialabs.overthere.spi.Protocol; import javax.net.SocketFactory; import java.net.InetSocketAddress; import java.net.Proxy; import static com.xebialabs.overthere.ConnectionOptions.*; import static com.xebialabs.overthere.OperatingSystemFamily.UNIX; import static com.xebialabs.overthere.proxy.ProxyConnection.PROXY_PROTOCOL; import static java.net.InetSocketAddress.createUnresolved; import static java.net.Proxy.Type.HTTP; /** * Transparent connection that ensures that a correct SocketFactory is introduced that connects through the required * proxy host. */ @Protocol(name = PROXY_PROTOCOL) public class ProxyConnection extends BaseOverthereConnection implements AddressPortMapper, OverthereConnectionBuilder { /** * Name of the protocol handled by this connection builder, i.e. "ssh". */ public static final String PROXY_PROTOCOL = "proxy"; /** * See <a href="https://github.com/xebialabs/overthere/blob/master/README.md#proxyType">the online documentation</a> */ public static final String PROXY_TYPE = "proxyType"; /** * See <a href="https://github.com/xebialabs/overthere/blob/master/README.md#proxyType">the online documentation</a> */ public static final Proxy.Type PROXY_TYPE_DEFAULT = HTTP; private final String proxyAddress; private final int proxyPort; private final Proxy.Type proxyType; public ProxyConnection(String protocol, ConnectionOptions options, AddressPortMapper mapper) { super(protocol, augmentOptions(options), mapper, false); String unmappedAddress = options.get(ADDRESS); int unmappedPort = options.getInteger(PORT); InetSocketAddress addressPort = mapper.map(createUnresolved(unmappedAddress, unmappedPort)); proxyAddress = addressPort.getHostName(); proxyPort = addressPort.getPort(); proxyType = options.getEnum(PROXY_TYPE, Proxy.Type.class, PROXY_TYPE_DEFAULT); if(proxyType != HTTP) { throw new IllegalArgumentException("Proxy of type other than HTTP not supported"); } if(options.containsKey(JUMPSTATION)) { throw new IllegalArgumentException("Cannot configure an HTTP proxy behind another proxy or behind an SSH jumpstation"); } } private static ConnectionOptions augmentOptions(ConnectionOptions options) { if (options.containsKey(OPERATING_SYSTEM)) { return options; } else { ConnectionOptions augmentedOptions = new ConnectionOptions(options); augmentedOptions.set(OPERATING_SYSTEM, UNIX); return augmentedOptions; } } @Override public OverthereConnection connect() { return this; } @Override public InetSocketAddress map(InetSocketAddress address) { return mapper.map(address); } @Override public SocketFactory socketFactory() { Proxy p = new Proxy(proxyType, new InetSocketAddress(proxyAddress, proxyPort)); return new ProxySocketFactory(p); } @Override protected void doClose() { // no-op } @Override protected OverthereFile getFileForTempFile(OverthereFile parent, String name) { throw new UnsupportedOperationException("Cannot get a file from the proxy."); } @Override public OverthereFile getFile(String hostPath) throws RuntimeIOException { throw new UnsupportedOperationException("Cannot get a file from the proxy."); } @Override public OverthereFile getFile(OverthereFile parent, String child) { throw new UnsupportedOperationException("Cannot get a file from the proxy."); } @Override public OverthereProcess startProcess(CmdLine commandLine) { throw new UnsupportedOperationException("Cannot start a process on the proxy."); } @Override public void setWorkingDirectory(OverthereFile workingDirectory) { throw new UnsupportedOperationException("Cannot set a working directory on the proxy."); } @Override public OverthereFile getWorkingDirectory() { throw new UnsupportedOperationException("Cannot get a working directory from the proxy."); } @Override public int execute(final OverthereExecutionOutputHandler stdoutHandler, final OverthereExecutionOutputHandler stderrHandler, final CmdLine commandLine) { throw new UnsupportedOperationException("Cannot execute a command on the proxy."); } @Override public String toString() { return "proxy:" + proxyType.toString().toLowerCase() + "://" + proxyAddress + ":" + proxyPort; } }