diff --git a/java/src/org/openqa/selenium/remote/BUILD.bazel b/java/src/org/openqa/selenium/remote/BUILD.bazel
index b4e98e1f9561a..4556e6c86192e 100644
--- a/java/src/org/openqa/selenium/remote/BUILD.bazel
+++ b/java/src/org/openqa/selenium/remote/BUILD.bazel
@@ -55,7 +55,7 @@ java_library(
"//java/src/org/openqa/selenium/json",
"//java/src/org/openqa/selenium/manager",
"//java/src/org/openqa/selenium/os",
- "//java/src/org/openqa/selenium/remote/http/netty",
+ "//java/src/org/openqa/selenium/remote/http/jdk",
"//java/src/org/openqa/selenium/remote/tracing",
"//java/src/org/openqa/selenium/remote/tracing/opentelemetry",
"//java/src/org/openqa/selenium/support/decorators",
diff --git a/java/src/org/openqa/selenium/remote/http/HttpClient.java b/java/src/org/openqa/selenium/remote/http/HttpClient.java
index 926051306c07b..ce593c9b82132 100644
--- a/java/src/org/openqa/selenium/remote/http/HttpClient.java
+++ b/java/src/org/openqa/selenium/remote/http/HttpClient.java
@@ -71,7 +71,7 @@ static Factory create(String name) {
*
{@see create}
*/
static Factory createDefault() {
- return create(System.getProperty("webdriver.http.factory", "netty"));
+ return create("jdk-http-client");
}
/**
diff --git a/java/src/org/openqa/selenium/remote/http/jdk/BUILD.bazel b/java/src/org/openqa/selenium/remote/http/jdk/BUILD.bazel
index 4679882dcdbc7..10ffa44fcb45d 100644
--- a/java/src/org/openqa/selenium/remote/http/jdk/BUILD.bazel
+++ b/java/src/org/openqa/selenium/remote/http/jdk/BUILD.bazel
@@ -1,17 +1,12 @@
-load("//java:defs.bzl", "java_export")
-load("//java:version.bzl", "SE_VERSION")
+load("@rules_jvm_external//:defs.bzl", "artifact")
+load("//java:defs.bzl", "java_library")
-java_export(
+java_library(
name = "jdk",
srcs = glob(["*.java"]),
- javacopts = [
- "--release",
- "11", # Deliberately targeting Java 11 for widest possible support
- ],
- maven_coordinates = "org.seleniumhq.selenium:selenium-http-jdk-client:%s" % SE_VERSION,
- pom_template = "//java/src/org/openqa/selenium:template-pom",
visibility = [
- "//visibility:public",
+ "//java/src/org/openqa/selenium/remote:__pkg__",
+ "//java/test/org/openqa/selenium/remote/http:__subpackages__",
],
deps = [
"//java:auto-service",
diff --git a/java/src/org/openqa/selenium/remote/http/netty/BUILD.bazel b/java/src/org/openqa/selenium/remote/http/netty/BUILD.bazel
deleted file mode 100644
index 21fbc3f7518cf..0000000000000
--- a/java/src/org/openqa/selenium/remote/http/netty/BUILD.bazel
+++ /dev/null
@@ -1,31 +0,0 @@
-load("@rules_jvm_external//:defs.bzl", "artifact")
-load("//java:defs.bzl", "java_library")
-
-java_library(
- name = "netty",
- srcs = glob(["*.java"]),
- visibility = [
- "//java/src/org/openqa/selenium/remote:__pkg__",
- "//java/test/org/openqa/selenium/remote/http:__subpackages__",
- ],
- deps = [
- "//java:auto-service",
- "//java/src/org/openqa/selenium:core",
- "//java/src/org/openqa/selenium/remote/http",
- artifact("com.google.guava:guava"),
- # artifact("com.typesafe.netty:netty-reactive-streams"),
- artifact("org.asynchttpclient:async-http-client"),
- artifact("io.netty:netty-buffer"),
- artifact("io.netty:netty-codec-http"),
- artifact("io.netty:netty-transport"),
- artifact("io.netty:netty-transport-classes-epoll"),
- artifact("io.netty:netty-transport-classes-kqueue"),
- artifact("io.netty:netty-transport-native-epoll"),
- artifact("io.netty:netty-transport-native-epoll-linux-x86_64"),
- artifact("io.netty:netty-transport-native-kqueue"),
- artifact("io.netty:netty-transport-native-kqueue-osx-aarch_64"),
- artifact("io.netty:netty-transport-native-kqueue-osx-x86_64"),
- artifact("io.netty:netty-transport-native-unix-common"),
- artifact("io.netty:netty-common"),
- ],
-)
diff --git a/java/src/org/openqa/selenium/remote/http/netty/NettyClient.java b/java/src/org/openqa/selenium/remote/http/netty/NettyClient.java
deleted file mode 100644
index 363690847da5b..0000000000000
--- a/java/src/org/openqa/selenium/remote/http/netty/NettyClient.java
+++ /dev/null
@@ -1,127 +0,0 @@
-// Licensed to the Software Freedom Conservancy (SFC) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The SFC licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.openqa.selenium.remote.http.netty;
-
-import com.google.auto.service.AutoService;
-import io.netty.util.HashedWheelTimer;
-import io.netty.util.Timer;
-import io.netty.util.concurrent.DefaultThreadFactory;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.function.BiFunction;
-import org.asynchttpclient.AsyncHttpClient;
-import org.asynchttpclient.DefaultAsyncHttpClientConfig;
-import org.asynchttpclient.Dsl;
-import org.asynchttpclient.config.AsyncHttpClientConfigDefaults;
-import org.openqa.selenium.internal.Require;
-import org.openqa.selenium.remote.http.ClientConfig;
-import org.openqa.selenium.remote.http.HttpClient;
-import org.openqa.selenium.remote.http.HttpClientName;
-import org.openqa.selenium.remote.http.HttpHandler;
-import org.openqa.selenium.remote.http.HttpRequest;
-import org.openqa.selenium.remote.http.HttpResponse;
-import org.openqa.selenium.remote.http.WebSocket;
-
-public class NettyClient implements HttpClient {
-
- private static final Timer TIMER;
- private static final AsyncHttpClient client = createHttpClient(ClientConfig.defaultConfig());
-
- static {
- ThreadFactory threadFactory = new DefaultThreadFactory("netty-client-timer", true);
- TIMER =
- new HashedWheelTimer(
- threadFactory,
- AsyncHttpClientConfigDefaults.defaultHashedWheelTimerTickDuration(),
- TimeUnit.MILLISECONDS,
- AsyncHttpClientConfigDefaults.defaultHashedWheelTimerSize());
- }
-
- private final ClientConfig config;
- private final HttpHandler handler;
- private final BiFunction toWebSocket;
-
- private NettyClient(ClientConfig config) {
- this.config = Require.nonNull("HTTP client config", config);
- this.handler = new NettyHttpHandler(config, client);
- this.toWebSocket = NettyWebSocket.create(config, client);
- }
-
- /**
- * Converts a long to an int, clamping the maximum and minimum values to fit in an integer without
- * overflowing.
- */
- static int toClampedInt(long value) {
- return (int) Math.max(Integer.MIN_VALUE, Math.min(Integer.MAX_VALUE, value));
- }
-
- private static AsyncHttpClient createHttpClient(ClientConfig config) {
- DefaultAsyncHttpClientConfig.Builder builder =
- new DefaultAsyncHttpClientConfig.Builder()
- .setThreadFactory(new DefaultThreadFactory("AsyncHttpClient", true))
- .setUseInsecureTrustManager(true)
- .setAggregateWebSocketFrameFragments(true)
- .setWebSocketMaxBufferSize(Integer.MAX_VALUE)
- .setWebSocketMaxFrameSize(Integer.MAX_VALUE)
- .setNettyTimer(TIMER)
- .setRequestTimeout(toClampedInt(config.readTimeout().toMillis()))
- .setConnectTimeout(toClampedInt(config.connectionTimeout().toMillis()))
- .setReadTimeout(toClampedInt(config.readTimeout().toMillis()))
- .setFollowRedirect(true)
- .setMaxRedirects(100)
- .setUseProxyProperties(true)
- .setUseProxySelector(true)
- .setMaxRequestRetry(0);
-
- return Dsl.asyncHttpClient(builder);
- }
-
- @Override
- public HttpResponse execute(HttpRequest request) {
- return handler.execute(request);
- }
-
- @Override
- public WebSocket openSocket(HttpRequest request, WebSocket.Listener listener) {
- Require.nonNull("Request to send", request);
- Require.nonNull("WebSocket listener", listener);
-
- return toWebSocket.apply(request, listener);
- }
-
- @Override
- public void close() {
- // no-op -- closing the client when the JVM shuts down
- }
-
- @AutoService(HttpClient.Factory.class)
- @HttpClientName("netty")
- public static class Factory implements HttpClient.Factory {
-
- @Override
- public HttpClient createClient(ClientConfig config) {
- Require.nonNull("Client config", config);
-
- if (config.baseUri() != null && "unix".equals(config.baseUri().getScheme())) {
- return new NettyDomainSocketClient(config);
- }
-
- return new NettyClient(config);
- }
- }
-}
diff --git a/java/src/org/openqa/selenium/remote/http/netty/NettyDomainSocketClient.java b/java/src/org/openqa/selenium/remote/http/netty/NettyDomainSocketClient.java
deleted file mode 100644
index 8bceb93195b69..0000000000000
--- a/java/src/org/openqa/selenium/remote/http/netty/NettyDomainSocketClient.java
+++ /dev/null
@@ -1,234 +0,0 @@
-// Licensed to the Software Freedom Conservancy (SFC) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The SFC licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.openqa.selenium.remote.http.netty;
-
-import static java.net.HttpURLConnection.HTTP_INTERNAL_ERROR;
-import static java.nio.charset.StandardCharsets.UTF_8;
-import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static org.openqa.selenium.remote.http.Contents.bytes;
-import static org.openqa.selenium.remote.http.Contents.utf8String;
-
-import com.google.common.base.Joiner;
-import com.google.common.base.Throwables;
-import com.google.common.io.ByteStreams;
-import io.netty.bootstrap.Bootstrap;
-import io.netty.buffer.ByteBufInputStream;
-import io.netty.buffer.Unpooled;
-import io.netty.channel.Channel;
-import io.netty.channel.ChannelFuture;
-import io.netty.channel.ChannelHandlerContext;
-import io.netty.channel.ChannelInitializer;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.SimpleChannelInboundHandler;
-import io.netty.channel.epoll.Epoll;
-import io.netty.channel.epoll.EpollDomainSocketChannel;
-import io.netty.channel.epoll.EpollEventLoopGroup;
-import io.netty.channel.kqueue.KQueue;
-import io.netty.channel.kqueue.KQueueDomainSocketChannel;
-import io.netty.channel.kqueue.KQueueEventLoopGroup;
-import io.netty.channel.unix.DomainSocketAddress;
-import io.netty.channel.unix.UnixChannel;
-import io.netty.handler.codec.http.DefaultFullHttpRequest;
-import io.netty.handler.codec.http.FullHttpResponse;
-import io.netty.handler.codec.http.HttpClientCodec;
-import io.netty.handler.codec.http.HttpContentDecompressor;
-import io.netty.handler.codec.http.HttpHeaderNames;
-import io.netty.handler.codec.http.HttpHeaderValues;
-import io.netty.handler.codec.http.HttpMethod;
-import io.netty.handler.codec.http.HttpObjectAggregator;
-import io.netty.handler.codec.http.HttpVersion;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.UncheckedIOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLEncoder;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.atomic.AtomicReference;
-import org.openqa.selenium.internal.Require;
-import org.openqa.selenium.remote.http.AddSeleniumUserAgent;
-import org.openqa.selenium.remote.http.ClientConfig;
-import org.openqa.selenium.remote.http.HttpClient;
-import org.openqa.selenium.remote.http.HttpRequest;
-import org.openqa.selenium.remote.http.HttpResponse;
-import org.openqa.selenium.remote.http.RemoteCall;
-import org.openqa.selenium.remote.http.WebSocket;
-
-class NettyDomainSocketClient extends RemoteCall implements HttpClient {
-
- private final EventLoopGroup eventLoopGroup;
- private final Class extends Channel> channelClazz;
- private final String path;
-
- public NettyDomainSocketClient(ClientConfig config) {
- super(config);
- URI uri = config.baseUri();
- Require.argument("URI scheme", uri.getScheme()).equalTo("unix");
-
- if (Epoll.isAvailable()) {
- this.eventLoopGroup = new EpollEventLoopGroup();
- this.channelClazz = EpollDomainSocketChannel.class;
- } else if (KQueue.isAvailable()) {
- this.eventLoopGroup = new KQueueEventLoopGroup();
- this.channelClazz = KQueueDomainSocketChannel.class;
- } else {
- throw new IllegalStateException("No native library for unix domain sockets is available");
- }
-
- this.path = uri.getPath();
- }
-
- @Override
- public HttpResponse execute(HttpRequest req) throws UncheckedIOException {
- Require.nonNull("Request to send", req);
-
- AtomicReference outRef = new AtomicReference<>();
- CountDownLatch latch = new CountDownLatch(1);
- Channel channel = createChannel(outRef, latch);
-
- StringBuilder uri = new StringBuilder(req.getUri());
- List queryPairs = new ArrayList<>();
- req.getQueryParameterNames()
- .forEach(
- name ->
- req.getQueryParameters(name)
- .forEach(
- value -> {
- try {
- queryPairs.add(
- URLEncoder.encode(name, UTF_8.toString())
- + "="
- + URLEncoder.encode(value, UTF_8.toString()));
- } catch (UnsupportedEncodingException e) {
- Thread.currentThread().interrupt();
- throw new UncheckedIOException(e);
- }
- }));
- if (!queryPairs.isEmpty()) {
- uri.append("?");
- Joiner.on('&').appendTo(uri, queryPairs);
- }
-
- byte[] bytes = bytes(req.getContent());
-
- DefaultFullHttpRequest fullRequest =
- new DefaultFullHttpRequest(
- HttpVersion.HTTP_1_1,
- HttpMethod.valueOf(req.getMethod().toString()),
- uri.toString(),
- Unpooled.wrappedBuffer(bytes));
- req.forEachHeader(fullRequest.headers()::add);
- if (req.getHeader("User-Agent") == null) {
- fullRequest.headers().set("User-Agent", AddSeleniumUserAgent.USER_AGENT);
- }
- fullRequest.headers().set(HttpHeaderNames.HOST, "localhost");
- fullRequest.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE);
- fullRequest.headers().set(HttpHeaderNames.CONTENT_LENGTH, bytes.length);
-
- ChannelFuture future = channel.writeAndFlush(fullRequest);
-
- try {
- future.get();
- channel.closeFuture().sync();
- } catch (InterruptedException | ExecutionException e) {
- Thread.currentThread().interrupt();
- throw new UncheckedIOException(new IOException(e));
- }
-
- try {
- if (!latch.await(getConfig().readTimeout().toMillis(), MILLISECONDS)) {
- throw new UncheckedIOException(new IOException("Timed out waiting for response"));
- }
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new RuntimeException(e);
- }
-
- return outRef.get();
- }
-
- @Override
- public WebSocket openSocket(HttpRequest request, WebSocket.Listener listener) {
- throw new UnsupportedOperationException("openSocket");
- }
-
- private Channel createChannel(AtomicReference outRef, CountDownLatch latch) {
- Bootstrap bootstrap =
- new Bootstrap()
- .group(eventLoopGroup)
- .channel(channelClazz)
- .handler(
- new ChannelInitializer() {
- @Override
- public void initChannel(UnixChannel ch) {
- ch.pipeline()
- .addLast(new HttpClientCodec())
- .addLast(new HttpContentDecompressor())
- .addLast(new HttpObjectAggregator(Integer.MAX_VALUE))
- .addLast(
- new SimpleChannelInboundHandler() {
- @Override
- public void channelRead0(
- ChannelHandlerContext ctx, FullHttpResponse msg) {
- HttpResponse res =
- new HttpResponse().setStatus(msg.status().code());
- msg.headers()
- .forEach(
- entry -> res.addHeader(entry.getKey(), entry.getValue()));
-
- try (InputStream is = new ByteBufInputStream(msg.content());
- ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
- ByteStreams.copy(is, bos);
- res.setContent(bytes(bos.toByteArray()));
- outRef.set(res);
- latch.countDown();
- } catch (IOException e) {
- outRef.set(
- new HttpResponse()
- .setStatus(HTTP_INTERNAL_ERROR)
- .setContent(
- utf8String(Throwables.getStackTraceAsString(e))));
- latch.countDown();
- }
- }
-
- @Override
- public void exceptionCaught(
- ChannelHandlerContext ctx, Throwable cause) {
- outRef.set(
- new HttpResponse()
- .setStatus(HTTP_INTERNAL_ERROR)
- .setContent(
- utf8String(Throwables.getStackTraceAsString(cause))));
- latch.countDown();
- }
- });
- }
- });
- try {
- return bootstrap.connect(new DomainSocketAddress(path)).sync().channel();
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new RuntimeException(e);
- }
- }
-}
diff --git a/java/src/org/openqa/selenium/remote/http/netty/NettyHttpHandler.java b/java/src/org/openqa/selenium/remote/http/netty/NettyHttpHandler.java
deleted file mode 100644
index b5fd588eeb22f..0000000000000
--- a/java/src/org/openqa/selenium/remote/http/netty/NettyHttpHandler.java
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed to the Software Freedom Conservancy (SFC) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The SFC licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.openqa.selenium.remote.http.netty;
-
-import java.io.IOException;
-import java.io.UncheckedIOException;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import org.asynchttpclient.AsyncHttpClient;
-import org.asynchttpclient.Response;
-import org.openqa.selenium.internal.Require;
-import org.openqa.selenium.remote.http.ClientConfig;
-import org.openqa.selenium.remote.http.HttpHandler;
-import org.openqa.selenium.remote.http.HttpRequest;
-import org.openqa.selenium.remote.http.HttpResponse;
-import org.openqa.selenium.remote.http.RemoteCall;
-
-public class NettyHttpHandler extends RemoteCall {
-
- private final HttpHandler handler;
- private final AsyncHttpClient client;
-
- public NettyHttpHandler(ClientConfig config, AsyncHttpClient client) {
- super(config);
- this.client = client;
- this.handler = config.filter().andFinally(this::makeCall);
- }
-
- @Override
- public HttpResponse execute(HttpRequest request) {
- return handler.execute(request);
- }
-
- private HttpResponse makeCall(HttpRequest request) {
- Require.nonNull("Request", request);
-
- Future whenResponse =
- client.executeRequest(NettyMessages.toNettyRequest(getConfig(), request));
-
- try {
- Response response =
- whenResponse.get(getConfig().readTimeout().toMillis(), TimeUnit.MILLISECONDS);
- return NettyMessages.toSeleniumResponse(response);
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- throw new RuntimeException("NettyHttpHandler request interrupted", e);
- } catch (TimeoutException e) {
- throw new org.openqa.selenium.TimeoutException(e);
- } catch (ExecutionException e) {
- Throwable cause = e.getCause();
- if (cause instanceof UncheckedIOException) {
- throw (UncheckedIOException) cause;
- }
-
- if (cause instanceof IOException) {
- throw new UncheckedIOException((IOException) cause);
- }
-
- throw new RuntimeException("NettyHttpHandler request execution error", e);
- }
- }
-}
diff --git a/java/src/org/openqa/selenium/remote/http/netty/NettyMessages.java b/java/src/org/openqa/selenium/remote/http/netty/NettyMessages.java
deleted file mode 100644
index 14af46f076171..0000000000000
--- a/java/src/org/openqa/selenium/remote/http/netty/NettyMessages.java
+++ /dev/null
@@ -1,146 +0,0 @@
-// Licensed to the Software Freedom Conservancy (SFC) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The SFC licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.openqa.selenium.remote.http.netty;
-
-import static org.asynchttpclient.Dsl.request;
-import static org.openqa.selenium.remote.http.Contents.empty;
-import static org.openqa.selenium.remote.http.Contents.memoize;
-import static org.openqa.selenium.remote.http.netty.NettyClient.toClampedInt;
-
-import com.google.common.base.Strings;
-import java.net.InetSocketAddress;
-import java.net.URI;
-import org.asynchttpclient.Dsl;
-import org.asynchttpclient.Realm;
-import org.asynchttpclient.Request;
-import org.asynchttpclient.RequestBuilder;
-import org.asynchttpclient.Response;
-import org.asynchttpclient.proxy.ProxyServer;
-import org.openqa.selenium.Credentials;
-import org.openqa.selenium.UsernameAndPassword;
-import org.openqa.selenium.remote.http.AddSeleniumUserAgent;
-import org.openqa.selenium.remote.http.ClientConfig;
-import org.openqa.selenium.remote.http.HttpMethod;
-import org.openqa.selenium.remote.http.HttpRequest;
-import org.openqa.selenium.remote.http.HttpResponse;
-
-class NettyMessages {
-
- private NettyMessages() {
- // Utility classes.
- }
-
- protected static Request toNettyRequest(ClientConfig config, HttpRequest request) {
-
- URI baseUrl = config.baseUri();
- int timeout = toClampedInt(config.readTimeout().toMillis());
- Credentials credentials = config.credentials();
-
- String rawUrl = getRawUrl(baseUrl, request.getUri());
-
- RequestBuilder builder =
- request(request.getMethod().toString(), rawUrl)
- .setReadTimeout(timeout)
- .setRequestTimeout(timeout);
-
- for (String name : request.getQueryParameterNames()) {
- for (String value : request.getQueryParameters(name)) {
- builder.addQueryParam(name, value);
- }
- }
-
- // Netty tends to timeout when a GET request has a 'Content-Length' header
- if (request.getMethod().equals(HttpMethod.GET) && request.getHeader("Content-Length") != null) {
- request.removeHeader("Content-Length");
- }
-
- request.forEachHeader(builder::addHeader);
- if (request.getHeader("User-Agent") == null) {
- builder.addHeader("User-Agent", AddSeleniumUserAgent.USER_AGENT);
- }
-
- Realm.Builder realmBuilder = null;
- String info = baseUrl.getUserInfo();
- if (!Strings.isNullOrEmpty(info)) {
- String[] parts = info.split(":", 2);
- String user = parts[0];
- String pass = parts.length > 1 ? parts[1] : null;
- realmBuilder = Dsl.basicAuthRealm(user, pass).setUsePreemptiveAuth(true);
- builder.setRealm(realmBuilder);
- } else if (credentials != null) {
- if (!(credentials instanceof UsernameAndPassword)) {
- throw new IllegalArgumentException("Credentials must be a user name and password");
- }
- UsernameAndPassword uap = (UsernameAndPassword) credentials;
- realmBuilder = Dsl.basicAuthRealm(uap.username(), uap.password()).setUsePreemptiveAuth(true);
- builder.setRealm(realmBuilder);
- }
-
- if (config.proxy() != null) {
- InetSocketAddress address = (InetSocketAddress) config.proxy().address();
- ProxyServer.Builder proxyBuilder =
- new ProxyServer.Builder(address.getHostName(), address.getPort());
- if (realmBuilder != null) {
- proxyBuilder.setRealm(realmBuilder);
- }
- builder.setProxyServer(proxyBuilder);
- }
-
- if (request.getMethod().equals(HttpMethod.POST)) {
- builder.setBody(request.getContent().get());
- }
-
- return builder.build();
- }
-
- public static HttpResponse toSeleniumResponse(Response response) {
- HttpResponse toReturn = new HttpResponse();
-
- toReturn.setStatus(response.getStatusCode());
-
- toReturn.setContent(
- !response.hasResponseBody() ? empty() : memoize(response::getResponseBodyAsStream));
-
- response
- .getHeaders()
- .names()
- .forEach(
- name -> response.getHeaders(name).forEach(value -> toReturn.addHeader(name, value)));
-
- return toReturn;
- }
-
- private static String getRawUrl(URI baseUrl, String uri) {
- String rawUrl;
- if (uri.startsWith("ws://")) {
- rawUrl = "http://" + uri.substring("ws://".length());
- } else if (uri.startsWith("wss://")) {
- rawUrl = "https://" + uri.substring("wss://".length());
- } else if (uri.startsWith("http://") || uri.startsWith("https://")) {
- rawUrl = uri;
- } else {
- String base = baseUrl.toString();
- if (base.endsWith("/")) {
- rawUrl = base.substring(0, base.length() - 1) + uri;
- } else {
- rawUrl = base + uri;
- }
- }
- return rawUrl;
- }
-}
diff --git a/java/src/org/openqa/selenium/remote/http/netty/NettyWebSocket.java b/java/src/org/openqa/selenium/remote/http/netty/NettyWebSocket.java
deleted file mode 100644
index 6e3f07f040208..0000000000000
--- a/java/src/org/openqa/selenium/remote/http/netty/NettyWebSocket.java
+++ /dev/null
@@ -1,174 +0,0 @@
-// Licensed to the Software Freedom Conservancy (SFC) under one
-// or more contributor license agreements. See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership. The SFC licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License. You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-package org.openqa.selenium.remote.http.netty;
-
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.atomic.AtomicReference;
-import java.util.function.BiFunction;
-import java.util.function.Function;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import org.asynchttpclient.AsyncHttpClient;
-import org.asynchttpclient.ListenableFuture;
-import org.asynchttpclient.Request;
-import org.asynchttpclient.ws.WebSocketListener;
-import org.asynchttpclient.ws.WebSocketUpgradeHandler;
-import org.openqa.selenium.internal.Require;
-import org.openqa.selenium.remote.http.BinaryMessage;
-import org.openqa.selenium.remote.http.ClientConfig;
-import org.openqa.selenium.remote.http.CloseMessage;
-import org.openqa.selenium.remote.http.ConnectionFailedException;
-import org.openqa.selenium.remote.http.Filter;
-import org.openqa.selenium.remote.http.HttpRequest;
-import org.openqa.selenium.remote.http.HttpResponse;
-import org.openqa.selenium.remote.http.Message;
-import org.openqa.selenium.remote.http.TextMessage;
-import org.openqa.selenium.remote.http.WebSocket;
-
-class NettyWebSocket implements WebSocket {
-
- private static final Logger LOG = Logger.getLogger(NettyWebSocket.class.getName());
-
- private final org.asynchttpclient.ws.WebSocket socket;
-
- private NettyWebSocket(AsyncHttpClient client, Request request, Listener listener) {
- Require.nonNull("HTTP client", client);
- Require.nonNull("WebSocket listener", listener);
-
- try {
- URL origUrl = new URL(request.getUrl());
- String wsScheme = "https".equalsIgnoreCase(origUrl.getProtocol()) ? "wss" : "ws";
-
- URI wsUri =
- new URI(
- wsScheme, null, origUrl.getHost(), origUrl.getPort(), origUrl.getPath(), null, null);
- ListenableFuture future =
- client
- .prepareGet(wsUri.toString())
- .execute(
- new WebSocketUpgradeHandler.Builder()
- .addWebSocketListener(
- new WebSocketListener() {
- @Override
- public void onOpen(org.asynchttpclient.ws.WebSocket websocket) {}
-
- @Override
- public void onClose(
- org.asynchttpclient.ws.WebSocket websocket,
- int code,
- String reason) {
- listener.onClose(code, reason);
- }
-
- @Override
- public void onError(Throwable t) {
- listener.onError(t);
- }
-
- @Override
- public void onBinaryFrame(
- byte[] payload, boolean finalFragment, int rsv) {
- if (payload != null) {
- listener.onBinary(payload);
- }
- }
-
- @Override
- public void onTextFrame(
- String payload, boolean finalFragment, int rsv) {
- if (payload != null) {
- listener.onText(payload);
- }
- }
- })
- .build());
- socket =
- future
- .toCompletableFuture()
- .exceptionally(
- t -> {
- LOG.log(Level.WARNING, t.getMessage(), t);
- return null;
- })
- .get();
-
- if (socket == null) {
- throw new ConnectionFailedException(
- "Unable to establish websocket connection to " + request.getUrl());
- }
- } catch (InterruptedException e) {
- Thread.currentThread().interrupt();
- LOG.log(Level.WARNING, "NettyWebSocket initial request interrupted", e);
- throw new ConnectionFailedException("NettyWebSocket initial request interrupted", e);
- } catch (ExecutionException | MalformedURLException | URISyntaxException e) {
- throw new ConnectionFailedException("NettyWebSocket initial request execution error", e);
- }
- }
-
- static BiFunction create(
- ClientConfig config, AsyncHttpClient client) {
- Filter filter = config.filter();
-
- Function filterRequest =
- req -> {
- AtomicReference ref = new AtomicReference<>();
- filter
- .andFinally(
- in -> {
- ref.set(in);
- return new HttpResponse();
- })
- .execute(req);
- return ref.get();
- };
-
- return (req, listener) -> {
- HttpRequest filtered = filterRequest.apply(req);
- Request nettyReq = NettyMessages.toNettyRequest(config, filtered);
- return new NettyWebSocket(client, nettyReq, listener);
- };
- }
-
- @Override
- public WebSocket send(Message message) {
- if (message instanceof BinaryMessage) {
- socket.sendBinaryFrame(((BinaryMessage) message).data());
- } else if (message instanceof CloseMessage) {
- socket.sendCloseFrame(((CloseMessage) message).code(), ((CloseMessage) message).reason());
- } else if (message instanceof TextMessage) {
- socket.sendTextFrame(((TextMessage) message).text());
- }
-
- return this;
- }
-
- @Override
- public WebSocket sendText(CharSequence data) {
- socket.sendTextFrame(data.toString());
- return this;
- }
-
- @Override
- public void close() {
- socket.sendCloseFrame(1000, "WebDriver closing socket");
- }
-}
diff --git a/java/test/org/openqa/selenium/remote/http/BUILD.bazel b/java/test/org/openqa/selenium/remote/http/BUILD.bazel
index d84861402521d..66bb20460f80e 100644
--- a/java/test/org/openqa/selenium/remote/http/BUILD.bazel
+++ b/java/test/org/openqa/selenium/remote/http/BUILD.bazel
@@ -14,7 +14,7 @@ java_test_suite(
"//java:auto-service",
"//java/src/org/openqa/selenium:core",
"//java/src/org/openqa/selenium/remote/http",
- "//java/src/org/openqa/selenium/remote/http/netty",
+ "//java/src/org/openqa/selenium/remote/http/jdk",
"//java/test/org/openqa/selenium/environment",
"//java/test/org/openqa/selenium/testing:annotations",
artifact("org.assertj:assertj-core"),
diff --git a/java/test/org/openqa/selenium/remote/http/netty/BUILD.bazel b/java/test/org/openqa/selenium/remote/http/netty/BUILD.bazel
index 066f9cc836f08..3ac9dd14b4a72 100644
--- a/java/test/org/openqa/selenium/remote/http/netty/BUILD.bazel
+++ b/java/test/org/openqa/selenium/remote/http/netty/BUILD.bazel
@@ -7,7 +7,7 @@ java_test_suite(
srcs = glob(["*.java"]),
deps = [
"//java/src/org/openqa/selenium/remote/http",
- "//java/src/org/openqa/selenium/remote/http/netty",
+ "//java/src/org/openqa/selenium/remote/http/jdk",
"//java/test/org/openqa/selenium/remote/internal:test-lib",
"//java/test/org/openqa/selenium/testing:annotations",
artifact("org.junit.jupiter:junit-jupiter-api"),