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.client5.http.impl;
29
30 import java.net.URI;
31 import java.net.URISyntaxException;
32 import java.util.Locale;
33
34 import org.apache.hc.client5.http.protocol.RedirectStrategy;
35 import org.apache.hc.client5.http.utils.URIUtils;
36 import org.apache.hc.core5.annotation.Contract;
37 import org.apache.hc.core5.annotation.ThreadingBehavior;
38 import org.apache.hc.core5.http.Header;
39 import org.apache.hc.core5.http.HttpException;
40 import org.apache.hc.core5.http.HttpHeaders;
41 import org.apache.hc.core5.http.HttpRequest;
42 import org.apache.hc.core5.http.HttpResponse;
43 import org.apache.hc.core5.http.HttpStatus;
44 import org.apache.hc.core5.http.ProtocolException;
45 import org.apache.hc.core5.http.protocol.HttpContext;
46 import org.apache.hc.core5.net.URIBuilder;
47 import org.apache.hc.core5.util.Args;
48
49
50
51
52
53
54 @Contract(threading = ThreadingBehavior.STATELESS)
55 public class DefaultRedirectStrategy implements RedirectStrategy {
56
57
58
59
60 public static final DefaultRedirectStrategy INSTANCE = new DefaultRedirectStrategy();
61
62 @Override
63 public boolean isRedirected(
64 final HttpRequest request,
65 final HttpResponse response,
66 final HttpContext context) throws ProtocolException {
67 Args.notNull(request, "HTTP request");
68 Args.notNull(response, "HTTP response");
69
70 if (!response.containsHeader(HttpHeaders.LOCATION)) {
71 return false;
72 }
73 final int statusCode = response.getCode();
74 switch (statusCode) {
75 case HttpStatus.SC_MOVED_PERMANENTLY:
76 case HttpStatus.SC_MOVED_TEMPORARILY:
77 case HttpStatus.SC_SEE_OTHER:
78 case HttpStatus.SC_TEMPORARY_REDIRECT:
79 case HttpStatus.SC_PERMANENT_REDIRECT:
80 return true;
81 default:
82 return false;
83 }
84 }
85
86 @Override
87 public URI getLocationURI(
88 final HttpRequest request,
89 final HttpResponse response,
90 final HttpContext context) throws HttpException {
91 Args.notNull(request, "HTTP request");
92 Args.notNull(response, "HTTP response");
93 Args.notNull(context, "HTTP context");
94
95
96 final Header locationHeader = response.getFirstHeader(HttpHeaders.LOCATION);
97 if (locationHeader == null) {
98 throw new HttpException("Redirect location is missing");
99 }
100 final String location = locationHeader.getValue();
101 URI uri = createLocationURI(location);
102 try {
103 if (!uri.isAbsolute()) {
104
105 uri = URIUtils.resolve(request.getUri(), uri);
106 }
107 } catch (final URISyntaxException ex) {
108 throw new ProtocolException(ex.getMessage(), ex);
109 }
110
111 return uri;
112 }
113
114
115
116
117 protected URI createLocationURI(final String location) throws ProtocolException {
118 try {
119 final URIBuilder b = new URIBuilder(new URI(location).normalize());
120 final String host = b.getHost();
121 if (host != null) {
122 b.setHost(host.toLowerCase(Locale.ROOT));
123 }
124 if (b.isPathEmpty()) {
125 b.setPathSegments("");
126 }
127 return b.build();
128 } catch (final URISyntaxException ex) {
129 throw new ProtocolException("Invalid redirect URI: " + location, ex);
130 }
131 }
132
133 }