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 public static final DefaultRedirectStrategy INSTANCE = new DefaultRedirectStrategy();
58
59 @Override
60 public boolean isRedirected(
61 final HttpRequest request,
62 final HttpResponse response,
63 final HttpContext context) throws ProtocolException {
64 Args.notNull(request, "HTTP request");
65 Args.notNull(response, "HTTP response");
66
67 if (!response.containsHeader(HttpHeaders.LOCATION)) {
68 return false;
69 }
70 final int statusCode = response.getCode();
71 switch (statusCode) {
72 case HttpStatus.SC_MOVED_PERMANENTLY:
73 case HttpStatus.SC_MOVED_TEMPORARILY:
74 case HttpStatus.SC_SEE_OTHER:
75 case HttpStatus.SC_TEMPORARY_REDIRECT:
76 case HttpStatus.SC_PERMANENT_REDIRECT:
77 return true;
78 default:
79 return false;
80 }
81 }
82
83 @Override
84 public URI getLocationURI(
85 final HttpRequest request,
86 final HttpResponse response,
87 final HttpContext context) throws HttpException {
88 Args.notNull(request, "HTTP request");
89 Args.notNull(response, "HTTP response");
90 Args.notNull(context, "HTTP context");
91
92
93 final Header locationHeader = response.getFirstHeader(HttpHeaders.LOCATION);
94 if (locationHeader == null) {
95 throw new HttpException("Redirect location is missing");
96 }
97 final String location = locationHeader.getValue();
98 URI uri = createLocationURI(location);
99 try {
100 if (!uri.isAbsolute()) {
101
102 uri = URIUtils.resolve(request.getUri(), uri);
103 }
104 } catch (final URISyntaxException ex) {
105 throw new ProtocolException(ex.getMessage(), ex);
106 }
107
108 return uri;
109 }
110
111
112
113
114 protected URI createLocationURI(final String location) throws ProtocolException {
115 try {
116 final URIBuilder b = new URIBuilder(new URI(location).normalize());
117 final String host = b.getHost();
118 if (host != null) {
119 b.setHost(host.toLowerCase(Locale.ROOT));
120 }
121 if (b.isPathEmpty()) {
122 b.setPathSegments("");
123 }
124 return b.build();
125 } catch (final URISyntaxException ex) {
126 throw new ProtocolException("Invalid redirect URI: " + location, ex);
127 }
128 }
129
130 }