All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sshtools.net.HttpProxyTransportWrapper Maven / Gradle / Ivy

The newest version!
/**
 * Copyright 2003-2016 SSHTOOLS Limited. All Rights Reserved.
 *
 * For product documentation visit https://www.sshtools.com/
 *
 * This file is part of J2SSH Maverick.
 *
 * J2SSH Maverick is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * J2SSH Maverick 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 J2SSH Maverick.  If not, see .
 */
package com.sshtools.net;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.net.UnknownHostException;

import com.sshtools.ssh.SshTransport;

/**
 * Provides an {@link com.sshtools.ssh.SshTransport} implementation that can
 * route the connection through a HTTP proxy.
 * 
 * To connect the transport simply call the {@link connectViaProxy(String, int,
 * String, int, String, String, String)} method. You can pass the name of your
 * application as the user agent and if no authentication is required simply
 * pass ""
 * 
 * @author Lee David Painter
 * 
 */
public class HttpProxyTransportWrapper extends SocketWrapper {
	private String proxyHost;
	private int proxyPort;
	private String remoteHost;
	private int remotePort;
	private HttpResponse responseHeader;
	private String username;
	private String password;
	private String userAgent;

	private static int connectionTimeout = 30000;

	private HttpProxyTransportWrapper(String host, int port, String proxyHost,
			int proxyPort) throws IOException, UnknownHostException {
		super(new Socket());
		this.proxyHost = proxyHost;
		this.proxyPort = proxyPort;
		this.remoteHost = host;
		this.remotePort = port;

		socket.connect(new InetSocketAddress(host, port), connectionTimeout);
		socket.setSoTimeout(connectionTimeout);
	}

	public static void setConnectionTimeout(int connectionTimeout) {
		HttpProxyTransportWrapper.connectionTimeout = connectionTimeout;
	}

	public static int getConnectionTimeout() {
		return connectionTimeout;
	}

	/**
	 * Connect the socket to a HTTP proxy and request forwarding to our remote
	 * host.
	 * 
	 * @param host
	 * @param port
	 * @param proxyHost
	 * @param proxyPort
	 * @param username
	 * @param password
	 * @param userAgent
	 * @return HttpProxyTransportWrapper
	 * @throws IOException
	 * @throws UnknownHostException
	 */
	public static HttpProxyTransportWrapper connectViaProxy(String host,
			int port, String proxyHost, int proxyPort, String username,
			String password, String userAgent) throws IOException,
			UnknownHostException {
		HttpProxyTransportWrapper socket = new HttpProxyTransportWrapper(host,
				port, proxyHost, proxyPort);
		int status;
		socket.username = username;
		socket.password = password;
		socket.userAgent = userAgent;

		try {
			InputStream in = socket.getInputStream();
			OutputStream out = socket.getOutputStream();
			HttpRequest request = new HttpRequest();

			request.setHeaderBegin("CONNECT " + host + ":" + port + " HTTP/1.0");
			request.setHeaderField("User-Agent", userAgent);
			request.setHeaderField("Pragma", "No-Cache");
			request.setHeaderField("Host", host);
			request.setHeaderField("Proxy-Connection", "Keep-Alive");
			out.write(request.toString().getBytes());
			out.flush();
			socket.responseHeader = new HttpResponse(in);

			if (socket.responseHeader.getStatus() == 407) {
				String realm = socket.responseHeader.getAuthenticationRealm();
				String method = socket.responseHeader.getAuthenticationMethod();

				if (realm == null) {
					realm = "";
				}

				if (method.equalsIgnoreCase("basic")) {
					socket.close();
					socket = new HttpProxyTransportWrapper(host, port,
							proxyHost, proxyPort);
					in = socket.getInputStream();
					out = socket.getOutputStream();
					request.setBasicAuthentication(username, password);
					out.write(request.toString().getBytes());
					out.flush();
					socket.responseHeader = new HttpResponse(in);
				} else if (method.equalsIgnoreCase("digest")) {
					throw new IOException(
							"Digest authentication is not supported");
				} else {
					throw new IOException("'" + method + "' is not supported");
				}
			}

			status = socket.responseHeader.getStatus();

		} catch (SocketException e) {
			throw new SocketException("Error communicating with proxy server "
					+ proxyHost + ":" + proxyPort + " (" + e.getMessage() + ")");
		} finally {

		}

		if ((status < 200) || (status > 299)) {
			throw new IOException("Proxy tunnel setup failed: "
					+ socket.responseHeader.getStartLine());
		}

		socket.setSoTimeout(0);
		return socket;
	}

	public String toString() {
		return "HTTPProxySocket [Proxy IP=" + socket.getInetAddress()
				+ ",Proxy Port=" + getPort() + ",localport="
				+ socket.getLocalPort() + "Remote Host=" + remoteHost
				+ "Remote Port=" + String.valueOf(remotePort) + "]";
	}

	HttpHeader getResponseHeader() {
		return responseHeader;
	}

	public String getHost() {
		return remoteHost;
	}

	public SshTransport duplicate() throws IOException {
		return connectViaProxy(remoteHost, remotePort, proxyHost, proxyPort,
				username, password, userAgent);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy