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

com.sshtools.net.HttpProxyTransport 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 java.util.Enumeration;
import java.util.Hashtable;

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 HttpProxyTransport extends Socket implements SshTransport {
	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 HttpRequest request = new HttpRequest();
	private Hashtable optionalHeaders;

	private static int connectionTimeout = 30000;

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

		connect(new InetSocketAddress(proxyHost, proxyPort), connectionTimeout);
		setSoTimeout(connectionTimeout);
	}

	public static void setConnectionTimeout(int connectionTimeout) {
		HttpProxyTransport.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 HttpProxyTransport
	 * @throws IOException
	 * @throws UnknownHostException
	 */
	public static HttpProxyTransport connectViaProxy(String host, int port,
			String proxyHost, int proxyPort, String username, String password,
			String userAgent) throws IOException, UnknownHostException {
		return connectViaProxy(host, port, proxyHost, proxyPort, username,
				password, userAgent, null);
	}

	/**
	 * 
	 * @param host
	 * @param port
	 * @param proxyHost
	 * @param proxyPort
	 * @param username
	 * @param password
	 * @param userAgent
	 * @param optionalHeaders
	 * @return
	 * @throws IOException
	 * @throws UnknownHostException
	 */
	public static HttpProxyTransport connectViaProxy(String host, int port,
			String proxyHost, int proxyPort, String username, String password,
			String userAgent, Hashtable optionalHeaders)
			throws IOException, UnknownHostException {
		HttpProxyTransport socket = new HttpProxyTransport(host, port,
				proxyHost, proxyPort);
		int status;
		socket.username = username;
		socket.password = password;
		socket.userAgent = userAgent;
		socket.optionalHeaders = optionalHeaders;

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

			socket.request.setHeaderBegin("CONNECT " + host + ":" + port
					+ " HTTP/1.0");
			socket.request.setHeaderField("User-Agent", userAgent);
			socket.request.setHeaderField("Pragma", "No-Cache");
			socket.request.setHeaderField("Host", host);
			socket.request.setHeaderField("Proxy-Connection", "Keep-Alive");

			if (optionalHeaders != null) {
				for (Enumeration e = optionalHeaders.keys(); e
						.hasMoreElements();) {
					String h = e.nextElement();
					socket.request.setHeaderField(h, optionalHeaders.get(h));
				}
			}
			out.write(socket.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 HttpProxyTransport(host, port, proxyHost,
							proxyPort);
					in = socket.getInputStream();
					out = socket.getOutputStream();
					socket.request.setBasicAuthentication(username, password);
					out.write(socket.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() + ")");
		}

		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=" + getInetAddress() + ",Proxy Port="
				+ getPort() + ",localport=" + 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, optionalHeaders);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy