View Javadoc
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.nio.integration;
29  
30  import java.io.IOException;
31  import java.math.BigInteger;
32  import java.net.InetSocketAddress;
33  import java.net.URL;
34  import java.util.concurrent.Future;
35  
36  import javax.net.ssl.SSLContext;
37  import javax.net.ssl.SSLEngine;
38  import javax.net.ssl.SSLException;
39  import javax.net.ssl.SSLSession;
40  
41  import org.apache.http.HttpException;
42  import org.apache.http.HttpHost;
43  import org.apache.http.HttpRequest;
44  import org.apache.http.HttpResponse;
45  import org.apache.http.impl.nio.pool.BasicNIOConnFactory;
46  import org.apache.http.message.BasicHttpRequest;
47  import org.apache.http.nio.NHttpConnection;
48  import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
49  import org.apache.http.nio.reactor.IOSession;
50  import org.apache.http.nio.reactor.ListenerEndpoint;
51  import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
52  import org.apache.http.nio.testserver.ClientConnectionFactory;
53  import org.apache.http.nio.testserver.HttpClientNio;
54  import org.apache.http.nio.testserver.HttpServerNio;
55  import org.apache.http.nio.testserver.ServerConnectionFactory;
56  import org.apache.http.protocol.HttpContext;
57  import org.apache.http.protocol.HttpCoreContext;
58  import org.apache.http.protocol.HttpRequestHandler;
59  import org.apache.http.ssl.SSLContextBuilder;
60  import org.junit.After;
61  import org.junit.Assert;
62  import org.junit.Test;
63  
64  public class TestCustomSSL {
65  
66      protected HttpServerNio server;
67      protected HttpClientNio client;
68  
69      @After
70      public void shutDownClient() throws Exception {
71          if (this.client != null) {
72              this.client.shutdown();
73              this.client = null;
74          }
75      }
76  
77      @After
78      public void shutDownServer() throws Exception {
79          if (this.server != null) {
80              this.server.shutdown();
81              this.server = null;
82          }
83      }
84  
85      @Test
86      public void testCustomSSLContext() throws Exception {
87          final SSLSetupHandler sslSetupHandler = new SSLSetupHandler() {
88  
89              @Override
90              public void initalize(
91                      final SSLEngine sslengine) throws SSLException {
92              }
93  
94              @Override
95              public void verify(
96                      final IOSession iosession, final SSLSession sslsession) throws SSLException {
97                  final BigInteger sslid = new BigInteger(sslsession.getId());
98                  iosession.setAttribute("ssl-id", sslid);
99              }
100 
101         };
102 
103         final HttpRequestHandler requestHandler = new HttpRequestHandler() {
104 
105             @Override
106             public void handle(
107                     final HttpRequest request,
108                     final HttpResponse response,
109                     final HttpContext context) throws HttpException, IOException {
110                 final NHttpConnection conn = (NHttpConnection) context.getAttribute(
111                         HttpCoreContext.HTTP_CONNECTION);
112                 final BigInteger sslid = (BigInteger) conn.getContext().getAttribute(
113                         "ssl-id");
114                 Assert.assertNotNull(sslid);
115             }
116 
117         };
118 
119         final URL keyStoreURL = getClass().getResource("/test.keystore");
120         final String storePassword = "nopassword";
121         final SSLContext serverSSLContext = SSLContextBuilder.create()
122                 .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
123                 .loadKeyMaterial(keyStoreURL, storePassword.toCharArray(), storePassword.toCharArray())
124                 .build();
125         this.server = new HttpServerNio();
126         this.server.setConnectionFactory(new ServerConnectionFactory(serverSSLContext, sslSetupHandler));
127         this.server.setTimeout(5000);
128 
129         final SSLContext clientSSLContext = SSLContextBuilder.create()
130                 .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
131                 .build();
132 
133         this.client = new HttpClientNio(new BasicNIOConnFactory(new ClientConnectionFactory(clientSSLContext), null));
134         this.client.setTimeout(5000);
135 
136         this.server.registerHandler("*", new BasicAsyncRequestHandler(requestHandler));
137 
138         this.server.start();
139         this.client.start();
140 
141         final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
142         endpoint.waitFor();
143 
144         final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
145 
146         final HttpHost target = new HttpHost("localhost", address.getPort());
147         final BasicHttpRequest request = new BasicHttpRequest("GET", "/");
148         final Future<HttpResponse> future = this.client.execute(target, request);
149         final HttpResponse response = future.get();
150         Assert.assertNotNull(response);
151         Assert.assertEquals(200, response.getStatusLine().getStatusCode());
152     }
153 
154 }