1
+
package org.openqa.selenium.remote.http.jdk;
2
+
3
+
import com.google.auto.service.AutoService;
4
+
import org.openqa.selenium.Credentials;
5
+
import org.openqa.selenium.TimeoutException;
6
+
import org.openqa.selenium.UsernameAndPassword;
7
+
import org.openqa.selenium.remote.http.BinaryMessage;
8
+
import org.openqa.selenium.remote.http.ClientConfig;
9
+
import org.openqa.selenium.remote.http.CloseMessage;
10
+
import org.openqa.selenium.remote.http.HttpClient;
11
+
import org.openqa.selenium.remote.http.HttpClientName;
12
+
import org.openqa.selenium.remote.http.HttpRequest;
13
+
import org.openqa.selenium.remote.http.HttpResponse;
14
+
import org.openqa.selenium.remote.http.Message;
15
+
import org.openqa.selenium.remote.http.TextMessage;
16
+
import org.openqa.selenium.remote.http.WebSocket;
17
+
18
+
import java.io.IOException;
19
+
import java.io.InputStream;
20
+
import java.io.UncheckedIOException;
21
+
import java.net.Authenticator;
22
+
import java.net.PasswordAuthentication;
23
+
import java.net.Proxy;
24
+
import java.net.ProxySelector;
25
+
import java.net.SocketAddress;
26
+
import java.net.URI;
27
+
import java.net.URISyntaxException;
28
+
import java.net.http.HttpResponse.BodyHandler;
29
+
import java.net.http.HttpResponse.BodyHandlers;
30
+
import java.net.http.HttpTimeoutException;
31
+
import java.nio.ByteBuffer;
32
+
import java.util.List;
33
+
import java.util.Objects;
34
+
import java.util.concurrent.CompletableFuture;
35
+
import java.util.concurrent.CompletionStage;
36
+
37
+
import static java.net.http.HttpClient.Redirect.ALWAYS;
38
+
39
+
public class JdkHttpClient implements HttpClient {
40
+
private final JdkHttpMessages messages;
41
+
private final java.net.http.HttpClient client;
42
+
43
+
JdkHttpClient(ClientConfig config) {
44
+
Objects.requireNonNull(config, "Client config must be set");
45
+
46
+
this.messages = new JdkHttpMessages(config);
47
+
48
+
java.net.http.HttpClient.Builder builder = java.net.http.HttpClient.newBuilder()
49
+
.connectTimeout(config.connectionTimeout())
50
+
.followRedirects(ALWAYS);
51
+
52
+
53
+
Credentials credentials = config.credentials();
54
+
if (credentials != null) {
55
+
if (!(credentials instanceof UsernameAndPassword)) {
56
+
throw new IllegalArgumentException("Credentials must be a user name and password: " + credentials);
57
+
}
58
+
UsernameAndPassword uap = (UsernameAndPassword) credentials;
59
+
Authenticator authenticator = new Authenticator() {
60
+
@Override
61
+
protected PasswordAuthentication getPasswordAuthentication() {
62
+
return new PasswordAuthentication(uap.username(), uap.password().toCharArray());
63
+
}
64
+
};
65
+
builder = builder.authenticator(authenticator);
66
+
}
67
+
68
+
Proxy proxy = config.proxy();
69
+
if (proxy != null) {
70
+
ProxySelector proxySelector = new ProxySelector() {
71
+
@Override
72
+
public List<Proxy> select(URI uri) {
73
+
if (proxy == null) {
74
+
return List.of();
75
+
}
76
+
if (uri.getScheme().toLowerCase().startsWith("http")) {
77
+
return List.of(proxy);
78
+
}
79
+
return List.of();
80
+
}
81
+
82
+
@Override
83
+
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
84
+
// Do nothing
85
+
}
86
+
};
87
+
builder = builder.proxy(proxySelector);
88
+
}
89
+
90
+
this.client = builder.build();
91
+
}
92
+
93
+
@Override
94
+
public WebSocket openSocket(HttpRequest request, WebSocket.Listener listener) {
95
+
URI uri = getWebSocketUri(request);
96
+
97
+
CompletableFuture<java.net.http.WebSocket> webSocketCompletableFuture =
98
+
client.newWebSocketBuilder().buildAsync(
99
+
uri,
100
+
new java.net.http.WebSocket.Listener() {
101
+
102
+
@Override
103
+
public CompletionStage<?> onText(java.net.http.WebSocket webSocket, CharSequence data, boolean last) {
104
+
listener.onText(data);
105
+
return null;
106
+
}
107
+
108
+
@Override
109
+
public CompletionStage<?> onBinary(java.net.http.WebSocket webSocket, ByteBuffer data, boolean last) {
110
+
byte[] ary = new byte[data.remaining()];
111
+
data.get(ary, 0, ary.length);
112
+
113
+
listener.onBinary(ary);
114
+
return null;
115
+
}
116
+
117
+
@Override
118
+
public CompletionStage<?> onClose(java.net.http.WebSocket webSocket, int statusCode, String reason) {
119
+
listener.onClose(statusCode, reason);
120
+
return null;
121
+
}
122
+
123
+
@Override
124
+
public void onError(java.net.http.WebSocket webSocket, Throwable error) {
125
+
listener.onError(error);
126
+
}
127
+
});
128
+
129
+
java.net.http.WebSocket underlyingSocket = webSocketCompletableFuture.join();
130
+
131
+
return new WebSocket() {
132
+
@Override
133
+
public WebSocket send(Message message) {
134
+
if (message instanceof BinaryMessage) {
135
+
BinaryMessage binaryMessage = (BinaryMessage) message;
136
+
underlyingSocket.sendBinary(ByteBuffer.wrap(binaryMessage.data()), true);
137
+
} else if (message instanceof TextMessage) {
138
+
TextMessage textMessage = (TextMessage) message;
139
+
underlyingSocket.sendText(textMessage.text(), true);
140
+
} else if (message instanceof CloseMessage) {
141
+
CloseMessage closeMessage = (CloseMessage) message;
142
+
underlyingSocket.sendClose(closeMessage.code(), closeMessage.reason());
143
+
} else {
144
+
throw new IllegalArgumentException("Unsupport message type: " + message);
145
+
}
146
+
return this;
147
+
}
148
+
149
+
@Override
150
+
public void close() {
151
+
underlyingSocket.sendClose(1000, "WebDriver closing socket");
152
+
}
153
+
};
154
+
}
155
+
156
+
private URI getWebSocketUri(HttpRequest request) {
157
+
URI uri = messages.createRequest(request).uri();
158
+
if ("http".equalsIgnoreCase(uri.getScheme())) {
159
+
try {
160
+
uri = new URI("ws", uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
161
+
} catch (URISyntaxException e) {
162
+
throw new RuntimeException(e);
163
+
}
164
+
} else if ("https".equalsIgnoreCase(uri.getScheme())) {
165
+
try {
166
+
uri = new URI("wss", uri.getUserInfo(), uri.getHost(), uri.getPort(), uri.getPath(), uri.getQuery(), uri.getFragment());
167
+
} catch (URISyntaxException e) {
168
+
throw new RuntimeException(e);
169
+
}
170
+
}
171
+
return uri;
172
+
}
173
+
174
+
@Override
175
+
public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
176
+
Objects.requireNonNull(req, "Request");
177
+
BodyHandler<InputStream> streamHandler = BodyHandlers.ofInputStream();
178
+
try {
179
+
return messages.createResponse(client.send(messages.createRequest(req), streamHandler));
180
+
} catch (HttpTimeoutException e) {
181
+
throw new TimeoutException(e);
182
+
} catch (IOException e) {
183
+
throw new UncheckedIOException(e);
184
+
} catch (InterruptedException e) {
185
+
Thread.currentThread().interrupt();
186
+
throw new RuntimeException(e);
187
+
}
188
+
}
189
+
190
+
@AutoService(HttpClient.Factory.class)
191
+
@HttpClientName("jdk-http-client")
192
+
public static class Factory implements HttpClient.Factory {
193
+
194
+
@Override
195
+
public HttpClient createClient(ClientConfig config) {
196
+
Objects.requireNonNull(config, "Client config must be set");
197
+
return new JdkHttpClient(config);
198
+
}
199
+
}
200
+
}
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