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