You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ro...@apache.org on 2007/01/05 18:56:08 UTC

svn commit: r493102 - in /jakarta/httpcomponents/httpclient/trunk/src: examples/org/apache/http/examples/conn/OperatorConnectProxy.java java/org/apache/http/conn/ssl/SSLSocketFactory.java

Author: rolandw
Date: Fri Jan  5 09:56:06 2007
New Revision: 493102

URL: http://svn.apache.org/viewvc?view=rev&rev=493102
Log:
new connection interfaces, step 5 - example for SSL tunnelling through proxy

Added:
    jakarta/httpcomponents/httpclient/trunk/src/examples/org/apache/http/examples/conn/OperatorConnectProxy.java   (with props)
Modified:
    jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/conn/ssl/SSLSocketFactory.java

Added: jakarta/httpcomponents/httpclient/trunk/src/examples/org/apache/http/examples/conn/OperatorConnectProxy.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/src/examples/org/apache/http/examples/conn/OperatorConnectProxy.java?view=auto&rev=493102
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/src/examples/org/apache/http/examples/conn/OperatorConnectProxy.java (added)
+++ jakarta/httpcomponents/httpclient/trunk/src/examples/org/apache/http/examples/conn/OperatorConnectProxy.java Fri Jan  5 09:56:06 2007
@@ -0,0 +1,260 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.examples.conn;
+
+
+import org.apache.http.HttpHost;
+import org.apache.http.Header;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpVersion;
+import org.apache.http.message.BasicHttpRequest;
+import org.apache.http.params.HttpParams;
+import org.apache.http.params.HttpProtocolParams;
+import org.apache.http.impl.DefaultHttpParams;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpExecutionContext;
+
+import org.apache.http.conn.Scheme;
+import org.apache.http.conn.SocketFactory;
+import org.apache.http.conn.PlainSocketFactory;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.conn.UnmanagedClientConnection;
+import org.apache.http.conn.SocketConnectionOperator;
+import org.apache.http.conn.impl.DefaultClientConnection;
+import org.apache.http.conn.impl.DefaultSocketConnectionOperator;
+
+
+
+/**
+ * How to open a secure connection through a proxy using
+ * {@link SocketConnectionOperator SocketConnectionOperator}.
+ * This exemplifies the <i>opening</i> of the connection only.
+ * The message exchange, both subsequently and for tunnelling,
+ * should not be used as a template.
+ *
+ * @author <a href="mailto:rolandw at apache.org">Roland Weber</a>
+ *
+ *
+ * <!-- empty lines above to avoid 'svn diff' context problems -->
+ * @version $Revision$ $Date$
+ *
+ * @since 4.0
+ */
+public class OperatorConnectProxy {
+
+    /**
+     * The default parameters.
+     * Instantiated in {@link #setup setup}.
+     */
+    private static HttpParams defaultParameters = null;
+
+
+    /**
+     * Main entry point to this example.
+     *
+     * @param args      ignored
+     */
+    public final static void main(String[] args)
+        throws Exception {
+
+        // make sure to use a proxy that supports CONNECT
+        final HttpHost target =
+            new HttpHost("issues.apache.org", 443, "https");
+        final HttpHost proxy =
+            new HttpHost("127.0.0.1", 8666, "http");
+
+        setup(); // some general setup
+
+        // one operator can be used for many connections
+        SocketConnectionOperator  scop = createOperator();
+        UnmanagedClientConnection conn = createConnection();
+
+        HttpRequest req = createRequest(target);
+        HttpContext ctx = createContext();
+
+        System.out.println("opening connection to " + proxy);
+        scop.openConnection(conn, proxy, ctx, getParams());
+
+        HttpRequest connect = createConnect(target);
+        System.out.println("opening tunnel to " + target);
+        conn.sendRequestHeader(connect);
+        // there is no request entity
+        conn.flush();
+
+        System.out.println("receiving confirmation for tunnel");
+        HttpResponse connected = conn.receiveResponseHeader(getParams());
+        System.out.println("----------------------------------------");
+        printResponseHeader(connected);
+        System.out.println("----------------------------------------");
+        int status = connected.getStatusLine().getStatusCode();
+        if ((status < 200) || (status > 299)) {
+            System.out.println("unexpected status code " + status);
+            System.exit(1);
+        }
+        System.out.println("receiving response body (ignored)");
+        conn.receiveResponseEntity(connected);
+
+        // Now we have a tunnel to the target. As we will be creating a
+        // layered TLS/SSL socket immediately afterwards, updating the
+        // connection with the new target is optional - but good style.
+        // The scheme part of the target is already "https", though the
+        // connection is not yet switched to the TLS/SSL protocol.
+        conn.update(null, target, false, getParams());
+
+        System.out.println("layering secure connection");
+        scop.updateSecureConnection(conn, target, ctx, getParams());
+
+        // finally we have the secure connection and can send the request
+
+        System.out.println("sending request");
+        conn.sendRequestHeader(req);
+        // there is no request entity
+        conn.flush();
+
+        System.out.println("receiving response header");
+        HttpResponse rsp = conn.receiveResponseHeader(getParams());
+
+        System.out.println("----------------------------------------");
+        printResponseHeader(rsp);
+        System.out.println("----------------------------------------");
+
+        System.out.println("closing connection");
+        conn.close();
+
+    } // main
+
+
+    private final static SocketConnectionOperator createOperator() {
+        return new DefaultSocketConnectionOperator();
+    }
+
+    private final static UnmanagedClientConnection createConnection() {
+        return new DefaultClientConnection();
+    }
+
+
+    /**
+     * Performs general setup.
+     * This should be called only once.
+     */
+    private final static void setup() {
+
+        // Register the "http" and "https" protocol schemes, they are
+        // required by the default operator to look up socket factories.
+        SocketFactory sf = PlainSocketFactory.getSocketFactory();
+        Scheme.registerScheme("http", new Scheme("http", sf, 80));
+        sf = SSLSocketFactory.getSocketFactory();
+        Scheme.registerScheme("https", new Scheme("https", sf, 80));
+
+        // Prepare parameters.
+        // Since this example doesn't use the full core framework,
+        // only few parameters are actually required.
+        HttpParams params = new DefaultHttpParams();
+        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
+        HttpProtocolParams.setUseExpectContinue(params, false);
+        defaultParameters = params;
+
+    } // setup
+
+
+    private final static HttpParams getParams() {
+        return defaultParameters;
+    }
+
+
+    /**
+     * Creates a request to tunnel a connection.
+     * In a real application, request interceptors should be used
+     * to add the required headers.
+     *
+     * @param target    the target server for the tunnel
+     *
+     * @return  a CONNECT request without an entity
+     */
+    private final static HttpRequest createConnect(HttpHost target) {
+
+        // see RFC 2817, section 5.2
+        final String authority = target.getHostName()+":"+target.getPort();
+
+        HttpRequest req = new BasicHttpRequest
+            ("CONNECT", authority, HttpVersion.HTTP_1_1);
+
+        req.addHeader("Host", authority);
+
+        return req;
+    }
+
+
+    /**
+     * Creates a request to execute in this example.
+     * In a real application, request interceptors should be used
+     * to add the required headers.
+     *
+     * @param target    the target server for the request
+     *
+     * @return  a request without an entity
+     */
+    private final static HttpRequest createRequest(HttpHost target) {
+
+        HttpRequest req = new BasicHttpRequest
+            ("OPTIONS", "*", HttpVersion.HTTP_1_1);
+
+        req.addHeader("Host", target.getHostName());
+
+        return req;
+    }
+
+
+    /**
+     * Creates a context for executing a request.
+     * Since this example doesn't really use the execution framework,
+     * the context can be left empty.
+     *
+     * @return  a new, empty context
+     */
+    private final static HttpContext createContext() {
+        return new HttpExecutionContext(null);
+    }
+
+
+    private final static void printResponseHeader(HttpResponse rsp) {
+
+        System.out.println(rsp.getStatusLine());
+        Header[] headers = rsp.getAllHeaders();
+        for (int i=0; i<headers.length; i++) {
+            System.out.println(headers[i]);
+        }
+    }
+
+} // class OperatorConnectProxy
+

