add Connection to org.ibex.net
authoradam <adam@megacz.com>
Sat, 17 Mar 2007 08:51:08 +0000 (08:51 +0000)
committeradam <adam@megacz.com>
Sat, 17 Mar 2007 08:51:08 +0000 (08:51 +0000)
darcs-hash:20070317085108-5007d-84d81e2e5eb1ee14634a171edfca1681cf4aee73.gz

src/org/ibex/net/Connection.java [new file with mode: 0644]
src/org/ibex/net/HTTP.java

diff --git a/src/org/ibex/net/Connection.java b/src/org/ibex/net/Connection.java
new file mode 100644 (file)
index 0000000..e97d879
--- /dev/null
@@ -0,0 +1,91 @@
+// Copyright 2000-2005 the Contributors, as shown in the revision logs.
+// Licensed under the Apache Public Source License 2.0 ("the License").
+// You may not use this file except in compliance with the License.
+
+package org.ibex.net;
+
+import java.net.*;
+import java.io.*;
+import org.ibex.io.*;
+import org.ibex.util.*;
+import javax.net.ssl.*;
+
+/** a stream backed by a socket */
+public class Connection extends Stream {
+    protected final Socket s;
+    public final String vhost;
+    public Connection(Socket s, String vhost) { super(s); this.vhost = vhost; this.s = s; }
+    protected Connection(InputStream i, OutputStream o) { super(i, o); vhost = null; s = null; }
+    public Socket getSocket() { return s; }
+
+    public int getLocalPort()                 { return s.getLocalPort(); }
+    public InetAddress getLocalAddress()      { return ((InetSocketAddress)s.getLocalSocketAddress()).getAddress(); }
+    public int getRemotePort()                { return s.getPort(); }
+    public InetAddress getRemoteAddress()     { return ((InetSocketAddress)s.getRemoteSocketAddress()).getAddress(); }
+    public String getRemoteHostname()         { return getRemoteAddress().getHostName(); }
+    public String getVirtualHost()            { return vhost; }
+    public void setTimeout(int ms)            { try { s.setSoTimeout(ms);     } catch(IOException e) { ioe(e); } }
+    public void setTcpNoDelay(boolean delay)  { try { s.setTcpNoDelay(delay); } catch(IOException e) { ioe(e); } }
+
+    /** never throws an exception */
+    public void close()                       { try{if (s!=null) s.close();}catch(Exception e){/*ignore*/} super.close(); }
+
+    public Connection negotiateSSL(boolean server) {
+        try {
+            SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
+            SSLSocket ssl = (SSLSocket) sslsocketfactory.createSocket(s, vhost, s.getLocalPort(), true);
+            ssl.setUseClientMode(!server);
+            return new Connection(ssl, vhost);
+        } catch (IOException e) { ioe(e); }
+        return null;
+    }
+
+    static int ioe(IOException e) {
+        if (e instanceof SocketException && e.toString().indexOf("Connection reset")!=-1)
+            throw new Closed(e.getMessage());
+        throw new StreamException(e);
+    }
+
+    // FEATURE: SOCKSv5
+    // FEATURE: SSL
+    // FEATURE: password authentication (inside SSL)
+    /**
+     *  Implements SOCKSv4 with v4a DNS extension
+     *  @see http://www.socks.nec.com/protocol/socks4.protocol
+     *  @see http://www.socks.nec.com/protocol/socks4a.protocol
+     */
+    public static class SOCKS extends Connection {
+        public SOCKS(String proxyHost, int proxyPort, String host, int port, boolean ssl) throws IOException {
+            super(new SSL(proxyHost, proxyPort, ssl), host);
+            //((SSL)s).negotiateSSL();
+            try {
+                DataOutputStream dos = new DataOutputStream(s.getOutputStream());
+                dos.writeByte(0x04);                         // SOCKSv4(a)
+                dos.writeByte(0x01);                         // CONNECT
+                dos.writeShort(port & 0xffff);               // port
+                //if (addr == null) {
+                dos.writeInt(0x00000001);  // bogus IP
+                //} else dos.write(addr.getAddress());       // actual IP
+                dos.writeByte(0x00);                         // no userid
+                //if (addr == null) {
+                    PrintWriter pw = new PrintWriter(new OutputStreamWriter(dos));
+                    pw.print(host);
+                    pw.flush();
+                    dos.writeByte(0x00);                     // hostname null terminator
+                    //}
+                dos.flush();
+
+                DataInputStream dis = new DataInputStream(s.getInputStream());
+                dis.readByte();                              // reply version
+                byte success = dis.readByte();               // success/fail
+                dis.skip(6);                                 // ip/port
+            
+                if ((int)(success & 0xff) != 90)
+                    throw new StreamException("SOCKS error code "+(success & 0xff));
+
+            } catch (IOException e) { ioe(e); }
+        }
+    }
+
+}
+
index 0bb9f38..d0b03a5 100644 (file)
@@ -762,7 +762,7 @@ public class HTTP {
                 DataOutputStream dos = new DataOutputStream(sock.getOutputStream());
                 dos.writeByte(0x04);                         // SOCKSv4(a)
                 dos.writeByte(0x01);                         // CONNECT
-                dos.writeShort(http.port & 0xffff);               // port
+                dos.writeShort(http.port & 0xffff);          // port
                 if (addr == null) dos.writeInt(0x00000001);  // bogus IP
                 else dos.write(addr.getAddress());           // actual IP
                 dos.writeByte(0x00);                         // no userid