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 org.apache.hc.core5.http.ClassicHttpRequest;
31 import org.apache.hc.core5.http.ClassicHttpResponse;
32 import org.apache.hc.core5.http.ContentType;
33 import org.apache.hc.core5.http.HttpHost;
34 import org.apache.hc.core5.http.Method;
35 import org.apache.hc.core5.http.URIScheme;
36 import org.apache.hc.core5.http.impl.bootstrap.HttpRequester;
37 import org.apache.hc.core5.http.impl.bootstrap.RequesterBootstrap;
38 import org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnectionFactory;
39 import org.apache.hc.core5.http.impl.io.MonitoringResponseOutOfOrderStrategy;
40 import org.apache.hc.core5.http.io.HttpRequestHandler;
41 import org.apache.hc.core5.http.io.SocketConfig;
42 import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
43 import org.apache.hc.core5.http.io.entity.EntityUtils;
44 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
45 import org.apache.hc.core5.http.protocol.HttpContext;
46 import org.apache.hc.core5.http.protocol.HttpCoreContext;
47 import org.apache.hc.core5.io.CloseMode;
48 import org.apache.hc.core5.testing.SSLTestContexts;
49 import org.apache.hc.core5.util.Timeout;
50 import org.junit.Assert;
51 import org.junit.Rule;
52 import org.junit.Test;
53 import org.junit.rules.ExternalResource;
54 import org.junit.runner.RunWith;
55 import org.junit.runners.Parameterized;
56
57 import java.io.IOException;
58 import java.io.InputStream;
59 import java.io.OutputStream;
60 import java.util.Arrays;
61 import java.util.Collection;
62
63 @RunWith(Parameterized.class)
64 public class MonitoringResponseOutOfOrderStrategyIntegrationTest {
65
66
67 private static final int BUFFER_SIZE = 16 * 1024;
68 private static final Timeout TIMEOUT = Timeout.ofSeconds(3);
69
70 @Parameterized.Parameters(name = "{0}")
71 public static Collection<Object[]> protocols() {
72 return Arrays.asList(new Object[][]{
73 { URIScheme.HTTP },
74 { URIScheme.HTTPS }
75 });
76 }
77
78 private final URIScheme scheme;
79 private ClassicTestServer server;
80 private HttpRequester requester;
81
82 public MonitoringResponseOutOfOrderStrategyIntegrationTest(final URIScheme scheme) {
83 this.scheme = scheme;
84 }
85
86 @Rule
87 public ExternalResource serverResource = new ExternalResource() {
88
89 @Override
90 protected void before() throws Throwable {
91 server = new ClassicTestServer(
92 scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null,
93 SocketConfig.custom()
94 .setSoTimeout(TIMEOUT)
95 .setSndBufSize(BUFFER_SIZE)
96 .setRcvBufSize(BUFFER_SIZE)
97 .setSoKeepAlive(false)
98 .build());
99 }
100
101 @Override
102 protected void after() {
103 if (server != null) {
104 try {
105 server.shutdown(CloseMode.IMMEDIATE);
106 server = null;
107 } catch (final Exception ignore) {
108 }
109 }
110 }
111
112 };
113
114 @Rule
115 public ExternalResource requesterResource = new ExternalResource() {
116
117 @Override
118 protected void before() throws Throwable {
119 requester = RequesterBootstrap.bootstrap()
120 .setSslContext(scheme == URIScheme.HTTPS ? SSLTestContexts.createClientSSLContext() : null)
121 .setSocketConfig(SocketConfig.custom()
122 .setSoTimeout(TIMEOUT)
123 .setRcvBufSize(BUFFER_SIZE)
124 .setSndBufSize(BUFFER_SIZE)
125 .setSoKeepAlive(false)
126 .build())
127 .setStreamListener(LoggingHttp1StreamListener.INSTANCE)
128 .setConnPoolListener(LoggingConnPoolListener.INSTANCE)
129 .setConnectionFactory(DefaultBHttpClientConnectionFactory.builder()
130 .responseOutOfOrderStrategy(MonitoringResponseOutOfOrderStrategy.INSTANCE)
131 .build())
132 .create();
133 }
134
135 @Override
136 protected void after() {
137 if (requester != null) {
138 try {
139 requester.close(CloseMode.IMMEDIATE);
140 requester = null;
141 } catch (final Exception ignore) {
142 }
143 }
144 }
145
146 };
147
148 @Test(timeout = 5000)
149 public void testResponseOutOfOrderWithDefaultStrategy() throws Exception {
150 this.server.registerHandler("*", new HttpRequestHandler() {
151
152 @Override
153 public void handle(
154 final ClassicHttpRequest request,
155 final ClassicHttpResponse response,
156 final HttpContext context) throws IOException {
157 response.setCode(400);
158 response.setEntity(new AllOnesHttpEntity(200000));
159 }
160
161 });
162
163 this.server.start(null, null, null);
164
165 final HttpCoreContext context = HttpCoreContext.create();
166 final HttpHost host = new HttpHost(scheme.id, "localhost", this.server.getPort());
167
168 final ClassicHttpRequest post = new BasicClassicHttpRequest(Method.POST, "/");
169 post.setEntity(new AllOnesHttpEntity(200000));
170
171 try (final ClassicHttpResponse response = requester.execute(host, post, TIMEOUT, context)) {
172 Assert.assertEquals(400, response.getCode());
173 EntityUtils.consumeQuietly(response.getEntity());
174 }
175 }
176
177 private static final class AllOnesHttpEntity extends AbstractHttpEntity {
178 private long remaining;
179
180 protected AllOnesHttpEntity(final long length) {
181 super(ContentType.APPLICATION_OCTET_STREAM, null, true);
182 this.remaining = length;
183 }
184
185 @Override
186 public InputStream getContent() {
187 throw new UnsupportedOperationException();
188 }
189
190 @Override
191 public void writeTo(final OutputStream outStream) throws IOException {
192 final byte[] buf = new byte[1024];
193 while (remaining > 0) {
194 final int writeLength = (int) Math.min(remaining, buf.length);
195 outStream.write(buf, 0, writeLength);
196 outStream.flush();
197 remaining -= writeLength;
198 }
199 }
200
201 @Override
202 public boolean isStreaming() {
203 return true;
204 }
205
206 @Override
207 public void close() {
208 }
209
210 @Override
211 public long getContentLength() {
212 return -1L;
213 }
214 }
215 }