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  package org.apache.hc.core5.http.examples;
28  
29  import java.net.InetAddress;
30  import java.util.concurrent.CountDownLatch;
31  import java.util.concurrent.TimeUnit;
32  
33  import javax.net.ssl.SSLPeerUnverifiedException;
34  import javax.net.ssl.SSLSession;
35  
36  import org.apache.hc.core5.concurrent.FutureCallback;
37  import org.apache.hc.core5.http.HttpConnection;
38  import org.apache.hc.core5.http.HttpHost;
39  import org.apache.hc.core5.http.HttpRequest;
40  import org.apache.hc.core5.http.HttpResponse;
41  import org.apache.hc.core5.http.Message;
42  import org.apache.hc.core5.http.impl.Http1StreamListener;
43  import org.apache.hc.core5.http.impl.bootstrap.AsyncRequesterBootstrap;
44  import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
45  import org.apache.hc.core5.http.message.RequestLine;
46  import org.apache.hc.core5.http.message.StatusLine;
47  import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
48  import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
49  import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
50  import org.apache.hc.core5.http.protocol.HttpCoreContext;
51  import org.apache.hc.core5.http.support.BasicRequestBuilder;
52  import org.apache.hc.core5.io.CloseMode;
53  import org.apache.hc.core5.reactor.IOReactorConfig;
54  import org.apache.hc.core5.util.Timeout;
55  
56  /**
57   * Example of SNI (Server Name Identification) usage with async I/O.
58   */
59  public class AsyncClientSNIExample {
60  
61      public static void main(final String[] args) throws Exception {
62  
63          final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
64                  .setSoTimeout(5, TimeUnit.SECONDS)
65                  .build();
66  
67          // Create and start requester
68          final HttpAsyncRequester requester = AsyncRequesterBootstrap.bootstrap()
69                  .setIOReactorConfig(ioReactorConfig)
70                  .setStreamListener(new Http1StreamListener() {
71  
72                      @Override
73                      public void onRequestHead(final HttpConnection connection, final HttpRequest request) {
74                          System.out.println(connection.getRemoteAddress() + " " + new RequestLine(request));
75                      }
76  
77                      @Override
78                      public void onResponseHead(final HttpConnection connection, final HttpResponse response) {
79                          System.out.println(connection.getRemoteAddress() + " " + new StatusLine(response));
80                      }
81  
82                      @Override
83                      public void onExchangeComplete(final HttpConnection connection, final boolean keepAlive) {
84                          if (keepAlive) {
85                              System.out.println(connection.getRemoteAddress() + " exchange completed (connection kept alive)");
86                          } else {
87                              System.out.println(connection.getRemoteAddress() + " exchange completed (connection closed)");
88                          }
89                      }
90  
91                  })
92                  .create();
93  
94          Runtime.getRuntime().addShutdownHook(new Thread(() -> {
95              System.out.println("HTTP requester shutting down");
96              requester.close(CloseMode.GRACEFUL);
97          }));
98          requester.start();
99  
100         // Physical endpoint (google.com)
101         final InetAddress targetAddress = InetAddress.getByName("www.google.com");
102         // Target host (google.ch)
103         final HttpHost target = new HttpHost("https", targetAddress, "www.google.ch", 443);
104         final HttpCoreContext coreContext = HttpCoreContext.create();
105 
106         final CountDownLatch latch = new CountDownLatch(1);
107         final HttpRequest request = BasicRequestBuilder.get()
108                 .setPath("/")
109                 .build();
110         requester.execute(
111                 target,
112                 new BasicRequestProducer(request, null),
113                 new BasicResponseConsumer<>(new StringAsyncEntityConsumer()),
114                 null,
115                 Timeout.ofSeconds(5),
116                 coreContext,
117                 new FutureCallback<Message<HttpResponse, String>>() {
118 
119                     @Override
120                     public void completed(final Message<HttpResponse, String> message) {
121                         final HttpResponse response = message.getHead();
122                         System.out.println(request.getRequestUri() + "->" + response.getCode());
123                         final SSLSession sslSession = coreContext.getSSLSession();
124                         if (sslSession != null) {
125                             try {
126                                 System.out.println("Peer: " + sslSession.getPeerPrincipal());
127                                 System.out.println("TLS protocol: " + sslSession.getProtocol());
128                                 System.out.println("TLS cipher suite: " + sslSession.getCipherSuite());
129                             } catch (final SSLPeerUnverifiedException ignore) {
130                             }
131                         }
132                         latch.countDown();
133                     }
134 
135                     @Override
136                     public void failed(final Exception ex) {
137                         System.out.println(request.getRequestUri() + "->" + ex);
138                         latch.countDown();
139                     }
140 
141                     @Override
142                     public void cancelled() {
143                         System.out.println(request.getRequestUri() + " cancelled");
144                         latch.countDown();
145                     }
146 
147                 });
148 
149         latch.await();
150         System.out.println("Shutting down I/O reactor");
151         requester.initiateShutdown();
152     }
153 
154 }