1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.core5.testing.classic;
29
30 import java.io.BufferedReader;
31 import java.io.IOException;
32 import java.io.InputStream;
33 import java.io.InputStreamReader;
34 import java.io.OutputStream;
35 import java.nio.charset.Charset;
36 import java.nio.charset.StandardCharsets;
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.Collection;
40 import java.util.List;
41 import java.util.Random;
42 import java.util.concurrent.TimeUnit;
43
44 import org.apache.hc.core5.function.Decorator;
45 import org.apache.hc.core5.http.ClassicHttpRequest;
46 import org.apache.hc.core5.http.ClassicHttpResponse;
47 import org.apache.hc.core5.http.ContentType;
48 import org.apache.hc.core5.http.EntityDetails;
49 import org.apache.hc.core5.http.Header;
50 import org.apache.hc.core5.http.HttpEntity;
51 import org.apache.hc.core5.http.HttpException;
52 import org.apache.hc.core5.http.HttpHeaders;
53 import org.apache.hc.core5.http.HttpHost;
54 import org.apache.hc.core5.http.HttpRequest;
55 import org.apache.hc.core5.http.HttpRequestInterceptor;
56 import org.apache.hc.core5.http.HttpStatus;
57 import org.apache.hc.core5.http.HttpVersion;
58 import org.apache.hc.core5.http.Method;
59 import org.apache.hc.core5.http.URIScheme;
60 import org.apache.hc.core5.http.config.Http1Config;
61 import org.apache.hc.core5.http.io.HttpRequestHandler;
62 import org.apache.hc.core5.http.io.HttpServerRequestHandler;
63 import org.apache.hc.core5.http.io.SocketConfig;
64 import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
65 import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
66 import org.apache.hc.core5.http.io.entity.EntityUtils;
67 import org.apache.hc.core5.http.io.entity.StringEntity;
68 import org.apache.hc.core5.http.io.support.BasicHttpServerExpectationDecorator;
69 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
70 import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
71 import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
72 import org.apache.hc.core5.http.protocol.HttpContext;
73 import org.apache.hc.core5.http.protocol.HttpCoreContext;
74 import org.apache.hc.core5.http.protocol.RequestConnControl;
75 import org.apache.hc.core5.http.protocol.RequestContent;
76 import org.apache.hc.core5.http.protocol.RequestExpectContinue;
77 import org.apache.hc.core5.http.protocol.RequestTargetHost;
78 import org.apache.hc.core5.http.protocol.RequestUserAgent;
79 import org.apache.hc.core5.io.CloseMode;
80 import org.apache.hc.core5.testing.SSLTestContexts;
81 import org.junit.Assert;
82 import org.junit.Rule;
83 import org.junit.Test;
84 import org.junit.rules.ExternalResource;
85 import org.junit.runner.RunWith;
86 import org.junit.runners.Parameterized;
87
88 @RunWith(Parameterized.class)
89 public class ClassicIntegrationTest {
90
91 @Parameterized.Parameters(name = "{0}")
92 public static Collection<Object[]> protocols() {
93 return Arrays.asList(new Object[][]{
94 { URIScheme.HTTP },
95 { URIScheme.HTTPS }
96 });
97 }
98
99 private final URIScheme scheme;
100 private ClassicTestServer server;
101
102 public ClassicIntegrationTest(final URIScheme scheme) {
103 this.scheme = scheme;
104 }
105
106 @Rule
107 public ExternalResource serverResource = new ExternalResource() {
108
109 @Override
110 protected void before() throws Throwable {
111 server = new ClassicTestServer(
112 scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null,
113 SocketConfig.custom()
114 .setSoTimeout(5, TimeUnit.SECONDS)
115 .build());
116 }
117
118 @Override
119 protected void after() {
120 if (server != null) {
121 try {
122 server.shutdown(CloseMode.IMMEDIATE);
123 server = null;
124 } catch (final Exception ignore) {
125 }
126 }
127 }
128
129 };
130
131 private ClassicTestClient client;
132
133 @Rule
134 public ExternalResource clientResource = new ExternalResource() {
135
136 @Override
137 protected void before() throws Throwable {
138 client = new ClassicTestClient(
139 scheme == URIScheme.HTTPS ? SSLTestContexts.createClientSSLContext() : null,
140 SocketConfig.custom()
141 .setSoTimeout(5, TimeUnit.SECONDS)
142 .build());
143 }
144
145 @Override
146 protected void after() {
147 if (client != null) {
148 try {
149 client.shutdown(CloseMode.IMMEDIATE);
150 client = null;
151 } catch (final Exception ignore) {
152 }
153 }
154 }
155
156 };
157
158
159
160
161 @Test
162 public void testSimpleBasicHttpRequests() throws Exception {
163
164 final int reqNo = 20;
165
166 final Random rnd = new Random();
167
168
169 final List<byte[]> testData = new ArrayList<>(reqNo);
170 for (int i = 0; i < reqNo; i++) {
171 final int size = rnd.nextInt(5000);
172 final byte[] data = new byte[size];
173 rnd.nextBytes(data);
174 testData.add(data);
175 }
176
177
178 this.server.registerHandler("*", new HttpRequestHandler() {
179
180 @Override
181 public void handle(
182 final ClassicHttpRequest request,
183 final ClassicHttpResponse response,
184 final HttpContext context) throws HttpException, IOException {
185
186 String s = request.getPath();
187 if (s.startsWith("/?")) {
188 s = s.substring(2);
189 }
190 final int index = Integer.parseInt(s);
191 final byte[] data = testData.get(index);
192 final ByteArrayEntity entity = new ByteArrayEntity(data, null);
193 response.setEntity(entity);
194 }
195
196 });
197
198 this.server.start();
199 this.client.start();
200
201 final HttpCoreContext context = HttpCoreContext.create();
202 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
203
204 for (int r = 0; r < reqNo; r++) {
205 final BasicClassicHttpRequest get = new BasicClassicHttpRequest(Method.GET, "/?" + r);
206 try (final ClassicHttpResponse response = this.client.execute(host, get, context)) {
207 final byte[] received = EntityUtils.toByteArray(response.getEntity());
208 final byte[] expected = testData.get(r);
209
210 Assert.assertEquals(expected.length, received.length);
211 for (int i = 0; i < expected.length; i++) {
212 Assert.assertEquals(expected[i], received[i]);
213 }
214 }
215 }
216 }
217
218
219
220
221
222 @Test
223 public void testSimpleHttpPostsWithContentLength() throws Exception {
224
225 final int reqNo = 20;
226
227 final Random rnd = new Random();
228
229
230 final List<byte[]> testData = new ArrayList<>(reqNo);
231 for (int i = 0; i < reqNo; i++) {
232 final int size = rnd.nextInt(5000);
233 final byte[] data = new byte[size];
234 rnd.nextBytes(data);
235 testData.add(data);
236 }
237
238
239 this.server.registerHandler("*", new HttpRequestHandler() {
240
241 @Override
242 public void handle(
243 final ClassicHttpRequest request,
244 final ClassicHttpResponse response,
245 final HttpContext context) throws HttpException, IOException {
246
247 final HttpEntity entity = request.getEntity();
248 if (entity != null) {
249 final byte[] data = EntityUtils.toByteArray(entity);
250 response.setEntity(new ByteArrayEntity(data, null));
251 }
252 }
253
254 });
255
256 this.server.start();
257 this.client.start();
258
259 final HttpCoreContext context = HttpCoreContext.create();
260 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
261
262 for (int r = 0; r < reqNo; r++) {
263 final BasicClassicHttpRequest post = new BasicClassicHttpRequest(Method.POST, "/");
264 final byte[] data = testData.get(r);
265 post.setEntity(new ByteArrayEntity(data, null));
266
267 try (final ClassicHttpResponse response = this.client.execute(host, post, context)) {
268 final byte[] received = EntityUtils.toByteArray(response.getEntity());
269 final byte[] expected = testData.get(r);
270
271 Assert.assertEquals(expected.length, received.length);
272 for (int i = 0; i < expected.length; i++) {
273 Assert.assertEquals(expected[i], received[i]);
274 }
275 }
276 }
277 }
278
279
280
281
282
283 @Test
284 public void testSimpleHttpPostsChunked() throws Exception {
285
286 final int reqNo = 20;
287
288 final Random rnd = new Random();
289
290
291 final List<byte[]> testData = new ArrayList<>(reqNo);
292 for (int i = 0; i < reqNo; i++) {
293 final int size = rnd.nextInt(20000);
294 final byte[] data = new byte[size];
295 rnd.nextBytes(data);
296 testData.add(data);
297 }
298
299
300 this.server.registerHandler("*", new HttpRequestHandler() {
301
302 @Override
303 public void handle(
304 final ClassicHttpRequest request,
305 final ClassicHttpResponse response,
306 final HttpContext context) throws HttpException, IOException {
307
308 final HttpEntity entity = request.getEntity();
309 if (entity != null) {
310 final byte[] data = EntityUtils.toByteArray(entity);
311 response.setEntity(new ByteArrayEntity(data, null, true));
312 }
313 }
314
315 });
316
317 this.server.start();
318 this.client.start();
319
320 final HttpCoreContext context = HttpCoreContext.create();
321 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
322
323 for (int r = 0; r < reqNo; r++) {
324 final BasicClassicHttpRequest post = new BasicClassicHttpRequest(Method.POST, "/");
325 final byte[] data = testData.get(r);
326 post.setEntity(new ByteArrayEntity(data, null, true));
327
328 try (final ClassicHttpResponse response = this.client.execute(host, post, context)) {
329 final byte[] received = EntityUtils.toByteArray(response.getEntity());
330 final byte[] expected = testData.get(r);
331
332 Assert.assertEquals(expected.length, received.length);
333 for (int i = 0; i < expected.length; i++) {
334 Assert.assertEquals(expected[i], received[i]);
335 }
336 }
337 }
338 }
339
340
341
342
343 @Test
344 public void testSimpleHttpPostsHTTP10() throws Exception {
345
346 final int reqNo = 20;
347
348 final Random rnd = new Random();
349
350
351 final List<byte[]> testData = new ArrayList<>(reqNo);
352 for (int i = 0; i < reqNo; i++) {
353 final int size = rnd.nextInt(5000);
354 final byte[] data = new byte[size];
355 rnd.nextBytes(data);
356 testData.add(data);
357 }
358
359
360 this.server.registerHandler("*", new HttpRequestHandler() {
361
362 @Override
363 public void handle(
364 final ClassicHttpRequest request,
365 final ClassicHttpResponse response,
366 final HttpContext context) throws HttpException, IOException {
367
368 final HttpEntity entity = request.getEntity();
369 if (entity != null) {
370 final byte[] data = EntityUtils.toByteArray(entity);
371 response.setEntity(new ByteArrayEntity(data, null));
372 }
373 if (HttpVersion.HTTP_1_0.equals(request.getVersion())) {
374 response.addHeader("Version", "1.0");
375 }
376 }
377
378 });
379
380 this.server.start();
381 this.client.start();
382
383 final HttpCoreContext context = HttpCoreContext.create();
384 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
385
386 for (int r = 0; r < reqNo; r++) {
387
388 final BasicClassicHttpRequest post = new BasicClassicHttpRequest(Method.POST, "/");
389 post.setVersion(HttpVersion.HTTP_1_0);
390 final byte[] data = testData.get(r);
391 post.setEntity(new ByteArrayEntity(data, null));
392
393 try (final ClassicHttpResponse response = this.client.execute(host, post, context)) {
394 Assert.assertEquals(HttpVersion.HTTP_1_1, response.getVersion());
395 final Header h1 = response.getFirstHeader("Version");
396 Assert.assertNotNull(h1);
397 Assert.assertEquals("1.0", h1.getValue());
398 final byte[] received = EntityUtils.toByteArray(response.getEntity());
399 final byte[] expected = testData.get(r);
400
401 Assert.assertEquals(expected.length, received.length);
402 for (int i = 0; i < expected.length; i++) {
403 Assert.assertEquals(expected[i], received[i]);
404 }
405 }
406 }
407 }
408
409
410
411
412
413 @Test
414 public void testHttpPostsWithExpectContinue() throws Exception {
415
416 final int reqNo = 20;
417
418 final Random rnd = new Random();
419
420
421 final List<byte[]> testData = new ArrayList<>(reqNo);
422 for (int i = 0; i < reqNo; i++) {
423 final int size = rnd.nextInt(5000);
424 final byte[] data = new byte[size];
425 rnd.nextBytes(data);
426 testData.add(data);
427 }
428
429
430 this.server.registerHandler("*", new HttpRequestHandler() {
431
432 @Override
433 public void handle(
434 final ClassicHttpRequest request,
435 final ClassicHttpResponse response,
436 final HttpContext context) throws HttpException, IOException {
437
438 final HttpEntity entity = request.getEntity();
439 if (entity != null) {
440 final byte[] data = EntityUtils.toByteArray(entity);
441 response.setEntity(new ByteArrayEntity(data, null, true));
442 }
443 }
444
445 });
446
447 this.server.start();
448 this.client.start();
449
450 final HttpCoreContext context = HttpCoreContext.create();
451 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
452
453 for (int r = 0; r < reqNo; r++) {
454 final BasicClassicHttpRequest post = new BasicClassicHttpRequest(Method.POST, "/");
455 final byte[] data = testData.get(r);
456 post.setEntity(new ByteArrayEntity(data, null, true));
457
458 try (final ClassicHttpResponse response = this.client.execute(host, post, context)) {
459 final byte[] received = EntityUtils.toByteArray(response.getEntity());
460 final byte[] expected = testData.get(r);
461
462 Assert.assertEquals(expected.length, received.length);
463 for (int i = 0; i < expected.length; i++) {
464 Assert.assertEquals(expected[i], received[i]);
465 }
466 }
467 }
468 }
469
470
471
472
473
474 @Test
475 public void testHttpPostsWithExpectationVerification() throws Exception {
476
477 final int reqNo = 20;
478
479
480 this.server.registerHandler("*", new HttpRequestHandler() {
481
482 @Override
483 public void handle(
484 final ClassicHttpRequest request,
485 final ClassicHttpResponse response,
486 final HttpContext context) throws HttpException, IOException {
487
488 response.setEntity(new StringEntity("No content"));
489 }
490
491 });
492
493 this.server.start(null, null, new Decorator<HttpServerRequestHandler>() {
494
495 @Override
496 public HttpServerRequestHandler decorate(final HttpServerRequestHandler handler) {
497 return new BasicHttpServerExpectationDecorator(handler) {
498
499 @Override
500 protected ClassicHttpResponse verify(final ClassicHttpRequest request, final HttpContext context) {
501 final Header someheader = request.getFirstHeader("Secret");
502 if (someheader != null) {
503 final int secretNumber;
504 try {
505 secretNumber = Integer.parseInt(someheader.getValue());
506 } catch (final NumberFormatException ex) {
507 final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_BAD_REQUEST);
508 response.setEntity(new StringEntity(ex.toString()));
509 return response;
510 }
511 if (secretNumber >= 2) {
512 final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_EXPECTATION_FAILED);
513 response.setEntity(new StringEntity("Wrong secret number", ContentType.TEXT_PLAIN));
514 return response;
515 }
516 }
517 return null;
518 }
519
520 };
521 }
522
523 });
524 this.client.start();
525
526 final HttpCoreContext context = HttpCoreContext.create();
527 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
528
529 for (int r = 0; r < reqNo; r++) {
530 final BasicClassicHttpRequest post = new BasicClassicHttpRequest(Method.POST, "/");
531 post.addHeader("Secret", Integer.toString(r));
532
533 final byte[] b = new byte[2048];
534 for (int i = 0; i < b.length; i++) {
535 b[i] = (byte) ('a' + r);
536 }
537 post.setEntity(new ByteArrayEntity(b, ContentType.TEXT_PLAIN));
538
539 try (final ClassicHttpResponse response = this.client.execute(host, post, context)) {
540 final HttpEntity responseEntity = response.getEntity();
541 Assert.assertNotNull(responseEntity);
542 EntityUtils.consume(responseEntity);
543
544 if (r >= 2) {
545 Assert.assertEquals(HttpStatus.SC_EXPECTATION_FAILED, response.getCode());
546 } else {
547 Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
548 }
549 }
550 }
551 }
552
553 static class RepeatingEntity extends AbstractHttpEntity {
554
555 private final byte[] raw;
556 private final int n;
557
558 public RepeatingEntity(final String content, final Charset charset, final int n, final boolean chunked) {
559 super(ContentType.TEXT_PLAIN.withCharset(charset), null, chunked);
560 final Charset cs = charset != null ? charset : StandardCharsets.US_ASCII;
561 this.raw = content.getBytes(cs);
562 this.n = n;
563 }
564
565 @Override
566 public InputStream getContent() throws IOException, IllegalStateException {
567 throw new IllegalStateException("This method is not implemented");
568 }
569
570 @Override
571 public long getContentLength() {
572 return (this.raw.length + 2) * this.n;
573 }
574
575 @Override
576 public boolean isRepeatable() {
577 return true;
578 }
579
580 @Override
581 public boolean isStreaming() {
582 return false;
583 }
584
585 @Override
586 public void writeTo(final OutputStream outStream) throws IOException {
587 for (int i = 0; i < this.n; i++) {
588 outStream.write(this.raw);
589 outStream.write('\r');
590 outStream.write('\n');
591 }
592 outStream.flush();
593 }
594
595 @Override
596 public void close() throws IOException {
597 }
598
599 }
600
601 @Test
602 public void testHttpContent() throws Exception {
603
604 final String[] patterns = {
605
606 "0123456789ABCDEF",
607 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
608 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
609 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
610 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
611 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
612 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
613 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
614 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
615 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
616 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
617 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
618 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
619 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
620 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that-" +
621 "yadayada-blahblah-this-and-that-yadayada-blahblah-this-and-that"
622 };
623
624
625 this.server.registerHandler("*", new HttpRequestHandler() {
626
627 @Override
628 public void handle(
629 final ClassicHttpRequest request,
630 final ClassicHttpResponse response,
631 final HttpContext context) throws HttpException, IOException {
632
633 int n = 1;
634 String s = request.getPath();
635 if (s.startsWith("/?n=")) {
636 s = s.substring(4);
637 try {
638 n = Integer.parseInt(s);
639 if (n <= 0) {
640 throw new HttpException("Invalid request: " +
641 "number of repetitions cannot be negative or zero");
642 }
643 } catch (final NumberFormatException ex) {
644 throw new HttpException("Invalid request: " +
645 "number of repetitions is invalid");
646 }
647 }
648
649 final HttpEntity entity = request.getEntity();
650 if (entity != null) {
651 final String line = EntityUtils.toString(entity);
652 final ContentType contentType = ContentType.parse(entity.getContentType());
653 Charset charset = contentType.getCharset();
654 if (charset == null) {
655 charset = StandardCharsets.ISO_8859_1;
656 }
657 response.setEntity(new RepeatingEntity(line, charset, n, n % 2 == 0));
658 }
659 }
660
661 });
662
663 this.server.start();
664 this.client.start();
665
666 final HttpCoreContext context = HttpCoreContext.create();
667 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
668
669 for (final String pattern : patterns) {
670 for (int n = 1000; n < 1020; n++) {
671 final BasicClassicHttpRequest post = new BasicClassicHttpRequest(
672 Method.POST.name(), "/?n=" + n);
673 post.setEntity(new StringEntity(pattern, ContentType.TEXT_PLAIN, n % 2 == 0));
674
675 try (final ClassicHttpResponse response = this.client.execute(host, post, context)) {
676 final HttpEntity entity = response.getEntity();
677 Assert.assertNotNull(entity);
678 final InputStream inStream = entity.getContent();
679 final ContentType contentType = ContentType.parse(entity.getContentType());
680 Charset charset = contentType.getCharset();
681 if (charset == null) {
682 charset = StandardCharsets.ISO_8859_1;
683 }
684 Assert.assertNotNull(inStream);
685 final BufferedReader reader = new BufferedReader(new InputStreamReader(inStream, charset));
686
687 String line;
688 int count = 0;
689 while ((line = reader.readLine()) != null) {
690 Assert.assertEquals(pattern, line);
691 count++;
692 }
693 Assert.assertEquals(n, count);
694 }
695 }
696 }
697 }
698
699 @Test
700 public void testHttpPostNoEntity() throws Exception {
701 this.server.registerHandler("*", new HttpRequestHandler() {
702
703 @Override
704 public void handle(
705 final ClassicHttpRequest request,
706 final ClassicHttpResponse response,
707 final HttpContext context) throws HttpException, IOException {
708
709 final HttpEntity entity = request.getEntity();
710 if (entity != null) {
711 final byte[] data = EntityUtils.toByteArray(entity);
712 response.setEntity(new ByteArrayEntity(data, null));
713 }
714 }
715
716 });
717
718 this.server.start();
719 this.client.start();
720
721 final HttpCoreContext context = HttpCoreContext.create();
722 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
723
724 final BasicClassicHttpRequest post = new BasicClassicHttpRequest(Method.POST, "/");
725 post.setEntity(null);
726
727 try (final ClassicHttpResponse response = this.client.execute(host, post, context)) {
728 Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
729 final byte[] received = EntityUtils.toByteArray(response.getEntity());
730 Assert.assertEquals(0, received.length);
731 }
732 }
733
734 @Test
735 public void testHttpPostNoContentLength() throws Exception {
736 this.server.registerHandler("*", new HttpRequestHandler() {
737
738 @Override
739 public void handle(
740 final ClassicHttpRequest request,
741 final ClassicHttpResponse response,
742 final HttpContext context) throws HttpException, IOException {
743
744 final HttpEntity entity = request.getEntity();
745 if (entity != null) {
746 final byte[] data = EntityUtils.toByteArray(entity);
747 response.setEntity(new ByteArrayEntity(data, null));
748 }
749 }
750
751 });
752
753 this.server.start();
754 this.client.start(new DefaultHttpProcessor(
755 new RequestTargetHost(),
756 new RequestConnControl(),
757 new RequestUserAgent(),
758 new RequestExpectContinue()));
759
760 final HttpCoreContext context = HttpCoreContext.create();
761 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
762
763 final BasicClassicHttpRequest post = new BasicClassicHttpRequest(Method.POST, "/");
764 post.setEntity(null);
765
766 try (final ClassicHttpResponse response = this.client.execute(host, post, context)) {
767 Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
768 final byte[] received = EntityUtils.toByteArray(response.getEntity());
769 Assert.assertEquals(0, received.length);
770 }
771 }
772
773 @Test
774 public void testHttpPostIdentity() throws Exception {
775 this.server.registerHandler("*", new HttpRequestHandler() {
776
777 @Override
778 public void handle(
779 final ClassicHttpRequest request,
780 final ClassicHttpResponse response,
781 final HttpContext context) throws HttpException, IOException {
782
783 final HttpEntity entity = request.getEntity();
784 if (entity != null) {
785 final byte[] data = EntityUtils.toByteArray(entity);
786 response.setEntity(new ByteArrayEntity(data, null));
787 }
788 }
789
790 });
791
792 this.server.start();
793 this.client.start(new DefaultHttpProcessor(
794 new HttpRequestInterceptor() {
795
796 @Override
797 public void process(
798 final HttpRequest request,
799 final EntityDetails entity,
800 final HttpContext context) throws HttpException, IOException {
801 request.addHeader(HttpHeaders.TRANSFER_ENCODING, "identity");
802 }
803
804 },
805 new RequestTargetHost(),
806 new RequestConnControl(),
807 new RequestUserAgent(),
808 new RequestExpectContinue()));
809
810 final HttpCoreContext context = HttpCoreContext.create();
811 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
812
813 final BasicClassicHttpRequest post = new BasicClassicHttpRequest(Method.POST, "/");
814 post.setEntity(null);
815
816 try (final ClassicHttpResponse response = this.client.execute(host, post, context)) {
817 Assert.assertEquals(HttpStatus.SC_NOT_IMPLEMENTED, response.getCode());
818 }
819 }
820
821 @Test
822 public void testNoContentResponse() throws Exception {
823
824 final int reqNo = 20;
825
826
827 this.server.registerHandler("*", new HttpRequestHandler() {
828
829 @Override
830 public void handle(
831 final ClassicHttpRequest request,
832 final ClassicHttpResponse response,
833 final HttpContext context) throws HttpException, IOException {
834 response.setCode(HttpStatus.SC_NO_CONTENT);
835 }
836
837 });
838
839 this.server.start();
840 this.client.start();
841
842 final HttpCoreContext context = HttpCoreContext.create();
843 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
844
845 for (int r = 0; r < reqNo; r++) {
846 final BasicClassicHttpRequest get = new BasicClassicHttpRequest(Method.GET, "/?" + r);
847 try (final ClassicHttpResponse response = this.client.execute(host, get, context)) {
848 Assert.assertNull(response.getEntity());
849 }
850 }
851 }
852
853 @Test
854 public void testAbsentHostHeader() throws Exception {
855
856
857 this.server.registerHandler("*", new HttpRequestHandler() {
858
859 @Override
860 public void handle(
861 final ClassicHttpRequest request,
862 final ClassicHttpResponse response,
863 final HttpContext context) throws HttpException, IOException {
864 response.setEntity(new StringEntity("All is well", StandardCharsets.US_ASCII));
865 }
866
867 });
868
869 this.server.start();
870 this.client.start(new DefaultHttpProcessor(new RequestContent(), new RequestConnControl()));
871
872 final HttpCoreContext context = HttpCoreContext.create();
873 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
874
875 final BasicClassicHttpRequest get1 = new BasicClassicHttpRequest(Method.GET, "/");
876 get1.setVersion(HttpVersion.HTTP_1_0);
877 try (final ClassicHttpResponse response1 = this.client.execute(host, get1, context)) {
878 Assert.assertEquals(200, response1.getCode());
879 EntityUtils.consume(response1.getEntity());
880 }
881
882 final BasicClassicHttpRequest get2 = new BasicClassicHttpRequest(Method.GET, "/");
883 try (final ClassicHttpResponse response2 = this.client.execute(host, get2, context)) {
884 Assert.assertEquals(400, response2.getCode());
885 EntityUtils.consume(response2.getEntity());
886 }
887 }
888
889 @Test
890 public void testHeaderTooLarge() throws Exception {
891 this.server.registerHandler("*", new HttpRequestHandler() {
892
893 @Override
894 public void handle(
895 final ClassicHttpRequest request,
896 final ClassicHttpResponse response,
897 final HttpContext context) throws HttpException, IOException {
898 response.setEntity(new StringEntity("All is well", StandardCharsets.US_ASCII));
899 }
900
901 });
902
903 this.server.start(
904 Http1Config.custom()
905 .setMaxLineLength(100)
906 .build(),
907 null,
908 null);
909 this.client.start();
910
911 final HttpCoreContext context = HttpCoreContext.create();
912 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
913
914 final BasicClassicHttpRequest get1 = new BasicClassicHttpRequest(Method.GET, "/");
915 get1.setHeader("big-f-header", "1234567890123456789012345678901234567890123456789012345678901234567890" +
916 "1234567890123456789012345678901234567890");
917 try (final ClassicHttpResponse response1 = this.client.execute(host, get1, context)) {
918 Assert.assertEquals(431, response1.getCode());
919 EntityUtils.consume(response1.getEntity());
920 }
921 }
922
923 @Test
924 public void testHeaderTooLargePost() throws Exception {
925 this.server.registerHandler("*", new HttpRequestHandler() {
926
927 @Override
928 public void handle(
929 final ClassicHttpRequest request,
930 final ClassicHttpResponse response,
931 final HttpContext context) throws HttpException, IOException {
932 response.setEntity(new StringEntity("All is well", StandardCharsets.US_ASCII));
933 }
934
935 });
936
937 this.server.start(
938 Http1Config.custom()
939 .setMaxLineLength(100)
940 .build(),
941 null,
942 null);
943 this.client.start(
944 new DefaultHttpProcessor(new RequestContent(), new RequestTargetHost(), new RequestConnControl()));
945
946 final HttpCoreContext context = HttpCoreContext.create();
947 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
948
949 final ClassicHttpRequest post1 = new BasicClassicHttpRequest(Method.POST, "/");
950 post1.setHeader("big-f-header", "1234567890123456789012345678901234567890123456789012345678901234567890" +
951 "1234567890123456789012345678901234567890");
952 final byte[] b = new byte[2048];
953 for (int i = 0; i < b.length; i++) {
954 b[i] = (byte) ('a' + i % 10);
955 }
956 post1.setEntity(new ByteArrayEntity(b, ContentType.TEXT_PLAIN));
957
958 try (final ClassicHttpResponse response1 = this.client.execute(host, post1, context)) {
959 Assert.assertEquals(431, response1.getCode());
960 EntityUtils.consume(response1.getEntity());
961 }
962 }
963
964 }