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.IOException;
31 import java.io.InputStream;
32 import java.io.OutputStream;
33 import java.util.concurrent.TimeUnit;
34
35 import org.apache.hc.core5.http.ClassicHttpRequest;
36 import org.apache.hc.core5.http.ClassicHttpResponse;
37 import org.apache.hc.core5.http.ContentType;
38 import org.apache.hc.core5.http.HttpHost;
39 import org.apache.hc.core5.http.Method;
40 import org.apache.hc.core5.http.URIScheme;
41 import org.apache.hc.core5.http.impl.bootstrap.HttpRequester;
42 import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
43 import org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnectionFactory;
44 import org.apache.hc.core5.http.impl.io.MonitoringResponseOutOfOrderStrategy;
45 import org.apache.hc.core5.http.impl.routing.RequestRouter;
46 import org.apache.hc.core5.http.io.HttpRequestHandler;
47 import org.apache.hc.core5.http.io.SocketConfig;
48 import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
49 import org.apache.hc.core5.http.io.entity.EntityUtils;
50 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
51 import org.apache.hc.core5.http.protocol.HttpCoreContext;
52 import org.apache.hc.core5.testing.classic.extension.HttpRequesterResource;
53 import org.apache.hc.core5.testing.classic.extension.HttpServerResource;
54 import org.apache.hc.core5.util.Timeout;
55 import org.junit.jupiter.api.Assertions;
56 import org.junit.jupiter.api.Test;
57 import org.junit.jupiter.api.extension.RegisterExtension;
58
59 public abstract class MonitoringResponseOutOfOrderStrategyIntegrationTest {
60
61
62 private static final int BUFFER_SIZE = 16 * 1024;
63 private static final Timeout TIMEOUT = Timeout.ofSeconds(3);
64
65 private final URIScheme scheme;
66
67 @RegisterExtension
68 private final HttpServerResource serverResource;
69
70 @RegisterExtension
71 private final HttpRequesterResource clientResource;
72
73 public MonitoringResponseOutOfOrderStrategyIntegrationTest(final URIScheme scheme) {
74 this.scheme = scheme;
75
76 this.serverResource = new HttpServerResource(scheme, bootstrap -> bootstrap
77 .setSocketConfig(SocketConfig.custom()
78 .setSoTimeout(TIMEOUT)
79 .setSndBufSize(BUFFER_SIZE)
80 .setRcvBufSize(BUFFER_SIZE)
81 .setSoKeepAlive(false)
82 .build())
83 .setRequestRouter(RequestRouter.<HttpRequestHandler>builder()
84 .addRoute(RequestRouter.LOCAL_AUTHORITY, "*", (request, response, context) -> {
85 response.setCode(400);
86 response.setEntity(new AllOnesHttpEntity(200000));
87 })
88 .resolveAuthority(RequestRouter.LOCAL_AUTHORITY_RESOLVER)
89 .build()));
90
91 this.clientResource = new HttpRequesterResource(bootstrap -> bootstrap
92 .setSocketConfig(SocketConfig.custom()
93 .setSoTimeout(TIMEOUT)
94 .setRcvBufSize(BUFFER_SIZE)
95 .setSndBufSize(BUFFER_SIZE)
96 .setSoKeepAlive(false)
97 .build())
98 .setConnectionFactory(DefaultBHttpClientConnectionFactory.builder()
99 .responseOutOfOrderStrategy(MonitoringResponseOutOfOrderStrategy.INSTANCE)
100 .build()));
101 }
102
103 @Test
104 @org.junit.jupiter.api.Timeout(value = 1, unit = TimeUnit.MINUTES)
105 public void testResponseOutOfOrderWithDefaultStrategy() throws Exception {
106 final HttpServer server = serverResource.start();
107 final HttpRequester requester = clientResource.start();
108
109 final HttpCoreContext context = HttpCoreContext.create();
110 final HttpHost host = new HttpHost(scheme.id, "localhost", server.getLocalPort());
111
112 final ClassicHttpRequest post = new BasicClassicHttpRequest(Method.POST, "/");
113 post.setEntity(new AllOnesHttpEntity(200000));
114
115 try (final ClassicHttpResponse response = requester.execute(host, post, TIMEOUT, context)) {
116 Assertions.assertEquals(400, response.getCode());
117 EntityUtils.consumeQuietly(response.getEntity());
118 }
119 }
120
121 private static final class AllOnesHttpEntity extends AbstractHttpEntity {
122 private long remaining;
123
124 protected AllOnesHttpEntity(final long length) {
125 super(ContentType.APPLICATION_OCTET_STREAM, null, true);
126 this.remaining = length;
127 }
128
129 @Override
130 public InputStream getContent() {
131 throw new UnsupportedOperationException();
132 }
133
134 @Override
135 public void writeTo(final OutputStream outStream) throws IOException {
136 final byte[] buf = new byte[1024];
137 while (remaining > 0) {
138 final int writeLength = (int) Math.min(remaining, buf.length);
139 outStream.write(buf, 0, writeLength);
140 outStream.flush();
141 remaining -= writeLength;
142 }
143 }
144
145 @Override
146 public boolean isStreaming() {
147 return true;
148 }
149
150 @Override
151 public void close() {
152 }
153
154 @Override
155 public long getContentLength() {
156 return -1L;
157 }
158 }
159 }