+45
-13
lines changedFilter options
+45
-13
lines changed Original file line number Diff line number Diff line change
@@ -39,6 +39,7 @@
39
39
import java.io.UncheckedIOException;
40
40
import java.net.Authenticator;
41
41
import java.net.PasswordAuthentication;
42
+
import java.net.ProtocolException;
42
43
import java.net.Proxy;
43
44
import java.net.ProxySelector;
44
45
import java.net.SocketAddress;
@@ -62,8 +63,6 @@
62
63
import java.util.logging.Level;
63
64
import java.util.logging.Logger;
64
65
65
-
import static java.net.http.HttpClient.Redirect.ALWAYS;
66
-
67
66
public class JdkHttpClient implements HttpClient {
68
67
public static final Logger LOG = Logger.getLogger(JdkHttpClient.class.getName());
69
68
private final JdkHttpMessages messages;
@@ -82,7 +81,7 @@ public class JdkHttpClient implements HttpClient {
82
81
83
82
java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder()
84
83
.connectTimeout(config.connectionTimeout())
85
-
.followRedirects(ALWAYS)
84
+
.followRedirects(java.net.http.HttpClient.Redirect.NEVER)
86
85
.executor(executorService);
87
86
88
87
Credentials credentials = config.credentials();
@@ -289,7 +288,42 @@ public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
289
288
290
289
BodyHandler<byte[]> byteHandler = BodyHandlers.ofByteArray();
291
290
try {
292
-
return messages.createResponse(client.send(messages.createRequest(req), byteHandler));
291
+
URI rawUri = messages.getRawUri(req);
292
+
293
+
// We need a custom handling of redirects to:
294
+
// - increase the maximum number of retries to 100
295
+
// - avoid a downgrade of POST requests, see the javadoc of j.n.h.HttpClient.Redirect
296
+
// - not run into https://bugs.openjdk.org/browse/JDK-8304701
297
+
for (int i = 0; i < 100; i++) {
298
+
java.net.http.HttpRequest request = messages.createRequest(req, rawUri);
299
+
java.net.http.HttpResponse<byte[]> response = client.send(request, byteHandler);
300
+
301
+
switch (response.statusCode()) {
302
+
case 301:
303
+
case 302:
304
+
case 303:
305
+
case 307:
306
+
case 308:
307
+
URI location = rawUri.resolve(response.headers()
308
+
.firstValue("location")
309
+
.orElseThrow(() -> new ProtocolException(
310
+
"HTTP " + response.statusCode() + " without 'location' header set"
311
+
)));
312
+
313
+
if ("https".equalsIgnoreCase(rawUri.getScheme()) && !"https".equalsIgnoreCase(location.getScheme()) ) {
314
+
throw new SecurityException("Downgrade from secure to insecure connection.");
315
+
} else if ("wss".equalsIgnoreCase(rawUri.getScheme()) && !"wss".equalsIgnoreCase(location.getScheme()) ) {
316
+
throw new SecurityException("Downgrade from secure to insecure connection.");
317
+
}
318
+
319
+
rawUri = location;
320
+
continue;
321
+
default:
322
+
return messages.createResponse(response);
323
+
}
324
+
}
325
+
326
+
throw new ProtocolException("Too many redirects: 101");
293
327
} catch (HttpTimeoutException e) {
294
328
throw new TimeoutException(e);
295
329
} catch (IOException e) {
Original file line number Diff line number Diff line change
@@ -45,8 +45,8 @@ public JdkHttpMessages(ClientConfig config) {
45
45
this.config = Objects.requireNonNull(config, "Client config");
46
46
}
47
47
48
-
public java.net.http.HttpRequest createRequest(HttpRequest req) {
49
-
String rawUrl = getRawUrl(config.baseUri(), req.getUri());
48
+
public java.net.http.HttpRequest createRequest(HttpRequest req, URI rawUri) {
49
+
String rawUrl = rawUri.toString();
50
50
51
51
// Add query string if necessary
52
52
String queryString = StreamSupport.stream(req.getQueryParameterNames().spliterator(), false)
@@ -129,20 +129,18 @@ private BodyPublisher notChunkingBodyPublisher(HttpRequest req) {
129
129
return BodyPublishers.fromPublisher(chunking, Long.parseLong(length));
130
130
}
131
131
132
-
private String getRawUrl(URI baseUrl, String uri) {
132
+
public URI getRawUri(HttpRequest req) {
133
+
URI baseUrl = config.baseUri();
134
+
String uri = req.getUri();
133
135
String rawUrl;
136
+
134
137
if (uri.startsWith("ws://") || uri.startsWith("wss://") ||
135
-
uri.startsWith("http://") || uri.startsWith("https://")) {
138
+
uri.startsWith("http://") || uri.startsWith("https://")) {
136
139
rawUrl = uri;
137
140
} else {
138
141
rawUrl = baseUrl.toString().replaceAll("/$", "") + uri;
139
142
}
140
143
141
-
return rawUrl;
142
-
}
143
-
144
-
public URI getRawUri(HttpRequest req) {
145
-
String rawUrl = getRawUrl(config.baseUri(), req.getUri());
146
144
return URI.create(rawUrl);
147
145
}
148
146
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4