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 package org.apache.hc.client5.testing.sync;
28
29 import java.io.IOException;
30 import java.net.Socket;
31
32 import org.apache.hc.client5.http.classic.methods.HttpGet;
33 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
34 import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
35 import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
36 import org.apache.hc.core5.http.ClassicHttpRequest;
37 import org.apache.hc.core5.http.ClassicHttpResponse;
38 import org.apache.hc.core5.http.HttpException;
39 import org.apache.hc.core5.http.HttpHost;
40 import org.apache.hc.core5.http.HttpStatus;
41 import org.apache.hc.core5.http.config.Http1Config;
42 import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
43 import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
44 import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnection;
45 import org.apache.hc.core5.http.io.HttpConnectionFactory;
46 import org.apache.hc.core5.http.io.HttpRequestHandler;
47 import org.apache.hc.core5.http.io.entity.EntityUtils;
48 import org.apache.hc.core5.http.io.entity.StringEntity;
49 import org.apache.hc.core5.http.protocol.HttpContext;
50 import org.junit.Assert;
51 import org.junit.Test;
52
53 public class TestMalformedServerResponse {
54
55 static class BrokenServerConnection extends DefaultBHttpServerConnection {
56
57 public BrokenServerConnection(final Http1Config h1Config) {
58 super(null, h1Config);
59 }
60
61 @Override
62 public void sendResponseHeader(final ClassicHttpResponse response) throws HttpException, IOException {
63 super.sendResponseHeader(response);
64 if (response.getCode() == HttpStatus.SC_NO_CONTENT) {
65 response.setEntity(new StringEntity(
66 "garbage\ngarbage\n" +
67 "garbage\ngarbage\n" +
68 "garbage\ngarbage\n" +
69 "garbage\ngarbage\n" +
70 "garbage\ngarbage\n" +
71 "garbage\ngarbage\n" +
72 "garbage\ngarbage\n" +
73 "garbage\ngarbage\n" +
74 "garbage\ngarbage\n"));
75 sendResponseEntity(response);
76 }
77 }
78 }
79
80 static class BrokenServerConnectionFactory implements HttpConnectionFactory<DefaultBHttpServerConnection> {
81
82 @Override
83 public DefaultBHttpServerConnection createConnection(final Socket socket) throws IOException {
84 final BrokenServerConnection conn = new BrokenServerConnection(Http1Config.DEFAULT);
85 conn.bind(socket);
86 return conn;
87 }
88 }
89
90 @Test
91 public void testNoContentResponseWithGarbage() throws Exception {
92 try (final HttpServer server = ServerBootstrap.bootstrap()
93 .setConnectionFactory(new BrokenServerConnectionFactory())
94 .register("/nostuff", new HttpRequestHandler() {
95
96 @Override
97 public void handle(
98 final ClassicHttpRequest request,
99 final ClassicHttpResponse response,
100 final HttpContext context) throws HttpException, IOException {
101 response.setCode(HttpStatus.SC_NO_CONTENT);
102 }
103
104 })
105 .register("/stuff", new HttpRequestHandler() {
106
107 @Override
108 public void handle(
109 final ClassicHttpRequest request,
110 final ClassicHttpResponse response,
111 final HttpContext context) throws HttpException, IOException {
112 response.setCode(HttpStatus.SC_OK);
113 response.setEntity(new StringEntity("Some important stuff"));
114 }
115
116 })
117 .create()) {
118 server.start();
119 final HttpHost target = new HttpHost("localhost", server.getLocalPort());
120 try (final CloseableHttpClient httpclient = HttpClientBuilder.create().build()) {
121 final HttpGet get1 = new HttpGet("/nostuff");
122 try (final CloseableHttpResponse response1 = httpclient.execute(target, get1)) {
123 Assert.assertEquals(HttpStatus.SC_NO_CONTENT, response1.getCode());
124 EntityUtils.consume(response1.getEntity());
125 }
126 final HttpGet get2 = new HttpGet("/stuff");
127 try (final CloseableHttpResponse response2 = httpclient.execute(target, get2)) {
128 Assert.assertEquals(HttpStatus.SC_OK, response2.getCode());
129 EntityUtils.consume(response2.getEntity());
130 }
131 }
132 }
133 }
134
135 }