dug         01/08/21 12:22:35

  Modified:    java/src/org/apache/soap/util/net HTTPUtils.java
                        SSLUtils.java
  Log:
  Add HTTPS proxy support (by David Melgar - [EMAIL PROTECTED])
  
  Revision  Changes    Path
  1.23      +13 -11    xml-soap/java/src/org/apache/soap/util/net/HTTPUtils.java
  
  Index: HTTPUtils.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/util/net/HTTPUtils.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- HTTPUtils.java    2001/08/02 00:20:14     1.22
  +++ HTTPUtils.java    2001/08/21 19:22:35     1.23
  @@ -99,26 +99,24 @@
        throws Exception {
         Socket s = null;
         String host = null;
  -      int port;
  -
  -      if (httpProxyHost == null) {
  -          host = url.getHost();
  -          port = targetPort;
  -      } else {
  -          host = httpProxyHost;
  -          port = httpProxyPort;
  -      }
  +      int port = targetPort;
  +      host = url.getHost();
   
         if (url.getProtocol().equalsIgnoreCase("HTTPS")) {
             // Using reflection to avoid compile time dependencies
             Class SSLUtilsClass =
                 Class.forName("org.apache.soap.util.net.SSLUtils");
  -          Class[] paramTypes = new Class[] {String.class, int.class};
  +          Class[] paramTypes = new Class[] {String.class, int.class, String.class, 
int.class};
             Method buildSSLSocket = SSLUtilsClass.getMethod(
                 "buildSSLSocket", paramTypes);
  -          Object[] params = new Object[] {host, new Integer(port)};
  +          Object[] params = new Object[] {host, new Integer(port),
  +              httpProxyHost, new Integer(httpProxyPort)};
             s = (Socket)buildSSLSocket.invoke(null, params);
         } else {
  +          if (httpProxyHost != null) {
  +              host = httpProxyHost;
  +              port = httpProxyPort;
  +          }
             s = new Socket(host, port);
         }
   
  @@ -193,6 +191,10 @@
             port = getPort(url);
   
             s = buildSocket(url, port, httpProxyHost, httpProxyPort);
  +          if (url.getProtocol().equalsIgnoreCase("HTTPS")) {
  +             // Ignore proxy from now on. Buildsocket takes handles it
  +             httpProxyHost = null;
  +          }
   
             if (timeout > 0)  // Should be redundant but not every JVM likes this
                 s.setSoTimeout(timeout);
  
  
  
  1.4       +134 -21   xml-soap/java/src/org/apache/soap/util/net/SSLUtils.java
  
  Index: SSLUtils.java
  ===================================================================
  RCS file: /home/cvs/xml-soap/java/src/org/apache/soap/util/net/SSLUtils.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SSLUtils.java     2001/02/12 07:02:26     1.3
  +++ SSLUtils.java     2001/08/21 19:22:35     1.4
  @@ -69,30 +69,143 @@
    * @author Chris Nelson ([EMAIL PROTECTED])
    */
   public class SSLUtils {
  +        static String tunnelHost;
  +        static int tunnelPort;
        
        /** This method builds an SSL socket, after auto-starting SSL */
  -     public static Socket buildSSLSocket(String host, int port)
  +     public static Socket buildSSLSocket(String host, int port, String 
httpProxyHost,
  +                                            int httpProxyPort)
                throws IOException, UnknownHostException
        {
  -         SSLSocketFactory factory =
  -             (SSLSocketFactory)SSLSocketFactory.getDefault();
  -         SSLSocket sslSocket = 
  -             (SSLSocket)factory.createSocket(host, port);
  -
  -             /*
  -          * Handshaking is started manually in this example because
  -          * PrintWriter catches all IOExceptions (including
  -          * SSLExceptions), sets an internal error flag, and then
  -          * returns without rethrowing the exception.
  -          *
  -          * Unfortunately, this means any error messages are lost,
  -          * which caused lots of confusion for others using this
  -          * code.  The only way to tell there was an error is to call
  -          * PrintWriter.checkError().
  -          */
  -         sslSocket.startHandshake();   
  -         
  -         return  sslSocket;  
  +           SSLSocket sslSocket =  null;
  +           SSLSocketFactory factory =
  +              (SSLSocketFactory)SSLSocketFactory.getDefault();
  +
  +           // Determine if a proxy should be used. Use system properties if set
  +           // Otherwise use http proxy. If neither is set, dont use a proxy
  +           tunnelHost = System.getProperty("https.proxyHost");
  +           tunnelPort = Integer.getInteger("https.proxyPort", 80).intValue();
  +
  +           if (tunnelHost==null) {
  +              // Try to use http proxy instead
  +              tunnelHost = httpProxyHost;
  +              tunnelPort = httpProxyPort;
  +           }
  +
  +           /*
  +           System.out.println("https proxyHost=" + tunnelHost +
  +                              " proxyPort=" + tunnelPort +
  +                              " host=" + host +
  +                              " port=" + port);
  +           */
  +
  +           /*                         
  +            * If a proxy has been set...
  +            * Set up a socket to do tunneling through the proxy.
  +            * Start it off as a regular socket, then layer SSL
  +            * over the top of it.
  +            */
  +           if (tunnelHost==null) {
  +              sslSocket = (SSLSocket)factory.createSocket(host, port);
  +           } else {
  +              Socket tunnel = new Socket(tunnelHost, tunnelPort);
  +              doTunnelHandshake(tunnel, host, port);
  +
  +              // Overlay tunnel socket with SSL
  +              sslSocket = (SSLSocket)factory.createSocket(tunnel, host, port, true);
  +           }
  +
  +           /*
  +            * Handshaking is started manually in this example because
  +            * PrintWriter catches all IOExceptions (including
  +            * SSLExceptions), sets an internal error flag, and then
  +            * returns without rethrowing the exception.
  +            *
  +            * Unfortunately, this means any error messages are lost,
  +            * which caused lots of confusion for others using this
  +            * code.  The only way to tell there was an error is to call
  +            * PrintWriter.checkError().
  +            */
  +           sslSocket.startHandshake();   
  +
  +           return  sslSocket;  
            
  -      }
  +     }
  +
  +        static private void doTunnelHandshake(Socket tunnel, String host, int port)
  +         throws IOException
  +        {
  +             OutputStream out = tunnel.getOutputStream();
  +             String msg = "CONNECT " + host + ":" + port + " HTTP/1.0\n"
  +                          + "User-Agent: "
  +                          + sun.net.www.protocol.http.HttpURLConnection.userAgent
  +                          + "\r\n\r\n";
  +             byte b[];
  +             try {
  +                 /*
  +                  * We really do want ASCII7 -- the http protocol doesn't change
  +                  * with locale.
  +                  */
  +                 b = msg.getBytes("ASCII7");
  +             } catch (UnsupportedEncodingException ignored) {
  +                 /*
  +                  * If ASCII7 isn't there, something serious is wrong, but
  +                  * Paranoia Is Good (tm)
  +                  */
  +                 b = msg.getBytes();
  +             }
  +             out.write(b);
  +             out.flush();
  +
  +             /*
  +              * We need to store the reply so we can create a detailed
  +              * error message to the user.
  +              */
  +             byte            reply[] = new byte[200];
  +             int             replyLen = 0;
  +             int             newlinesSeen = 0;
  +             boolean         headerDone = false;     /* Done on first newline */
  +
  +             InputStream     in = tunnel.getInputStream();
  +             boolean         error = false;
  +
  +             while (newlinesSeen < 2) {
  +                 int i = in.read();
  +                 if (i < 0) {
  +                     throw new IOException("Unexpected EOF from proxy");
  +                 }
  +                 if (i == '\n') {
  +                     headerDone = true;
  +                     ++newlinesSeen;
  +                 } else if (i != '\r') {
  +                     newlinesSeen = 0;
  +                     if (!headerDone && replyLen < reply.length) {
  +                         reply[replyLen++] = (byte) i;
  +                     }
  +                 }
  +             }
  +
  +             /*
  +              * Converting the byte array to a string is slightly wasteful
  +              * in the case where the connection was successful, but it's
  +              * insignificant compared to the network overhead.
  +              */
  +             String replyStr;
  +             try {
  +                 replyStr = new String(reply, 0, replyLen, "ASCII7");
  +             } catch (UnsupportedEncodingException ignored) {
  +                 replyStr = new String(reply, 0, replyLen);
  +             }
  +
  +             // Parse response, check for status code
  +             StringTokenizer st = new StringTokenizer(replyStr);
  +             st.nextToken(); // ignore version part
  +             if (!st.nextToken().startsWith("200")) {
  +                throw new IOException("Unable to tunnel through "
  +                        + tunnelHost + ":" + tunnelPort
  +                        + ".  Proxy returns \"" + replyStr + "\"");
  +             }
  +
  +             /* tunneling Handshake was successful! */
  +         }
   }
  
  
  

Reply via email to