001: /*
002: * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0-beta1/module-nio/src/examples/org/apache/http/examples/nio/NHttpSSLClient.java $
003: * $Revision: 610464 $
004: * $Date: 2008-01-09 18:10:55 +0100 (Wed, 09 Jan 2008) $
005: *
006: * ====================================================================
007: * Licensed to the Apache Software Foundation (ASF) under one
008: * or more contributor license agreements. See the NOTICE file
009: * distributed with this work for additional information
010: * regarding copyright ownership. The ASF licenses this file
011: * to you under the Apache License, Version 2.0 (the
012: * "License"); you may not use this file except in compliance
013: * with the License. You may obtain a copy of the License at
014: *
015: * http://www.apache.org/licenses/LICENSE-2.0
016: *
017: * Unless required by applicable law or agreed to in writing,
018: * software distributed under the License is distributed on an
019: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
020: * KIND, either express or implied. See the License for the
021: * specific language governing permissions and limitations
022: * under the License.
023: * ====================================================================
024: *
025: * This software consists of voluntary contributions made by many
026: * individuals on behalf of the Apache Software Foundation. For more
027: * information on the Apache Software Foundation, please see
028: * <http://www.apache.org/>.
029: *
030: */
031: package org.apache.http.examples.nio;
032:
033: import java.io.IOException;
034: import java.io.InterruptedIOException;
035: import java.net.InetSocketAddress;
036:
037: import javax.net.ssl.SSLContext;
038:
039: import org.apache.http.HttpEntity;
040: import org.apache.http.HttpException;
041: import org.apache.http.HttpHost;
042: import org.apache.http.HttpRequest;
043: import org.apache.http.HttpResponse;
044: import org.apache.http.impl.DefaultConnectionReuseStrategy;
045: import org.apache.http.impl.nio.SSLClientIOEventDispatch;
046: import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;
047: import org.apache.http.message.BasicHttpRequest;
048: import org.apache.http.nio.NHttpConnection;
049: import org.apache.http.nio.protocol.BufferingHttpClientHandler;
050: import org.apache.http.nio.protocol.EventListener;
051: import org.apache.http.nio.protocol.HttpRequestExecutionHandler;
052: import org.apache.http.nio.reactor.ConnectingIOReactor;
053: import org.apache.http.nio.reactor.IOEventDispatch;
054: import org.apache.http.nio.reactor.SessionRequest;
055: import org.apache.http.params.BasicHttpParams;
056: import org.apache.http.params.CoreConnectionPNames;
057: import org.apache.http.params.HttpParams;
058: import org.apache.http.params.CoreProtocolPNames;
059: import org.apache.http.protocol.BasicHttpProcessor;
060: import org.apache.http.protocol.ExecutionContext;
061: import org.apache.http.protocol.HttpContext;
062: import org.apache.http.protocol.RequestConnControl;
063: import org.apache.http.protocol.RequestContent;
064: import org.apache.http.protocol.RequestExpectContinue;
065: import org.apache.http.protocol.RequestTargetHost;
066: import org.apache.http.protocol.RequestUserAgent;
067: import org.apache.http.util.EntityUtils;
068:
069: public class NHttpSSLClient {
070:
071: public static void main(String[] args) throws Exception {
072: HttpParams params = new BasicHttpParams();
073: params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 30000)
074: .setIntParameter(
075: CoreConnectionPNames.CONNECTION_TIMEOUT, 30000)
076: .setIntParameter(
077: CoreConnectionPNames.SOCKET_BUFFER_SIZE,
078: 8 * 1024).setBooleanParameter(
079: CoreConnectionPNames.STALE_CONNECTION_CHECK,
080: false).setBooleanParameter(
081: CoreConnectionPNames.TCP_NODELAY, true)
082: .setParameter(CoreProtocolPNames.USER_AGENT,
083: "Jakarta-HttpComponents-NIO/1.1");
084:
085: final ConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(
086: 2, params);
087:
088: BasicHttpProcessor httpproc = new BasicHttpProcessor();
089: httpproc.addInterceptor(new RequestContent());
090: httpproc.addInterceptor(new RequestTargetHost());
091: httpproc.addInterceptor(new RequestConnControl());
092: httpproc.addInterceptor(new RequestUserAgent());
093: httpproc.addInterceptor(new RequestExpectContinue());
094:
095: // Initialize default SSL context
096: SSLContext sslcontext = SSLContext.getInstance("SSL");
097: sslcontext.init(null, null, null);
098:
099: // We are going to use this object to synchronize between the
100: // I/O event and main threads
101: RequestCount requestCount = new RequestCount(3);
102:
103: BufferingHttpClientHandler handler = new BufferingHttpClientHandler(
104: httpproc, new MyHttpRequestExecutionHandler(
105: requestCount),
106: new DefaultConnectionReuseStrategy(), params);
107:
108: handler.setEventListener(new EventLogger());
109:
110: final IOEventDispatch ioEventDispatch = new SSLClientIOEventDispatch(
111: handler, sslcontext, params);
112:
113: Thread t = new Thread(new Runnable() {
114:
115: public void run() {
116: try {
117: ioReactor.execute(ioEventDispatch);
118: } catch (InterruptedIOException ex) {
119: System.err.println("Interrupted");
120: } catch (IOException e) {
121: System.err.println("I/O error: " + e.getMessage());
122: }
123: System.out.println("Shutdown");
124: }
125:
126: });
127: t.start();
128:
129: SessionRequest[] reqs = new SessionRequest[requestCount
130: .getValue()];
131: reqs[0] = ioReactor.connect(new InetSocketAddress(
132: "www.netscape.com", 443), null, new HttpHost(
133: "www.netscape.com", 443), null);
134: reqs[1] = ioReactor.connect(new InetSocketAddress(
135: "www.verisign.com", 443), null, new HttpHost(
136: "www.verisign.com", 443), null);
137: reqs[2] = ioReactor.connect(new InetSocketAddress(
138: "www.yahoo.com", 443), null, new HttpHost(
139: "www.yahoo.com", 443), null);
140:
141: // Block until all connections signal
142: // completion of the request execution
143: synchronized (requestCount) {
144: while (requestCount.getValue() > 0) {
145: requestCount.wait();
146: }
147: }
148:
149: System.out.println("Shutting down I/O reactor");
150:
151: ioReactor.shutdown();
152:
153: System.out.println("Done");
154: }
155:
156: static class MyHttpRequestExecutionHandler implements
157: HttpRequestExecutionHandler {
158:
159: private final static String REQUEST_SENT = "request-sent";
160: private final static String RESPONSE_RECEIVED = "response-received";
161:
162: private final RequestCount requestCount;
163:
164: public MyHttpRequestExecutionHandler(
165: final RequestCount requestCount) {
166: super ();
167: this .requestCount = requestCount;
168: }
169:
170: public void initalizeContext(final HttpContext context,
171: final Object attachment) {
172: HttpHost targetHost = (HttpHost) attachment;
173: context.setAttribute(ExecutionContext.HTTP_TARGET_HOST,
174: targetHost);
175: }
176:
177: public void finalizeContext(final HttpContext context) {
178: Object flag = context.getAttribute(RESPONSE_RECEIVED);
179: if (flag == null) {
180: // Signal completion of the request execution
181: synchronized (this .requestCount) {
182: this .requestCount.decrement();
183: this .requestCount.notifyAll();
184: }
185: }
186: }
187:
188: public HttpRequest submitRequest(final HttpContext context) {
189: HttpHost targetHost = (HttpHost) context
190: .getAttribute(ExecutionContext.HTTP_TARGET_HOST);
191: Object token = context.getAttribute(REQUEST_SENT);
192: if (token == null) {
193: // Stick some object into the context
194: context.setAttribute(REQUEST_SENT, Boolean.TRUE);
195:
196: System.out.println("--------------");
197: System.out.println("Sending request to " + targetHost);
198: System.out.println("--------------");
199:
200: return new BasicHttpRequest("GET", "/");
201: } else {
202: // No new request to submit
203: return null;
204: }
205: }
206:
207: public void handleResponse(final HttpResponse response,
208: final HttpContext context) {
209: HttpEntity entity = response.getEntity();
210: try {
211: String content = EntityUtils.toString(entity);
212:
213: System.out.println("--------------");
214: System.out.println(response.getStatusLine());
215: System.out.println("--------------");
216: System.out.println("Document length: "
217: + content.length());
218: System.out.println("--------------");
219: } catch (IOException ex) {
220: System.err.println("I/O error: " + ex.getMessage());
221: }
222:
223: context.setAttribute(RESPONSE_RECEIVED, Boolean.TRUE);
224:
225: // Signal completion of the request execution
226: synchronized (this .requestCount) {
227: this .requestCount.decrement();
228: this .requestCount.notifyAll();
229: }
230: }
231:
232: }
233:
234: static class EventLogger implements EventListener {
235:
236: public void connectionOpen(final NHttpConnection conn) {
237: System.out.println("Connection open: " + conn);
238: }
239:
240: public void connectionTimeout(final NHttpConnection conn) {
241: System.out.println("Connection timed out: " + conn);
242: }
243:
244: public void connectionClosed(final NHttpConnection conn) {
245: System.out.println("Connection closed: " + conn);
246: }
247:
248: public void fatalIOException(final IOException ex,
249: final NHttpConnection conn) {
250: System.err.println("I/O error: " + ex.getMessage());
251: }
252:
253: public void fatalProtocolException(final HttpException ex,
254: final NHttpConnection conn) {
255: System.err.println("HTTP error: " + ex.getMessage());
256: }
257:
258: }
259:
260: static class RequestCount {
261:
262: private int value;
263:
264: public RequestCount(int initialValue) {
265: this .value = initialValue;
266: }
267:
268: public int getValue() {
269: return this .value;
270: }
271:
272: public void decrement() {
273: this.value--;
274: }
275:
276: }
277:
278: }
|