Subversion Repositories javautils

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * ====================================================================
  3.  * Licensed to the Apache Software Foundation (ASF) under one
  4.  * or more contributor license agreements.  See the NOTICE file
  5.  * distributed with this work for additional information
  6.  * regarding copyright ownership.  The ASF licenses this file
  7.  * to you under the Apache License, Version 2.0 (the
  8.  * "License"); you may not use this file except in compliance
  9.  * with the License.  You may obtain a copy of the License at
  10.  *
  11.  *   http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing,
  14.  * software distributed under the License is distributed on an
  15.  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  16.  * KIND, either express or implied.  See the License for the
  17.  * specific language governing permissions and limitations
  18.  * under the License.
  19.  * ====================================================================
  20.  *
  21.  * This software consists of voluntary contributions made by many
  22.  * individuals on behalf of the Apache Software Foundation.  For more
  23.  * information on the Apache Software Foundation, please see
  24.  * <http://www.apache.org/>.
  25.  *
  26.  */
  27.  
  28. package org.apache.http.examples.conn;
  29.  
  30. import org.apache.http.Header;
  31. import org.apache.http.HttpHost;
  32. import org.apache.http.HttpRequest;
  33. import org.apache.http.HttpResponse;
  34. import org.apache.http.HttpVersion;
  35. import org.apache.http.conn.ClientConnectionOperator;
  36. import org.apache.http.conn.OperatedClientConnection;
  37. import org.apache.http.conn.scheme.PlainSocketFactory;
  38. import org.apache.http.conn.scheme.Scheme;
  39. import org.apache.http.conn.scheme.SchemeRegistry;
  40. import org.apache.http.conn.ssl.SSLSocketFactory;
  41. import org.apache.http.impl.conn.DefaultClientConnectionOperator;
  42. import org.apache.http.message.BasicHttpRequest;
  43. import org.apache.http.params.BasicHttpParams;
  44. import org.apache.http.params.HttpParams;
  45. import org.apache.http.params.HttpProtocolParams;
  46. import org.apache.http.protocol.HttpContext;
  47. import org.apache.http.protocol.BasicHttpContext;
  48.  
  49. /**
  50.  * How to open a secure connection through a proxy using
  51.  * {@link ClientConnectionOperator ClientConnectionOperator}.
  52.  * This exemplifies the <i>opening</i> of the connection only.
  53.  * The message exchange, both subsequently and for tunnelling,
  54.  * should not be used as a template.
  55.  *
  56.  * @since 4.0
  57.  */
  58. public class OperatorConnectProxy {
  59.  
  60.     public static void main(String[] args) throws Exception {
  61.  
  62.         // make sure to use a proxy that supports CONNECT
  63.         HttpHost target = new HttpHost("issues.apache.org", 443, "https");
  64.         HttpHost proxy = new HttpHost("127.0.0.1", 8666, "http");
  65.  
  66.         // some general setup
  67.         // Register the "http" and "https" protocol schemes, they are
  68.         // required by the default operator to look up socket factories.
  69.         SchemeRegistry supportedSchemes = new SchemeRegistry();
  70.         supportedSchemes.register(new Scheme("http",
  71.                 PlainSocketFactory.getSocketFactory(), 80));
  72.         supportedSchemes.register(new Scheme("https",
  73.                 SSLSocketFactory.getSocketFactory(), 443));
  74.  
  75.         // Prepare parameters.
  76.         // Since this example doesn't use the full core framework,
  77.         // only few parameters are actually required.
  78.         HttpParams params = new BasicHttpParams();
  79.         HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
  80.         HttpProtocolParams.setUseExpectContinue(params, false);
  81.  
  82.         // one operator can be used for many connections
  83.         ClientConnectionOperator scop = new DefaultClientConnectionOperator(supportedSchemes);
  84.  
  85.         HttpRequest req = new BasicHttpRequest("OPTIONS", "*", HttpVersion.HTTP_1_1);
  86.         // In a real application, request interceptors should be used
  87.         // to add the required headers.
  88.         req.addHeader("Host", target.getHostName());
  89.        
  90.         HttpContext ctx = new BasicHttpContext();
  91.  
  92.         OperatedClientConnection conn = scop.createConnection();
  93.         try {
  94.             System.out.println("opening connection to " + proxy);
  95.             scop.openConnection(conn, proxy, null, ctx, params);
  96.  
  97.             // Creates a request to tunnel a connection.
  98.             // For details see RFC 2817, section 5.2
  99.             String authority = target.getHostName() + ":" + target.getPort();
  100.             HttpRequest connect = new BasicHttpRequest("CONNECT", authority,
  101.                     HttpVersion.HTTP_1_1);
  102.             // In a real application, request interceptors should be used
  103.             // to add the required headers.
  104.             connect.addHeader("Host", authority);
  105.  
  106.             System.out.println("opening tunnel to " + target);
  107.             conn.sendRequestHeader(connect);
  108.             // there is no request entity
  109.             conn.flush();
  110.  
  111.             System.out.println("receiving confirmation for tunnel");
  112.             HttpResponse connected = conn.receiveResponseHeader();
  113.             System.out.println("----------------------------------------");
  114.             printResponseHeader(connected);
  115.             System.out.println("----------------------------------------");
  116.             int status = connected.getStatusLine().getStatusCode();
  117.             if ((status < 200) || (status > 299)) {
  118.                 System.out.println("unexpected status code " + status);
  119.                 System.exit(1);
  120.             }
  121.             System.out.println("receiving response body (ignored)");
  122.             conn.receiveResponseEntity(connected);
  123.  
  124.             // Now we have a tunnel to the target. As we will be creating a
  125.             // layered TLS/SSL socket immediately afterwards, updating the
  126.             // connection with the new target is optional - but good style.
  127.             // The scheme part of the target is already "https", though the
  128.             // connection is not yet switched to the TLS/SSL protocol.
  129.             conn.update(null, target, false, params);
  130.  
  131.             System.out.println("layering secure connection");
  132.             scop.updateSecureConnection(conn, target, ctx, params);
  133.  
  134.             // finally we have the secure connection and can send the request
  135.  
  136.             System.out.println("sending request");
  137.             conn.sendRequestHeader(req);
  138.             // there is no request entity
  139.             conn.flush();
  140.  
  141.             System.out.println("receiving response header");
  142.             HttpResponse rsp = conn.receiveResponseHeader();
  143.  
  144.             System.out.println("----------------------------------------");
  145.             printResponseHeader(rsp);
  146.             System.out.println("----------------------------------------");
  147.  
  148.         } finally {
  149.             System.out.println("closing connection");
  150.             conn.close();
  151.         }
  152.     }
  153.  
  154.     private final static void printResponseHeader(HttpResponse rsp) {
  155.         System.out.println(rsp.getStatusLine());
  156.         Header[] headers = rsp.getAllHeaders();
  157.         for (int i=0; i<headers.length; i++) {
  158.             System.out.println(headers[i]);
  159.         }
  160.     }
  161.  
  162. }
  163.  
  164.