aboutsummaryrefslogtreecommitdiffstats
path: root/sshlib/src/main/java/com/trilead/ssh2/HTTPProxyData.java
diff options
context:
space:
mode:
Diffstat (limited to 'sshlib/src/main/java/com/trilead/ssh2/HTTPProxyData.java')
-rw-r--r--sshlib/src/main/java/com/trilead/ssh2/HTTPProxyData.java114
1 files changed, 109 insertions, 5 deletions
diff --git a/sshlib/src/main/java/com/trilead/ssh2/HTTPProxyData.java b/sshlib/src/main/java/com/trilead/ssh2/HTTPProxyData.java
index 2edffe6..3c3c54a 100644
--- a/sshlib/src/main/java/com/trilead/ssh2/HTTPProxyData.java
+++ b/sshlib/src/main/java/com/trilead/ssh2/HTTPProxyData.java
@@ -1,6 +1,16 @@
package com.trilead.ssh2;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+
+import com.trilead.ssh2.crypto.Base64;
+import com.trilead.ssh2.transport.ClientServerHello;
+
/**
* A <code>HTTPProxyData</code> object is used to specify the needed connection data
* to connect through a HTTP proxy.
@@ -13,11 +23,11 @@ package com.trilead.ssh2;
public class HTTPProxyData implements ProxyData
{
- public final String proxyHost;
- public final int proxyPort;
- public final String proxyUser;
- public final String proxyPass;
- public final String[] requestHeaderLines;
+ private final String proxyHost;
+ private final int proxyPort;
+ private final String proxyUser;
+ private final String proxyPass;
+ private final String[] requestHeaderLines;
/**
* Same as calling {@link #HTTPProxyData(String, int, String, String) HTTPProxyData(proxyHost, proxyPort, <code>null</code>, <code>null</code>)}
@@ -80,4 +90,98 @@ public class HTTPProxyData implements ProxyData
this.proxyPass = proxyPass;
this.requestHeaderLines = requestHeaderLines;
}
+
+ @Override
+ public Socket openConnection(String hostname, int port, int connectTimeout) throws IOException {
+ Socket sock = new Socket();
+
+ InetAddress addr = InetAddress.getByName(proxyHost);
+ sock.connect(new InetSocketAddress(addr, proxyPort), connectTimeout);
+ sock.setSoTimeout(0);
+
+ /* OK, now tell the proxy where we actually want to connect to */
+
+ StringBuffer sb = new StringBuffer();
+
+ sb.append("CONNECT ");
+ sb.append(hostname);
+ sb.append(':');
+ sb.append(port);
+ sb.append(" HTTP/1.0\r\n");
+
+ if ((proxyUser != null) && (proxyPass != null))
+ {
+ String credentials = proxyUser + ":" + proxyPass;
+ char[] encoded = Base64.encode(credentials.getBytes("ISO-8859-1"));
+ sb.append("Proxy-Authorization: Basic ");
+ sb.append(encoded);
+ sb.append("\r\n");
+ }
+
+ if (requestHeaderLines != null)
+ {
+ for (int i = 0; i < requestHeaderLines.length; i++)
+ {
+ if (requestHeaderLines[i] != null)
+ {
+ sb.append(requestHeaderLines[i]);
+ sb.append("\r\n");
+ }
+ }
+ }
+
+ sb.append("\r\n");
+
+ OutputStream out = sock.getOutputStream();
+
+ out.write(sb.toString().getBytes("ISO-8859-1"));
+ out.flush();
+
+ /* Now parse the HTTP response */
+
+ byte[] buffer = new byte[1024];
+ InputStream in = sock.getInputStream();
+
+ int len = ClientServerHello.readLineRN(in, buffer);
+
+ String httpReponse = new String(buffer, 0, len, "ISO-8859-1");
+
+ if (httpReponse.startsWith("HTTP/") == false)
+ 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 = 0;
+
+ 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);
+ }
+
+ /* OK, read until empty line */
+
+ while (true)
+ {
+ len = ClientServerHello.readLineRN(in, buffer);
+ if (len == 0)
+ break;
+ }
+
+ return sock;
+ }
}