001: /*
002: * $HeadURL: https://svn.apache.org/repos/asf/httpcomponents/httpcore/tags/4.0-beta1/module-main/src/test/java/org/apache/http/protocol/TestHttpServiceAndExecutor.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.protocol;
032:
033: import java.io.IOException;
034: import java.net.Socket;
035: import java.util.ArrayList;
036: import java.util.List;
037: import java.util.Random;
038:
039: import org.apache.http.Header;
040: import org.apache.http.HttpEntity;
041: import org.apache.http.HttpEntityEnclosingRequest;
042: import org.apache.http.HttpException;
043: import org.apache.http.HttpHost;
044: import org.apache.http.HttpRequest;
045: import org.apache.http.HttpResponse;
046: import org.apache.http.HttpStatus;
047: import org.apache.http.HttpVersion;
048: import org.apache.http.entity.ByteArrayEntity;
049: import org.apache.http.entity.StringEntity;
050: import org.apache.http.impl.DefaultHttpClientConnection;
051: import org.apache.http.message.BasicHttpEntityEnclosingRequest;
052: import org.apache.http.message.BasicHttpRequest;
053: import org.apache.http.mockup.TestHttpClient;
054: import org.apache.http.mockup.TestHttpServer;
055: import org.apache.http.params.CoreProtocolPNames;
056: import org.apache.http.util.EncodingUtils;
057: import org.apache.http.util.EntityUtils;
058:
059: import junit.framework.*;
060: import org.apache.http.HttpConnectionMetrics;
061:
062: public class TestHttpServiceAndExecutor extends TestCase {
063:
064: // ------------------------------------------------------------ Constructor
065: public TestHttpServiceAndExecutor(String testName) {
066: super (testName);
067: }
068:
069: // ------------------------------------------------------------------- Main
070: public static void main(String args[]) {
071: String[] testCaseName = { TestHttpServiceAndExecutor.class
072: .getName() };
073: junit.textui.TestRunner.main(testCaseName);
074: }
075:
076: // ------------------------------------------------------- TestCase Methods
077:
078: public static Test suite() {
079: return new TestSuite(TestHttpServiceAndExecutor.class);
080: }
081:
082: private TestHttpServer server;
083: private TestHttpClient client;
084:
085: protected void setUp() throws Exception {
086: this .server = new TestHttpServer();
087: this .client = new TestHttpClient();
088: }
089:
090: protected void tearDown() throws Exception {
091: this .server.shutdown();
092: }
093:
094: /**
095: * This test case executes a series of simple GET requests
096: */
097: public void testSimpleBasicHttpRequests() throws Exception {
098:
099: int reqNo = 20;
100:
101: Random rnd = new Random();
102:
103: // Prepare some random data
104: final List testData = new ArrayList(reqNo);
105: for (int i = 0; i < reqNo; i++) {
106: int size = rnd.nextInt(5000);
107: byte[] data = new byte[size];
108: rnd.nextBytes(data);
109: testData.add(data);
110: }
111:
112: // Initialize the server-side request handler
113: this .server.registerHandler("*", 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: if (s.startsWith("/?")) {
122: s = s.substring(2);
123: }
124: int index = Integer.parseInt(s);
125: byte[] data = (byte[]) testData.get(index);
126: ByteArrayEntity entity = new ByteArrayEntity(data);
127: response.setEntity(entity);
128: }
129:
130: });
131:
132: this .server.start();
133:
134: DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
135: HttpHost host = new HttpHost("localhost", this .server.getPort());
136:
137: try {
138: for (int r = 0; r < reqNo; r++) {
139: if (!conn.isOpen()) {
140: Socket socket = new Socket(host.getHostName(), host
141: .getPort());
142: conn.bind(socket, this .client.getParams());
143: }
144:
145: BasicHttpRequest get = new BasicHttpRequest("GET", "/?"
146: + r);
147: HttpResponse response = this .client.execute(get, host,
148: conn);
149: byte[] received = EntityUtils.toByteArray(response
150: .getEntity());
151: byte[] expected = (byte[]) testData.get(r);
152:
153: assertEquals(expected.length, received.length);
154: for (int i = 0; i < expected.length; i++) {
155: assertEquals(expected[i], received[i]);
156: }
157: if (!this .client.keepAlive(response)) {
158: conn.close();
159: }
160: }
161:
162: //Verify the connection metrics
163: HttpConnectionMetrics cm = conn.getMetrics();
164: assertEquals(reqNo, cm.getRequestCount());
165: assertEquals(reqNo, cm.getResponseCount());
166:
167: } finally {
168: conn.close();
169: this .server.shutdown();
170: }
171: }
172:
173: /**
174: * This test case executes a series of simple POST requests with content length
175: * delimited content.
176: */
177: public void testSimpleHttpPostsWithContentLength() throws Exception {
178:
179: int reqNo = 20;
180:
181: Random rnd = new Random();
182:
183: // Prepare some random data
184: List testData = new ArrayList(reqNo);
185: for (int i = 0; i < reqNo; i++) {
186: int size = rnd.nextInt(5000);
187: byte[] data = new byte[size];
188: rnd.nextBytes(data);
189: testData.add(data);
190: }
191:
192: // Initialize the server-side request handler
193: this .server.registerHandler("*", new HttpRequestHandler() {
194:
195: public void handle(final HttpRequest request,
196: final HttpResponse response,
197: final HttpContext context) throws HttpException,
198: IOException {
199:
200: if (request instanceof HttpEntityEnclosingRequest) {
201: HttpEntity incoming = ((HttpEntityEnclosingRequest) request)
202: .getEntity();
203: byte[] data = EntityUtils.toByteArray(incoming);
204:
205: ByteArrayEntity outgoing = new ByteArrayEntity(data);
206: outgoing.setChunked(false);
207: response.setEntity(outgoing);
208: } else {
209: StringEntity outgoing = new StringEntity(
210: "No content");
211: response.setEntity(outgoing);
212: }
213: }
214:
215: });
216:
217: this .server.start();
218:
219: DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
220: HttpHost host = new HttpHost("localhost", this .server.getPort());
221:
222: try {
223: for (int r = 0; r < reqNo; r++) {
224: if (!conn.isOpen()) {
225: Socket socket = new Socket(host.getHostName(), host
226: .getPort());
227: conn.bind(socket, this .client.getParams());
228: }
229:
230: BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest(
231: "POST", "/");
232: byte[] data = (byte[]) testData.get(r);
233: ByteArrayEntity outgoing = new ByteArrayEntity(data);
234: post.setEntity(outgoing);
235:
236: HttpResponse response = this .client.execute(post, host,
237: conn);
238: byte[] received = EntityUtils.toByteArray(response
239: .getEntity());
240: byte[] expected = (byte[]) testData.get(r);
241:
242: assertEquals(expected.length, received.length);
243: for (int i = 0; i < expected.length; i++) {
244: assertEquals(expected[i], received[i]);
245: }
246: if (!this .client.keepAlive(response)) {
247: conn.close();
248: }
249: }
250: //Verify the connection metrics
251: HttpConnectionMetrics cm = conn.getMetrics();
252: assertEquals(reqNo, cm.getRequestCount());
253: assertEquals(reqNo, cm.getResponseCount());
254:
255: } finally {
256: conn.close();
257: this .server.shutdown();
258: }
259: }
260:
261: /**
262: * This test case executes a series of simple POST requests with chunk
263: * coded content content.
264: */
265: public void testSimpleHttpPostsChunked() throws Exception {
266:
267: int reqNo = 20;
268:
269: Random rnd = new Random();
270:
271: // Prepare some random data
272: List testData = new ArrayList(reqNo);
273: for (int i = 0; i < reqNo; i++) {
274: int size = rnd.nextInt(20000);
275: byte[] data = new byte[size];
276: rnd.nextBytes(data);
277: testData.add(data);
278: }
279:
280: // Initialize the server-side request handler
281: this .server.registerHandler("*", new HttpRequestHandler() {
282:
283: public void handle(final HttpRequest request,
284: final HttpResponse response,
285: final HttpContext context) throws HttpException,
286: IOException {
287:
288: if (request instanceof HttpEntityEnclosingRequest) {
289: HttpEntity incoming = ((HttpEntityEnclosingRequest) request)
290: .getEntity();
291: byte[] data = EntityUtils.toByteArray(incoming);
292:
293: ByteArrayEntity outgoing = new ByteArrayEntity(data);
294: outgoing.setChunked(true);
295: response.setEntity(outgoing);
296: } else {
297: StringEntity outgoing = new StringEntity(
298: "No content");
299: response.setEntity(outgoing);
300: }
301: }
302:
303: });
304:
305: this .server.start();
306:
307: DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
308: HttpHost host = new HttpHost("localhost", this .server.getPort());
309:
310: try {
311: for (int r = 0; r < reqNo; r++) {
312: if (!conn.isOpen()) {
313: Socket socket = new Socket(host.getHostName(), host
314: .getPort());
315: conn.bind(socket, this .client.getParams());
316: }
317:
318: BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest(
319: "POST", "/");
320: byte[] data = (byte[]) testData.get(r);
321: ByteArrayEntity outgoing = new ByteArrayEntity(data);
322: outgoing.setChunked(true);
323: post.setEntity(outgoing);
324:
325: HttpResponse response = this .client.execute(post, host,
326: conn);
327: byte[] received = EntityUtils.toByteArray(response
328: .getEntity());
329: byte[] expected = (byte[]) testData.get(r);
330:
331: assertEquals(expected.length, received.length);
332: for (int i = 0; i < expected.length; i++) {
333: assertEquals(expected[i], received[i]);
334: }
335: if (!this .client.keepAlive(response)) {
336: conn.close();
337: }
338: }
339: //Verify the connection metrics
340: HttpConnectionMetrics cm = conn.getMetrics();
341: assertEquals(reqNo, cm.getRequestCount());
342: assertEquals(reqNo, cm.getResponseCount());
343: } finally {
344: conn.close();
345: this .server.shutdown();
346: }
347: }
348:
349: /**
350: * This test case executes a series of simple HTTP/1.0 POST requests.
351: */
352: public void testSimpleHttpPostsHTTP10() throws Exception {
353:
354: int reqNo = 20;
355:
356: Random rnd = new Random();
357:
358: // Prepare some random data
359: List testData = new ArrayList(reqNo);
360: for (int i = 0; i < reqNo; i++) {
361: int size = rnd.nextInt(5000);
362: byte[] data = new byte[size];
363: rnd.nextBytes(data);
364: testData.add(data);
365: }
366:
367: // Initialize the server-side request handler
368: this .server.registerHandler("*", new HttpRequestHandler() {
369:
370: public void handle(final HttpRequest request,
371: final HttpResponse response,
372: final HttpContext context) throws HttpException,
373: IOException {
374:
375: if (request instanceof HttpEntityEnclosingRequest) {
376: HttpEntity incoming = ((HttpEntityEnclosingRequest) request)
377: .getEntity();
378: byte[] data = EntityUtils.toByteArray(incoming);
379:
380: ByteArrayEntity outgoing = new ByteArrayEntity(data);
381: outgoing.setChunked(false);
382: response.setEntity(outgoing);
383: } else {
384: StringEntity outgoing = new StringEntity(
385: "No content");
386: response.setEntity(outgoing);
387: }
388: }
389:
390: });
391:
392: this .server.start();
393:
394: // Set protocol level to HTTP/1.0
395: this .client.getParams().setParameter(
396: CoreProtocolPNames.PROTOCOL_VERSION,
397: HttpVersion.HTTP_1_0);
398:
399: DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
400: HttpHost host = new HttpHost("localhost", this .server.getPort());
401:
402: try {
403: for (int r = 0; r < reqNo; r++) {
404: if (!conn.isOpen()) {
405: Socket socket = new Socket(host.getHostName(), host
406: .getPort());
407: conn.bind(socket, this .client.getParams());
408: }
409:
410: BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest(
411: "POST", "/");
412: byte[] data = (byte[]) testData.get(r);
413: ByteArrayEntity outgoing = new ByteArrayEntity(data);
414: post.setEntity(outgoing);
415:
416: HttpResponse response = this .client.execute(post, host,
417: conn);
418: assertEquals(HttpVersion.HTTP_1_0, response
419: .getStatusLine().getProtocolVersion());
420: byte[] received = EntityUtils.toByteArray(response
421: .getEntity());
422: byte[] expected = (byte[]) testData.get(r);
423:
424: assertEquals(expected.length, received.length);
425: for (int i = 0; i < expected.length; i++) {
426: assertEquals(expected[i], received[i]);
427: }
428: if (!this .client.keepAlive(response)) {
429: conn.close();
430: }
431: }
432:
433: //Verify the connection metrics
434: HttpConnectionMetrics cm = conn.getMetrics();
435: assertEquals(reqNo, cm.getRequestCount());
436: assertEquals(reqNo, cm.getResponseCount());
437: } finally {
438: conn.close();
439: this .server.shutdown();
440: }
441: }
442:
443: /**
444: * This test case executes a series of simple POST requests using
445: * the 'expect: continue' handshake.
446: */
447: public void testHttpPostsWithExpectContinue() throws Exception {
448:
449: int reqNo = 20;
450:
451: Random rnd = new Random();
452:
453: // Prepare some random data
454: List testData = new ArrayList(reqNo);
455: for (int i = 0; i < reqNo; i++) {
456: int size = rnd.nextInt(5000);
457: byte[] data = new byte[size];
458: rnd.nextBytes(data);
459: testData.add(data);
460: }
461:
462: // Initialize the server-side request handler
463: this .server.registerHandler("*", new HttpRequestHandler() {
464:
465: public void handle(final HttpRequest request,
466: final HttpResponse response,
467: final HttpContext context) throws HttpException,
468: IOException {
469:
470: if (request instanceof HttpEntityEnclosingRequest) {
471: HttpEntity incoming = ((HttpEntityEnclosingRequest) request)
472: .getEntity();
473: byte[] data = EntityUtils.toByteArray(incoming);
474:
475: ByteArrayEntity outgoing = new ByteArrayEntity(data);
476: outgoing.setChunked(true);
477: response.setEntity(outgoing);
478: } else {
479: StringEntity outgoing = new StringEntity(
480: "No content");
481: response.setEntity(outgoing);
482: }
483: }
484:
485: });
486:
487: this .server.start();
488:
489: // Activate 'expect: continue' handshake
490: this .client.getParams().setBooleanParameter(
491: CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
492:
493: DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
494: HttpHost host = new HttpHost("localhost", this .server.getPort());
495:
496: try {
497: for (int r = 0; r < reqNo; r++) {
498: if (!conn.isOpen()) {
499: Socket socket = new Socket(host.getHostName(), host
500: .getPort());
501: conn.bind(socket, this .client.getParams());
502: }
503:
504: BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest(
505: "POST", "/");
506: byte[] data = (byte[]) testData.get(r);
507: ByteArrayEntity outgoing = new ByteArrayEntity(data);
508: outgoing.setChunked(true);
509: post.setEntity(outgoing);
510:
511: HttpResponse response = this .client.execute(post, host,
512: conn);
513: byte[] received = EntityUtils.toByteArray(response
514: .getEntity());
515: byte[] expected = (byte[]) testData.get(r);
516:
517: assertEquals(expected.length, received.length);
518: for (int i = 0; i < expected.length; i++) {
519: assertEquals(expected[i], received[i]);
520: }
521: if (!this .client.keepAlive(response)) {
522: conn.close();
523: }
524: }
525:
526: //Verify the connection metrics
527: HttpConnectionMetrics cm = conn.getMetrics();
528: assertEquals(reqNo, cm.getRequestCount());
529: assertEquals(reqNo, cm.getResponseCount());
530: } finally {
531: conn.close();
532: this .server.shutdown();
533: }
534: }
535:
536: /**
537: * This test case executes a series of simple POST requests that do not
538: * meet the target server expectations.
539: */
540: public void testHttpPostsWithExpectationVerification()
541: throws Exception {
542:
543: int reqNo = 3;
544:
545: // Initialize the server-side request handler
546: this .server.registerHandler("*", new HttpRequestHandler() {
547:
548: public void handle(final HttpRequest request,
549: final HttpResponse response,
550: final HttpContext context) throws HttpException,
551: IOException {
552:
553: StringEntity outgoing = new StringEntity("No content");
554: response.setEntity(outgoing);
555: }
556:
557: });
558:
559: this .server
560: .setExpectationVerifier(new HttpExpectationVerifier() {
561:
562: public void verify(final HttpRequest request,
563: final HttpResponse response,
564: final HttpContext context)
565: throws HttpException {
566: Header someheader = request
567: .getFirstHeader("Secret");
568: if (someheader != null) {
569: int secretNumber;
570: try {
571: secretNumber = Integer
572: .parseInt(someheader.getValue());
573: } catch (NumberFormatException ex) {
574: response
575: .setStatusCode(HttpStatus.SC_BAD_REQUEST);
576: return;
577: }
578: if (secretNumber < 2) {
579: response
580: .setStatusCode(HttpStatus.SC_EXPECTATION_FAILED);
581: ByteArrayEntity outgoing = new ByteArrayEntity(
582: EncodingUtils
583: .getAsciiBytes("Wrong secret number"));
584: response.setEntity(outgoing);
585: }
586: }
587: }
588:
589: });
590:
591: this .server.start();
592:
593: // Activate 'expect: continue' handshake
594: this .client.getParams().setBooleanParameter(
595: CoreProtocolPNames.USE_EXPECT_CONTINUE, true);
596:
597: DefaultHttpClientConnection conn = new DefaultHttpClientConnection();
598: HttpHost host = new HttpHost("localhost", this .server.getPort());
599:
600: try {
601: for (int r = 0; r < reqNo; r++) {
602: if (!conn.isOpen()) {
603: Socket socket = new Socket(host.getHostName(), host
604: .getPort());
605: conn.bind(socket, this .client.getParams());
606: }
607:
608: BasicHttpEntityEnclosingRequest post = new BasicHttpEntityEnclosingRequest(
609: "POST", "/");
610: post.addHeader("Secret", Integer.toString(r));
611: ByteArrayEntity outgoing = new ByteArrayEntity(
612: EncodingUtils.getAsciiBytes("No content"));
613: post.setEntity(outgoing);
614:
615: HttpResponse response = this .client.execute(post, host,
616: conn);
617:
618: HttpEntity entity = response.getEntity();
619: assertNotNull(entity);
620: entity.consumeContent();
621:
622: if (r < 2) {
623: assertEquals(HttpStatus.SC_EXPECTATION_FAILED,
624: response.getStatusLine().getStatusCode());
625: } else {
626: assertEquals(HttpStatus.SC_OK, response
627: .getStatusLine().getStatusCode());
628: }
629:
630: if (!this .client.keepAlive(response)) {
631: conn.close();
632: }
633: }
634: //Verify the connection metrics
635: HttpConnectionMetrics cm = conn.getMetrics();
636: assertEquals(reqNo, cm.getRequestCount());
637: assertEquals(reqNo, cm.getResponseCount());
638: } finally {
639: conn.close();
640: this.server.shutdown();
641: }
642: }
643:
644: }
|