Propchange: jakarta/httpcomponents/httpclient/trunk/src/examples/org/apache/http/examples/conn/OperatorConnectProxy.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/httpcomponents/httpclient/trunk/src/examples/org/apache/http/examples/conn/OperatorConnectProxy.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/httpcomponents/httpclient/trunk/src/examples/org/apache/http/examples/conn/OperatorConnectProxy.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/conn/ssl/SSLSocketFactory.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/conn/ssl/SSLSocketFactory.java?view=diff&rev=493102&r1=493101&r2=493102
==============================================================================
--- jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/conn/ssl/SSLSocketFactory.java (original)
+++ jakarta/httpcomponents/httpclient/trunk/src/java/org/apache/http/conn/ssl/SSLSocketFactory.java Fri Jan  5 09:56:06 2007
@@ -142,7 +142,7 @@
     public static final String SSLV2 = "SSLv2";
     
     /**
-     * The factory singleton.
+     * The factory using the default JVM settings for secure connections.
      */
     private static final SSLSocketFactory DEFAULT_FACTORY = new SSLSocketFactory();
     
@@ -204,7 +204,12 @@
         this(TLS, null, null, truststore, null);
     }
 
-    public SSLSocketFactory() {
+    /**
+     * Creates the default SSL socket factory.
+     * This constructor is used exclusively to instantiate the factory for
+     * {@link #getSocketFactory getSocketFactory}.
+     */
+    private SSLSocketFactory() {
         super();
         this.sslcontext = null;
         this.socketfactory = HttpsURLConnection.getDefaultSSLSocketFactory();