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.http.client.utils;
28
29 import java.net.URI;
30 import java.net.URISyntaxException;
31 import java.util.ArrayList;
32 import java.util.EnumSet;
33 import java.util.Iterator;
34 import java.util.List;
35 import java.util.Locale;
36 import java.util.Stack;
37
38 import org.apache.http.HttpHost;
39 import org.apache.http.conn.routing.RouteInfo;
40 import org.apache.http.util.Args;
41 import org.apache.http.util.TextUtils;
42
43
44
45
46
47
48
49 public class URIUtils {
50
51
52
53
54
55
56 public enum UriFlag {
57 DROP_FRAGMENT,
58 NORMALIZE
59 }
60
61
62
63
64
65
66 public static final EnumSet<UriFlag> NO_FLAGS = EnumSet.noneOf(UriFlag.class);
67
68
69
70
71
72
73 public static final EnumSet<UriFlag> DROP_FRAGMENT = EnumSet.of(UriFlag.DROP_FRAGMENT);
74
75
76
77
78
79
80 public static final EnumSet<UriFlag> NORMALIZE = EnumSet.of(UriFlag.NORMALIZE);
81
82
83
84
85
86
87 public static final EnumSet<UriFlag> DROP_FRAGMENT_AND_NORMALIZE = EnumSet.of(UriFlag.DROP_FRAGMENT, UriFlag.NORMALIZE);
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117 @Deprecated
118 public static URI createURI(
119 final String scheme,
120 final String host,
121 final int port,
122 final String path,
123 final String query,
124 final String fragment) throws URISyntaxException {
125 final StringBuilder buffer = new StringBuilder();
126 if (host != null) {
127 if (scheme != null) {
128 buffer.append(scheme);
129 buffer.append("://");
130 }
131 buffer.append(host);
132 if (port > 0) {
133 buffer.append(':');
134 buffer.append(port);
135 }
136 }
137 if (path == null || !path.startsWith("/")) {
138 buffer.append('/');
139 }
140 if (path != null) {
141 buffer.append(path);
142 }
143 if (query != null) {
144 buffer.append('?');
145 buffer.append(query);
146 }
147 if (fragment != null) {
148 buffer.append('#');
149 buffer.append(fragment);
150 }
151 return new URI(buffer.toString());
152 }
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171 @Deprecated
172 public static URI rewriteURI(
173 final URI uri,
174 final HttpHost target,
175 final boolean dropFragment) throws URISyntaxException
176 {
177 return rewriteURI(uri, target, dropFragment ? DROP_FRAGMENT : NO_FLAGS);
178 }
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197 public static URI rewriteURI(
198 final URI uri,
199 final HttpHost target,
200 final EnumSet<UriFlag> flags) throws URISyntaxException {
201 Args.notNull(uri, "URI");
202 Args.notNull(flags, "URI flags");
203 if (uri.isOpaque()) {
204 return uri;
205 }
206 final URIBuilderuilder.html#URIBuilder">URIBuilder uribuilder = new URIBuilder(uri);
207 if (target != null) {
208 uribuilder.setScheme(target.getSchemeName());
209 uribuilder.setHost(target.getHostName());
210 uribuilder.setPort(target.getPort());
211 } else {
212 uribuilder.setScheme(null);
213 uribuilder.setHost(null);
214 uribuilder.setPort(-1);
215 }
216 if (flags.contains(UriFlag.DROP_FRAGMENT)) {
217 uribuilder.setFragment(null);
218 }
219 if (flags.contains(UriFlag.NORMALIZE)) {
220 final List<String> originalPathSegments = uribuilder.getPathSegments();
221 final List<String> pathSegments = new ArrayList<String>(originalPathSegments);
222 for (final Iterator<String> it = pathSegments.iterator(); it.hasNext(); ) {
223 final String pathSegment = it.next();
224 if (pathSegment.isEmpty() && it.hasNext()) {
225 it.remove();
226 }
227 }
228 if (pathSegments.size() != originalPathSegments.size()) {
229 uribuilder.setPathSegments(pathSegments);
230 }
231 }
232 if (uribuilder.isPathEmpty()) {
233 uribuilder.setPathSegments("");
234 }
235 return uribuilder.build();
236 }
237
238
239
240
241
242
243 public static URI rewriteURI(
244 final URI uri,
245 final HttpHost target) throws URISyntaxException {
246 return rewriteURI(uri, target, NORMALIZE);
247 }
248
249
250
251
252
253
254
255
256
257
258
259
260 public static URI rewriteURI(final URI uri) throws URISyntaxException {
261 Args.notNull(uri, "URI");
262 if (uri.isOpaque()) {
263 return uri;
264 }
265 final URIBuilderuilder.html#URIBuilder">URIBuilder uribuilder = new URIBuilder(uri);
266 if (uribuilder.getUserInfo() != null) {
267 uribuilder.setUserInfo(null);
268 }
269 if (uribuilder.getPathSegments().isEmpty()) {
270 uribuilder.setPathSegments("");
271 }
272 if (TextUtils.isEmpty(uribuilder.getPath())) {
273 uribuilder.setPath("/");
274 }
275 if (uribuilder.getHost() != null) {
276 uribuilder.setHost(uribuilder.getHost().toLowerCase(Locale.ROOT));
277 }
278 uribuilder.setFragment(null);
279 return uribuilder.build();
280 }
281
282
283
284
285
286
287
288
289
290
291
292
293 public static URI rewriteURIForRoute(final URI uri, final RouteInfo route) throws URISyntaxException {
294 return rewriteURIForRoute(uri, route, true);
295 }
296
297
298
299
300
301
302
303
304
305
306
307
308 public static URI rewriteURIForRoute(final URI uri, final RouteInfo route, final boolean normalizeUri) throws URISyntaxException {
309 if (uri == null) {
310 return null;
311 }
312 if (route.getProxyHost() != null && !route.isTunnelled()) {
313
314 return uri.isAbsolute()
315 ? rewriteURI(uri)
316 : rewriteURI(uri, route.getTargetHost(), normalizeUri ? DROP_FRAGMENT_AND_NORMALIZE : DROP_FRAGMENT);
317 }
318
319 return uri.isAbsolute() ? rewriteURI(uri, null, normalizeUri ? DROP_FRAGMENT_AND_NORMALIZE : DROP_FRAGMENT) : rewriteURI(uri);
320 }
321
322
323
324
325
326
327
328
329
330 public static URI resolve(final URI baseURI, final String reference) {
331 return resolve(baseURI, URI.create(reference));
332 }
333
334
335
336
337
338
339
340
341
342 public static URI resolve(final URI baseURI, final URI reference){
343 Args.notNull(baseURI, "Base URI");
344 Args.notNull(reference, "Reference URI");
345 final String s = reference.toASCIIString();
346 if (s.startsWith("?")) {
347 String baseUri = baseURI.toASCIIString();
348 final int i = baseUri.indexOf('?');
349 baseUri = i > -1 ? baseUri.substring(0, i) : baseUri;
350 return URI.create(baseUri + s);
351 }
352 final boolean emptyReference = s.isEmpty();
353 URI resolved;
354 if (emptyReference) {
355 resolved = baseURI.resolve(URI.create("#"));
356 final String resolvedString = resolved.toASCIIString();
357 resolved = URI.create(resolvedString.substring(0, resolvedString.indexOf('#')));
358 } else {
359 resolved = baseURI.resolve(reference);
360 }
361 try {
362 return normalizeSyntax(resolved);
363 } catch (final URISyntaxException ex) {
364 throw new IllegalArgumentException(ex);
365 }
366 }
367
368
369
370
371
372
373
374
375
376
377 public static URI normalizeSyntax(final URI uri) throws URISyntaxException {
378 if (uri.isOpaque() || uri.getAuthority() == null) {
379
380 return uri;
381 }
382 final URIBuilderRIBuilder.html#URIBuilder">URIBuilder builder = new URIBuilder(uri);
383 final List<String> inputSegments = builder.getPathSegments();
384 final Stack<String> outputSegments = new Stack<String>();
385 for (final String inputSegment : inputSegments) {
386 if (".".equals(inputSegment)) {
387
388 } else if ("..".equals(inputSegment)) {
389 if (!outputSegments.isEmpty()) {
390 outputSegments.pop();
391 }
392 } else {
393 outputSegments.push(inputSegment);
394 }
395 }
396 if (outputSegments.size() == 0) {
397 outputSegments.add("");
398 }
399 builder.setPathSegments(outputSegments);
400 if (builder.getScheme() != null) {
401 builder.setScheme(builder.getScheme().toLowerCase(Locale.ROOT));
402 }
403 if (builder.getHost() != null) {
404 builder.setHost(builder.getHost().toLowerCase(Locale.ROOT));
405 }
406 return builder.build();
407 }
408
409
410
411
412
413
414
415
416
417
418 public static HttpHost extractHost(final URI uri) {
419 if (uri == null) {
420 return null;
421 }
422 if (uri.isAbsolute()) {
423 if (uri.getHost() == null) {
424
425 if (uri.getAuthority() != null) {
426 String content = uri.getAuthority();
427
428 int at = content.indexOf('@');
429 if (at != -1) {
430 content = content.substring(at + 1);
431 }
432 final String scheme = uri.getScheme();
433 final String hostname;
434 final int port;
435 at = content.indexOf(":");
436 if (at != -1) {
437 hostname = content.substring(0, at);
438 try {
439 final String portText = content.substring(at + 1);
440 port = !TextUtils.isEmpty(portText) ? Integer.parseInt(portText) : -1;
441 } catch (final NumberFormatException ex) {
442 return null;
443 }
444 } else {
445 hostname = content;
446 port = -1;
447 }
448 try {
449 return new HttpHost(hostname, port, scheme);
450 } catch (final IllegalArgumentException ex) {
451
452 }
453 }
454 } else {
455 return new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
456 }
457 }
458 return null;
459 }
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477 public static URI resolve(
478 final URI originalURI,
479 final HttpHost target,
480 final List<URI> redirects) throws URISyntaxException {
481 Args.notNull(originalURI, "Request URI");
482 final URIBuilder uribuilder;
483 if (redirects == null || redirects.isEmpty()) {
484 uribuilder = new URIBuilder(originalURI);
485 } else {
486 uribuilder = new URIBuilder(redirects.get(redirects.size() - 1));
487 String frag = uribuilder.getFragment();
488
489 for (int i = redirects.size() - 1; frag == null && i >= 0; i--) {
490 frag = redirects.get(i).getFragment();
491 }
492 uribuilder.setFragment(frag);
493 }
494
495 if (uribuilder.getFragment() == null) {
496 uribuilder.setFragment(originalURI.getFragment());
497 }
498
499 if (target != null && !uribuilder.isAbsolute()) {
500 uribuilder.setScheme(target.getSchemeName());
501 uribuilder.setHost(target.getHostName());
502 uribuilder.setPort(target.getPort());
503 }
504 return uribuilder.build();
505 }
506
507
508
509
510 private URIUtils() {
511 }
512
513 }