Mercurial > 510Connectbot
diff src/ch/ethz/ssh2/transport/HTTPProxyClientTransportManager.java @ 273:91a31873c42a ganymed
start conversion from trilead to ganymed
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Fri, 18 Jul 2014 11:21:46 -0700 |
parents | |
children | 071eccdff8ea |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ch/ethz/ssh2/transport/HTTPProxyClientTransportManager.java Fri Jul 18 11:21:46 2014 -0700 @@ -0,0 +1,111 @@ +package ch.ethz.ssh2.transport; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.net.Socket; + +import ch.ethz.ssh2.HTTPProxyData; +import ch.ethz.ssh2.HTTPProxyException; +import ch.ethz.ssh2.crypto.Base64; +import ch.ethz.ssh2.util.StringEncoder; + +/** + * @version $Id: HTTPProxyClientTransportManager.java 155 2014-04-28 12:01:19Z dkocher@sudo.ch $ + */ +public class HTTPProxyClientTransportManager extends ClientTransportManager { + + /** + * Used to tell the library that the connection shall be established through a proxy server. + */ + + private HTTPProxyData pd; + + private final Socket sock; + + public HTTPProxyClientTransportManager(final Socket socket, final HTTPProxyData pd) { + super(socket); + this.sock = socket; + this.pd = pd; + } + + @Override + protected void connect(final String hostname, final int port, final int connectTimeout) throws IOException { + + sock.connect(new InetSocketAddress(pd.proxyHost, pd.proxyPort), connectTimeout); + + // Tell the proxy where we actually want to connect to + StringBuilder sb = new StringBuilder(); + + sb.append("CONNECT "); + sb.append(hostname); + sb.append(':'); + sb.append(port); + sb.append(" HTTP/1.0\r\n"); + + if((pd.proxyUser != null) && (pd.proxyPass != null)) { + String credentials = pd.proxyUser + ":" + pd.proxyPass; + char[] encoded = Base64.encode(StringEncoder.GetBytes(credentials)); + sb.append("Proxy-Authorization: Basic "); + sb.append(encoded); + sb.append("\r\n"); + } + + if(pd.requestHeaderLines != null) { + for(int i = 0; i < pd.requestHeaderLines.length; i++) { + if(pd.requestHeaderLines[i] != null) { + sb.append(pd.requestHeaderLines[i]); + sb.append("\r\n"); + } + } + } + + sb.append("\r\n"); + + OutputStream out = sock.getOutputStream(); + + out.write(StringEncoder.GetBytes(sb.toString())); + out.flush(); + + // Parse the HTTP response + + InputStream in = sock.getInputStream(); + + final LineNumberReader reader = new LineNumberReader(new InputStreamReader(in)); + String httpReponse = reader.readLine(); + + if(!httpReponse.startsWith("HTTP/")) { + throw new IOException("The proxy did not send back a valid HTTP response."); + } + + // "HTTP/1.X XYZ X" => 14 characters minimum + + if((httpReponse.length() < 14) || (httpReponse.charAt(8) != ' ') || (httpReponse.charAt(12) != ' ')) { + throw new IOException("The proxy did not send back a valid HTTP response."); + } + + int errorCode; + + try { + errorCode = Integer.parseInt(httpReponse.substring(9, 12)); + } + catch(NumberFormatException ignore) { + throw new IOException("The proxy did not send back a valid HTTP response."); + } + + if((errorCode < 0) || (errorCode > 999)) { + throw new IOException("The proxy did not send back a valid HTTP response."); + } + + if(errorCode != 200) { + throw new HTTPProxyException(httpReponse.substring(13), errorCode); + } + + while(reader.readLine() != null) { + // Read until empty line + } + } +}