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.ByteArrayInputStream;
30 import java.io.IOException;
31 import java.net.URI;
32
33 import org.apache.hc.client5.http.HttpRequestRetryStrategy;
34 import org.apache.hc.client5.http.classic.methods.HttpGet;
35 import org.apache.hc.client5.http.classic.methods.HttpPost;
36 import org.apache.hc.client5.http.protocol.HttpClientContext;
37 import org.apache.hc.client5.http.protocol.RedirectLocations;
38 import org.apache.hc.client5.http.utils.URIUtils;
39 import org.apache.hc.core5.http.ClassicHttpRequest;
40 import org.apache.hc.core5.http.ClassicHttpResponse;
41 import org.apache.hc.core5.http.EntityDetails;
42 import org.apache.hc.core5.http.Header;
43 import org.apache.hc.core5.http.HttpException;
44 import org.apache.hc.core5.http.HttpHost;
45 import org.apache.hc.core5.http.HttpRequest;
46 import org.apache.hc.core5.http.HttpRequestInterceptor;
47 import org.apache.hc.core5.http.HttpResponse;
48 import org.apache.hc.core5.http.HttpStatus;
49 import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
50 import org.apache.hc.core5.http.io.HttpClientConnection;
51 import org.apache.hc.core5.http.io.HttpRequestHandler;
52 import org.apache.hc.core5.http.io.entity.EntityUtils;
53 import org.apache.hc.core5.http.io.entity.InputStreamEntity;
54 import org.apache.hc.core5.http.io.entity.StringEntity;
55 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
56 import org.apache.hc.core5.http.protocol.HttpContext;
57 import org.apache.hc.core5.net.URIBuilder;
58 import org.apache.hc.core5.util.TimeValue;
59 import org.junit.Assert;
60 import org.junit.Test;
61
62
63
64
65 public class TestClientRequestExecution extends LocalServerTestBase {
66
67 private static class SimpleService implements HttpRequestHandler {
68
69 public SimpleService() {
70 super();
71 }
72
73 @Override
74 public void handle(
75 final ClassicHttpRequest request,
76 final ClassicHttpResponse response,
77 final HttpContext context) throws HttpException, IOException {
78 response.setCode(HttpStatus.SC_OK);
79 final StringEntity entity = new StringEntity("Whatever");
80 response.setEntity(entity);
81 }
82 }
83
84 private static class FaultyHttpRequestExecutor extends HttpRequestExecutor {
85
86 private static final String MARKER = "marker";
87
88 private final String failureMsg;
89
90 public FaultyHttpRequestExecutor(final String failureMsg) {
91 this.failureMsg = failureMsg;
92 }
93
94 @Override
95 public ClassicHttpResponse execute(
96 final ClassicHttpRequest request,
97 final HttpClientConnection conn,
98 final HttpContext context) throws IOException, HttpException {
99
100 final ClassicHttpResponse response = super.execute(request, conn, context);
101 final Object marker = context.getAttribute(MARKER);
102 if (marker == null) {
103 context.setAttribute(MARKER, Boolean.TRUE);
104 throw new IOException(failureMsg);
105 }
106 return response;
107 }
108
109 }
110
111 @Test
112 public void testAutoGeneratedHeaders() throws Exception {
113 this.server.registerHandler("*", new SimpleService());
114
115 final HttpRequestInterceptor interceptor = new HttpRequestInterceptor() {
116
117 @Override
118 public void process(
119 final HttpRequest request,
120 final EntityDetails entityDetails,
121 final HttpContext context) throws HttpException, IOException {
122 request.addHeader("my-header", "stuff");
123 }
124
125 };
126
127 final HttpRequestRetryStrategy requestRetryStrategy = new HttpRequestRetryStrategy() {
128
129 @Override
130 public boolean retryRequest(
131 final HttpRequest request,
132 final IOException exception,
133 final int executionCount,
134 final HttpContext context) {
135 return true;
136 }
137
138 @Override
139 public boolean retryRequest(
140 final HttpResponse response,
141 final int executionCount,
142 final HttpContext context) {
143 return false;
144 }
145
146 @Override
147 public TimeValue getRetryInterval(
148 final HttpResponse response,
149 final int executionCount,
150 final HttpContext context) {
151 return TimeValue.ofSeconds(1L);
152 }
153
154 };
155
156 this.httpclient = this.clientBuilder
157 .addRequestInterceptorFirst(interceptor)
158 .setRequestExecutor(new FaultyHttpRequestExecutor("Oppsie"))
159 .setRetryStrategy(requestRetryStrategy)
160 .build();
161
162 final HttpHost target = start();
163
164 final HttpClientContext context = HttpClientContext.create();
165
166 final HttpGet httpget = new HttpGet("/");
167
168 final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
169 EntityUtils.consume(response.getEntity());
170
171 final HttpRequest reqWrapper = context.getRequest();
172
173 Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
174
175 final Header[] myheaders = reqWrapper.getHeaders("my-header");
176 Assert.assertNotNull(myheaders);
177 Assert.assertEquals(1, myheaders.length);
178 }
179
180 @Test(expected=IOException.class)
181 public void testNonRepeatableEntity() throws Exception {
182 this.server.registerHandler("*", new SimpleService());
183
184 final HttpRequestRetryStrategy requestRetryStrategy = new HttpRequestRetryStrategy() {
185
186 @Override
187 public boolean retryRequest(
188 final HttpRequest request,
189 final IOException exception,
190 final int executionCount,
191 final HttpContext context) {
192 return true;
193 }
194
195 @Override
196 public boolean retryRequest(
197 final HttpResponse response,
198 final int executionCount,
199 final HttpContext context) {
200 return false;
201 }
202
203 @Override
204 public TimeValue getRetryInterval(
205 final HttpResponse response,
206 final int executionCount,
207 final HttpContext context) {
208 return TimeValue.ofSeconds(1L);
209 }
210
211 };
212
213 this.httpclient = this.clientBuilder
214 .setRequestExecutor(new FaultyHttpRequestExecutor("a message showing that this failed"))
215 .setRetryStrategy(requestRetryStrategy)
216 .build();
217
218 final HttpHost target = start();
219
220 final HttpClientContext context = HttpClientContext.create();
221
222 final HttpPost httppost = new HttpPost("/");
223 httppost.setEntity(new InputStreamEntity(
224 new ByteArrayInputStream(
225 new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 } ),
226 -1, null));
227 this.httpclient.execute(target, httppost, context);
228 }
229
230 @Test
231 public void testNonCompliantURI() throws Exception {
232 this.server.registerHandler("*", new SimpleService());
233
234 final HttpHost target = start();
235
236 final HttpClientContext context = HttpClientContext.create();
237 final ClassicHttpRequest request = new BasicClassicHttpRequest("GET", "{{|boom|}}");
238 final ClassicHttpResponse response = this.httpclient.execute(target, request, context);
239 EntityUtils.consume(response.getEntity());
240
241 Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
242
243 final HttpRequest reqWrapper = context.getRequest();
244
245 Assert.assertEquals("{{|boom|}}", reqWrapper.getRequestUri());
246 }
247
248 @Test
249 public void testRelativeRequestURIWithFragment() throws Exception {
250 this.server.registerHandler("*", new SimpleService());
251
252 final HttpHost target = start();
253
254 final HttpGet httpget = new HttpGet("/stuff#blahblah");
255 final HttpClientContext context = HttpClientContext.create();
256
257 final ClassicHttpResponse response = this.httpclient.execute(target, httpget, context);
258 Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
259 EntityUtils.consume(response.getEntity());
260
261 final HttpRequest request = context.getRequest();
262 Assert.assertEquals("/stuff", request.getRequestUri());
263 }
264
265 @Test
266 public void testAbsoluteRequestURIWithFragment() throws Exception {
267 this.server.registerHandler("*", new SimpleService());
268
269 final HttpHost target = start();
270
271 final URI uri = new URIBuilder()
272 .setHost(target.getHostName())
273 .setPort(target.getPort())
274 .setScheme(target.getSchemeName())
275 .setPath("/stuff")
276 .setFragment("blahblah")
277 .build();
278
279 final HttpGet httpget = new HttpGet(uri);
280 final HttpClientContext context = HttpClientContext.create();
281
282 final ClassicHttpResponse response = this.httpclient.execute(httpget, context);
283 Assert.assertEquals(HttpStatus.SC_OK, response.getCode());
284 EntityUtils.consume(response.getEntity());
285
286 final HttpRequest request = context.getRequest();
287 Assert.assertEquals("/stuff", request.getRequestUri());
288
289 final RedirectLocations redirectLocations = context.getRedirectLocations();
290 final URI location = URIUtils.resolve(uri, target, redirectLocations.getAll());
291 Assert.assertEquals(uri, location);
292 }
293
294 }