001: /*
002: * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0-beta1/module-nio/src/test/java/org/apache/http/nio/protocol/TestNIOSSLHttp.java $
003: * $Revision: 613298 $
004: * $Date: 2008-01-18 23:09:22 +0100 (Fri, 18 Jan 2008) $
005: * ====================================================================
006: * Licensed to the Apache Software Foundation (ASF) under one
007: * or more contributor license agreements. See the NOTICE file
008: * distributed with this work for additional information
009: * regarding copyright ownership. The ASF licenses this file
010: * to you under the Apache License, Version 2.0 (the
011: * "License"); you may not use this file except in compliance
012: * with the License. You may obtain a copy of the License at
013: *
014: * http://www.apache.org/licenses/LICENSE-2.0
015: *
016: * Unless required by applicable law or agreed to in writing,
017: * software distributed under the License is distributed on an
018: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
019: * KIND, either express or implied. See the License for the
020: * specific language governing permissions and limitations
021: * under the License.
022: * ====================================================================
023: *
024: * This software consists of voluntary contributions made by many
025: * individuals on behalf of the Apache Software Foundation. For more
026: * information on the Apache Software Foundation, please see
027: * <http://www.apache.org/>.
028: *
029: */
030:
031: package org.apache.http.nio.protocol;
032:
033: import java.io.IOException;
034: import java.net.InetSocketAddress;
035: import java.net.URI;
036: import java.net.URISyntaxException;
037: import java.util.ArrayList;
038: import java.util.List;
039:
040: import junit.framework.Test;
041: import junit.framework.TestSuite;
042:
043: import org.apache.http.HttpCoreNIOSSLTestBase;
044: import org.apache.http.HttpEntity;
045: import org.apache.http.HttpEntityEnclosingRequest;
046: import org.apache.http.HttpException;
047: import org.apache.http.HttpRequest;
048: import org.apache.http.HttpResponse;
049: import org.apache.http.HttpVersion;
050: import org.apache.http.entity.ByteArrayEntity;
051: import org.apache.http.entity.StringEntity;
052: import org.apache.http.message.BasicHttpEntityEnclosingRequest;
053: import org.apache.http.message.BasicHttpRequest;
054: import org.apache.http.mockup.ByteSequence;
055: import org.apache.http.mockup.RequestCount;
056: import org.apache.http.mockup.SimpleEventListener;
057: import org.apache.http.nio.NHttpClientHandler;
058: import org.apache.http.nio.NHttpConnection;
059: import org.apache.http.nio.NHttpServiceHandler;
060: import org.apache.http.nio.protocol.HttpRequestExecutionHandler;
061: import org.apache.http.nio.reactor.ListenerEndpoint;
062: import org.apache.http.params.CoreProtocolPNames;
063: import org.apache.http.protocol.ExecutionContext;
064: import org.apache.http.protocol.HttpContext;
065: import org.apache.http.protocol.HttpRequestHandler;
066: import org.apache.http.util.EntityUtils;
067:
068: /**
069: * HttpCore NIO SSL tests.
070: *
071: * @author <a href="mailto:oleg at ural.ru">Oleg Kalnichevski</a>
072: *
073: * @version $Id: TestNIOSSLHttp.java 613298 2008-01-18 22:09:22Z sebb $
074: */
075: public class TestNIOSSLHttp extends HttpCoreNIOSSLTestBase {
076:
077: // ------------------------------------------------------------ Constructor
078: public TestNIOSSLHttp(String testName) {
079: super (testName);
080: }
081:
082: // ------------------------------------------------------------------- Main
083: public static void main(String args[]) {
084: String[] testCaseName = { TestNIOSSLHttp.class.getName() };
085: junit.textui.TestRunner.main(testCaseName);
086: }
087:
088: // ------------------------------------------------------- TestCase Methods
089:
090: public static Test suite() {
091: return new TestSuite(TestNIOSSLHttp.class);
092: }
093:
094: /**
095: * This test case executes a series of simple (non-pipelined) GET requests
096: * over multiple connections.
097: */
098: public void testSimpleHttpGets() throws Exception {
099: final int connNo = 3;
100: final int reqNo = 20;
101: final RequestCount requestCount = new RequestCount(connNo
102: * reqNo);
103:
104: final ByteSequence requestData = new ByteSequence();
105: requestData.rnd(reqNo);
106:
107: List<ByteSequence> responseData = new ArrayList<ByteSequence>(
108: connNo);
109: for (int i = 0; i < connNo; i++) {
110: responseData.add(new ByteSequence());
111: }
112:
113: HttpRequestHandler requestHandler = new HttpRequestHandler() {
114:
115: public void handle(final HttpRequest request,
116: final HttpResponse response,
117: final HttpContext context) throws HttpException,
118: IOException {
119:
120: String s = request.getRequestLine().getUri();
121: URI uri;
122: try {
123: uri = new URI(s);
124: } catch (URISyntaxException ex) {
125: throw new HttpException("Invalid request URI: " + s);
126: }
127: int index = Integer.parseInt(uri.getQuery());
128: byte[] bytes = requestData.getBytes(index);
129: ByteArrayEntity entity = new ByteArrayEntity(bytes);
130: response.setEntity(entity);
131: }
132:
133: };
134:
135: HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
136:
137: public void initalizeContext(final HttpContext context,
138: final Object attachment) {
139: context.setAttribute("LIST", (ByteSequence) attachment);
140: context.setAttribute("REQ-COUNT", new Integer(0));
141: context.setAttribute("RES-COUNT", new Integer(0));
142: }
143:
144: public void finalizeContext(final HttpContext context) {
145: }
146:
147: public HttpRequest submitRequest(final HttpContext context) {
148: int i = ((Integer) context.getAttribute("REQ-COUNT"))
149: .intValue();
150: BasicHttpRequest get = null;
151: if (i < reqNo) {
152: get = new BasicHttpRequest("GET", "/?" + i);
153: context.setAttribute("REQ-COUNT",
154: new Integer(i + 1));
155: }
156: return get;
157: }
158:
159: public void handleResponse(final HttpResponse response,
160: final HttpContext context) {
161: NHttpConnection conn = (NHttpConnection) context
162: .getAttribute(ExecutionContext.HTTP_CONNECTION);
163:
164: ByteSequence list = (ByteSequence) context
165: .getAttribute("LIST");
166: int i = ((Integer) context.getAttribute("RES-COUNT"))
167: .intValue();
168: i++;
169: context.setAttribute("RES-COUNT", new Integer(i));
170:
171: try {
172: HttpEntity entity = response.getEntity();
173: byte[] data = EntityUtils.toByteArray(entity);
174: list.addBytes(data);
175: requestCount.decrement();
176: } catch (IOException ex) {
177: requestCount.abort();
178: }
179:
180: if (i < reqNo) {
181: conn.requestInput();
182: }
183: }
184:
185: };
186:
187: NHttpServiceHandler serviceHandler = createHttpServiceHandler(
188: requestHandler, null, new SimpleEventListener());
189:
190: NHttpClientHandler clientHandler = createHttpClientHandler(
191: requestExecutionHandler, new SimpleEventListener());
192:
193: this .server.start(serviceHandler);
194: this .client.start(clientHandler);
195:
196: ListenerEndpoint endpoint = this .server.getListenerEndpoint();
197: endpoint.waitFor();
198: InetSocketAddress serverAddress = (InetSocketAddress) endpoint
199: .getAddress();
200:
201: for (int i = 0; i < responseData.size(); i++) {
202: this .client.openConnection(new InetSocketAddress(
203: "localhost", serverAddress.getPort()), responseData
204: .get(i));
205: }
206:
207: requestCount.await(10000);
208: assertEquals(0, requestCount.getValue());
209:
210: this .client.shutdown();
211: this .server.shutdown();
212:
213: for (int c = 0; c < responseData.size(); c++) {
214: ByteSequence receivedPackets = responseData.get(c);
215: ByteSequence expectedPackets = requestData;
216: assertEquals(expectedPackets.size(), receivedPackets.size());
217: for (int p = 0; p < requestData.size(); p++) {
218: byte[] expected = requestData.getBytes(p);
219: byte[] received = receivedPackets.getBytes(p);
220:
221: assertEquals(expected.length, received.length);
222: for (int i = 0; i < expected.length; i++) {
223: assertEquals(expected[i], received[i]);
224: }
225: }
226: }
227:
228: }
229:
230: /**
231: * This test case executes a series of simple (non-pipelined) POST requests
232: * with content length delimited content over multiple connections.
233: */
234: public void testSimpleBasicHttpEntityEnclosingRequestsWithContentLength()
235: throws Exception {
236:
237: final int connNo = 3;
238: final int reqNo = 20;
239: final RequestCount requestCount = new RequestCount(connNo
240: * reqNo);
241:
242: final ByteSequence requestData = new ByteSequence();
243: requestData.rnd(reqNo);
244:
245: List<ByteSequence> responseData = new ArrayList<ByteSequence>(
246: connNo);
247: for (int i = 0; i < connNo; i++) {
248: responseData.add(new ByteSequence());
249: }
250:
251: HttpRequestHandler requestHandler = new HttpRequestHandler() {
252:
253: public void handle(final HttpRequest request,
254: final HttpResponse response,
255: final HttpContext context) throws HttpException,
256: IOException {
257:
258: if (request instanceof HttpEntityEnclosingRequest) {
259: HttpEntity incoming = ((HttpEntityEnclosingRequest) request)
260: .getEntity();
261: byte[] data = EntityUtils.toByteArray(incoming);
262:
263: ByteArrayEntity outgoing = new ByteArrayEntity(data);
264: outgoing.setChunked(false);
265: response.setEntity(outgoing);
266: } else {
267: StringEntity outgoing = new StringEntity(
268: "No content");
269: response.setEntity(outgoing);
270: }
271: }
272:
273: };
274:
275: HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
276:
277: public void initalizeContext(final HttpContext context,
278: final Object attachment) {
279: context.setAttribute("LIST", (ByteSequence) attachment);
280: context.setAttribute("REQ-COUNT", new Integer(0));
281: context.setAttribute("RES-COUNT", new Integer(0));
282: }
283:
284: public void finalizeContext(final HttpContext context) {
285: }
286:
287: public HttpRequest submitRequest(final HttpContext context) {
288: int i = ((Integer) context.getAttribute("REQ-COUNT"))
289: .intValue();
290: BasicHttpEntityEnclosingRequest post = null;
291: if (i < reqNo) {
292: post = new BasicHttpEntityEnclosingRequest("POST",
293: "/?" + i);
294: byte[] bytes = requestData.getBytes(i);
295: ByteArrayEntity outgoing = new ByteArrayEntity(
296: bytes);
297: post.setEntity(outgoing);
298:
299: context.setAttribute("REQ-COUNT",
300: new Integer(i + 1));
301: }
302: return post;
303: }
304:
305: public void handleResponse(final HttpResponse response,
306: final HttpContext context) {
307: NHttpConnection conn = (NHttpConnection) context
308: .getAttribute(ExecutionContext.HTTP_CONNECTION);
309:
310: ByteSequence list = (ByteSequence) context
311: .getAttribute("LIST");
312: int i = ((Integer) context.getAttribute("RES-COUNT"))
313: .intValue();
314: i++;
315: context.setAttribute("RES-COUNT", new Integer(i));
316:
317: try {
318: HttpEntity entity = response.getEntity();
319: byte[] data = EntityUtils.toByteArray(entity);
320: list.addBytes(data);
321: requestCount.decrement();
322: } catch (IOException ex) {
323: requestCount.abort();
324: }
325:
326: if (i < reqNo) {
327: conn.requestInput();
328: }
329: }
330:
331: };
332:
333: NHttpServiceHandler serviceHandler = createHttpServiceHandler(
334: requestHandler, null, new SimpleEventListener());
335:
336: NHttpClientHandler clientHandler = createHttpClientHandler(
337: requestExecutionHandler, new SimpleEventListener());
338:
339: this .server.start(serviceHandler);
340: this .client.start(clientHandler);
341:
342: ListenerEndpoint endpoint = this .server.getListenerEndpoint();
343: endpoint.waitFor();
344: InetSocketAddress serverAddress = (InetSocketAddress) endpoint
345: .getAddress();
346:
347: for (int i = 0; i < responseData.size(); i++) {
348: this .client.openConnection(new InetSocketAddress(
349: "localhost", serverAddress.getPort()), responseData
350: .get(i));
351: }
352:
353: requestCount.await(10000);
354: assertEquals(0, requestCount.getValue());
355:
356: this .client.shutdown();
357: this .server.shutdown();
358:
359: for (int c = 0; c < responseData.size(); c++) {
360: ByteSequence receivedPackets = responseData.get(c);
361: ByteSequence expectedPackets = requestData;
362: assertEquals(expectedPackets.size(), receivedPackets.size());
363: for (int p = 0; p < requestData.size(); p++) {
364: byte[] expected = requestData.getBytes(p);
365: byte[] received = receivedPackets.getBytes(p);
366:
367: assertEquals(expected.length, received.length);
368: for (int i = 0; i < expected.length; i++) {
369: assertEquals(expected[i], received[i]);
370: }
371: }
372: }
373:
374: }
375:
376: /**
377: * This test case executes a series of simple (non-pipelined) POST requests
378: * with chunk coded content content over multiple connections.
379: */
380: public void testSimpleBasicHttpEntityEnclosingRequestsChunked()
381: throws Exception {
382:
383: final int connNo = 3;
384: final int reqNo = 20;
385: final RequestCount requestCount = new RequestCount(connNo
386: * reqNo);
387:
388: final ByteSequence requestData = new ByteSequence();
389: requestData.rnd(reqNo);
390:
391: List<ByteSequence> responseData = new ArrayList<ByteSequence>(
392: connNo);
393: for (int i = 0; i < connNo; i++) {
394: responseData.add(new ByteSequence());
395: }
396:
397: HttpRequestHandler requestHandler = new HttpRequestHandler() {
398:
399: public void handle(final HttpRequest request,
400: final HttpResponse response,
401: final HttpContext context) throws HttpException,
402: IOException {
403:
404: if (request instanceof HttpEntityEnclosingRequest) {
405: HttpEntity incoming = ((HttpEntityEnclosingRequest) request)
406: .getEntity();
407: byte[] data = EntityUtils.toByteArray(incoming);
408: ByteArrayEntity outgoing = new ByteArrayEntity(data);
409: outgoing.setChunked(true);
410: response.setEntity(outgoing);
411: } else {
412: StringEntity outgoing = new StringEntity(
413: "No content");
414: response.setEntity(outgoing);
415: }
416: }
417:
418: };
419:
420: HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
421:
422: public void initalizeContext(final HttpContext context,
423: final Object attachment) {
424: context.setAttribute("LIST", (ByteSequence) attachment);
425: context.setAttribute("REQ-COUNT", new Integer(0));
426: context.setAttribute("RES-COUNT", new Integer(0));
427: }
428:
429: public void finalizeContext(final HttpContext context) {
430: }
431:
432: public HttpRequest submitRequest(final HttpContext context) {
433: int i = ((Integer) context.getAttribute("REQ-COUNT"))
434: .intValue();
435: BasicHttpEntityEnclosingRequest post = null;
436: if (i < reqNo) {
437: post = new BasicHttpEntityEnclosingRequest("POST",
438: "/?" + i);
439: byte[] bytes = requestData.getBytes(i);
440: ByteArrayEntity outgoing = new ByteArrayEntity(
441: bytes);
442: outgoing.setChunked(true);
443: post.setEntity(outgoing);
444:
445: context.setAttribute("REQ-COUNT",
446: new Integer(i + 1));
447: }
448: return post;
449: }
450:
451: public void handleResponse(final HttpResponse response,
452: final HttpContext context) {
453: NHttpConnection conn = (NHttpConnection) context
454: .getAttribute(ExecutionContext.HTTP_CONNECTION);
455:
456: ByteSequence list = (ByteSequence) context
457: .getAttribute("LIST");
458: int i = ((Integer) context.getAttribute("RES-COUNT"))
459: .intValue();
460: i++;
461: context.setAttribute("RES-COUNT", new Integer(i));
462:
463: try {
464: HttpEntity entity = response.getEntity();
465: byte[] data = EntityUtils.toByteArray(entity);
466: list.addBytes(data);
467: requestCount.decrement();
468: } catch (IOException ex) {
469: requestCount.abort();
470: }
471:
472: if (i < reqNo) {
473: conn.requestInput();
474: }
475: }
476:
477: };
478:
479: SimpleEventListener serverEventListener = new SimpleEventListener();
480: SimpleEventListener clientEventListener = new SimpleEventListener();
481:
482: NHttpServiceHandler serviceHandler = createHttpServiceHandler(
483: requestHandler, null, serverEventListener);
484:
485: NHttpClientHandler clientHandler = createHttpClientHandler(
486: requestExecutionHandler, clientEventListener);
487:
488: this .server.start(serviceHandler);
489: this .client.start(clientHandler);
490:
491: ListenerEndpoint endpoint = this .server.getListenerEndpoint();
492: endpoint.waitFor();
493: InetSocketAddress serverAddress = (InetSocketAddress) endpoint
494: .getAddress();
495:
496: for (int i = 0; i < responseData.size(); i++) {
497: this .client.openConnection(new InetSocketAddress(
498: "localhost", serverAddress.getPort()), responseData
499: .get(i));
500: }
501:
502: requestCount.await(10000);
503: assertEquals(0, requestCount.getValue());
504:
505: this .client.shutdown();
506: this .server.shutdown();
507:
508: for (int c = 0; c < responseData.size(); c++) {
509: ByteSequence receivedPackets = responseData.get(c);
510: ByteSequence expectedPackets = requestData;
511: assertEquals(expectedPackets.size(), receivedPackets.size());
512: for (int p = 0; p < requestData.size(); p++) {
513: byte[] expected = requestData.getBytes(p);
514: byte[] received = receivedPackets.getBytes(p);
515:
516: assertEquals(expected.length, received.length);
517: for (int i = 0; i < expected.length; i++) {
518: assertEquals(expected[i], received[i]);
519: }
520: }
521: }
522:
523: }
524:
525: /**
526: * This test case executes a series of simple (non-pipelined) HTTP/1.0
527: * POST requests over multiple persistent connections.
528: */
529: public void testSimpleBasicHttpEntityEnclosingRequestsHTTP10()
530: throws Exception {
531:
532: final int connNo = 3;
533: final int reqNo = 20;
534: final RequestCount requestCount = new RequestCount(connNo
535: * reqNo);
536:
537: final ByteSequence requestData = new ByteSequence();
538: requestData.rnd(reqNo);
539:
540: List<ByteSequence> responseData = new ArrayList<ByteSequence>(
541: connNo);
542: for (int i = 0; i < connNo; i++) {
543: responseData.add(new ByteSequence());
544: }
545:
546: HttpRequestHandler requestHandler = new HttpRequestHandler() {
547:
548: public void handle(final HttpRequest request,
549: final HttpResponse response,
550: final HttpContext context) throws HttpException,
551: IOException {
552:
553: if (request instanceof HttpEntityEnclosingRequest) {
554: HttpEntity incoming = ((HttpEntityEnclosingRequest) request)
555: .getEntity();
556: byte[] data = EntityUtils.toByteArray(incoming);
557:
558: ByteArrayEntity outgoing = new ByteArrayEntity(data);
559: outgoing.setChunked(false);
560: response.setEntity(outgoing);
561: } else {
562: StringEntity outgoing = new StringEntity(
563: "No content");
564: response.setEntity(outgoing);
565: }
566: }
567:
568: };
569:
570: // Set protocol level to HTTP/1.0
571: this .client.getParams().setParameter(
572: CoreProtocolPNames.PROTOCOL_VERSION,
573: HttpVersion.HTTP_1_0);
574:
575: HttpRequestExecutionHandler requestExecutionHandler = new HttpRequestExecutionHandler() {
576:
577: public void initalizeContext(final HttpContext context,
578: final Object attachment) {
579: context.setAttribute("LIST", (ByteSequence) attachment);
580: context.setAttribute("REQ-COUNT", new Integer(0));
581: context.setAttribute("RES-COUNT", new Integer(0));
582: }
583:
584: public void finalizeContext(final HttpContext context) {
585: }
586:
587: public HttpRequest submitRequest(final HttpContext context) {
588: int i = ((Integer) context.getAttribute("REQ-COUNT"))
589: .intValue();
590: BasicHttpEntityEnclosingRequest post = null;
591: if (i < reqNo) {
592: post = new BasicHttpEntityEnclosingRequest("POST",
593: "/?" + i);
594: byte[] bytes = requestData.getBytes(i);
595: ByteArrayEntity outgoing = new ByteArrayEntity(
596: bytes);
597: post.setEntity(outgoing);
598:
599: context.setAttribute("REQ-COUNT",
600: new Integer(i + 1));
601: }
602: return post;
603: }
604:
605: public void handleResponse(final HttpResponse response,
606: final HttpContext context) {
607: NHttpConnection conn = (NHttpConnection) context
608: .getAttribute(ExecutionContext.HTTP_CONNECTION);
609:
610: ByteSequence list = (ByteSequence) context
611: .getAttribute("LIST");
612: int i = ((Integer) context.getAttribute("RES-COUNT"))
613: .intValue();
614: i++;
615: context.setAttribute("RES-COUNT", new Integer(i));
616:
617: try {
618: HttpEntity entity = response.getEntity();
619: byte[] data = EntityUtils.toByteArray(entity);
620: list.addBytes(data);
621: requestCount.decrement();
622: } catch (IOException ex) {
623: requestCount.abort();
624: }
625:
626: if (i < reqNo) {
627: conn.requestInput();
628: }
629: }
630:
631: };
632:
633: SimpleEventListener serverEventListener = new SimpleEventListener();
634: SimpleEventListener clientEventListener = new SimpleEventListener();
635:
636: NHttpServiceHandler serviceHandler = createHttpServiceHandler(
637: requestHandler, null, serverEventListener);
638:
639: NHttpClientHandler clientHandler = createHttpClientHandler(
640: requestExecutionHandler, clientEventListener);
641:
642: this .server.start(serviceHandler);
643: this .client.start(clientHandler);
644:
645: ListenerEndpoint endpoint = this .server.getListenerEndpoint();
646: endpoint.waitFor();
647: InetSocketAddress serverAddress = (InetSocketAddress) endpoint
648: .getAddress();
649:
650: for (int i = 0; i < responseData.size(); i++) {
651: this .client.openConnection(new InetSocketAddress(
652: "localhost", serverAddress.getPort()), responseData
653: .get(i));
654: }
655:
656: requestCount.await(10000);
657: assertEquals(0, requestCount.getValue());
658:
659: this .client.shutdown();
660: this .server.shutdown();
661:
662: for (int c = 0; c < responseData.size(); c++) {
663: ByteSequence receivedPackets = responseData.get(c);
664: ByteSequence expectedPackets = requestData;
665: assertEquals(expectedPackets.size(), receivedPackets.size());
666: for (int p = 0; p < requestData.size(); p++) {
667: byte[] expected = requestData.getBytes(p);
668: byte[] received = receivedPackets.getBytes(p);
669:
670: assertEquals(expected.length, received.length);
671: for (int i = 0; i < expected.length; i++) {
672: assertEquals(expected[i], received[i]);
673: }
674: }
675: }
676:
677: }
678:
679: }
|