Reorganization of jetty-client classes. (#9127)
* Reorganization of jetty-client classes. * Moved oej.client.api to oej.client * Moved oej.client.util to oej.client * Moved implementation classes to oej.client.internal * Moved transports to oej.client.transport * Moved transport implementation classes to oej.client.transport.internal * Moved TunnelRequest to oej.client.internal. * Moved FastCGI transport classes to o.e.j.fcgi.transport * Moved FastCGI transport implementation classes to o.e.j.fcgi.transport.internal * Updated WebSocket core client to use only exported, non-internal, oej.client classes. * Expanded oej.client.Destination APIs: - added: getOrigin(), isSecure(), getProxy(), getConnectionPool(), getHttpClient(), send(..). - removed: getScheme(), getHost(), getPort() because they don't uniquely identify a Destination anymore (Origin does) * Moved destination sweeper functionality from HttpDestination to HttpClient. HttpDestination does not implement close() anymore, now relies on LifeCycle.stop() * Moved HttpReceiver.storeCookie() logic to HttpClient.putCookie() to avoid exposing CookieManager. * Moved HttpClient.getAcceptEncodingField() to ContentDecoder.Factories * Avoid public/protected Logger instances. Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
parent
03569efb6c
commit
a1c5cefd0d
|
@ -26,34 +26,34 @@ import java.nio.file.Paths;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.AsyncRequestContent;
|
||||
import org.eclipse.jetty.client.Authentication;
|
||||
import org.eclipse.jetty.client.AuthenticationStore;
|
||||
import org.eclipse.jetty.client.BasicAuthentication;
|
||||
import org.eclipse.jetty.client.BufferingResponseListener;
|
||||
import org.eclipse.jetty.client.BytesRequestContent;
|
||||
import org.eclipse.jetty.client.ConnectionPool;
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.client.Destination;
|
||||
import org.eclipse.jetty.client.DigestAuthentication;
|
||||
import org.eclipse.jetty.client.FutureResponseListener;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpClientTransport;
|
||||
import org.eclipse.jetty.client.HttpDestination;
|
||||
import org.eclipse.jetty.client.HttpProxy;
|
||||
import org.eclipse.jetty.client.InputStreamRequestContent;
|
||||
import org.eclipse.jetty.client.InputStreamResponseListener;
|
||||
import org.eclipse.jetty.client.OutputStreamRequestContent;
|
||||
import org.eclipse.jetty.client.PathRequestContent;
|
||||
import org.eclipse.jetty.client.ProxyConfiguration;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.client.Result;
|
||||
import org.eclipse.jetty.client.RoundRobinConnectionPool;
|
||||
import org.eclipse.jetty.client.api.Authentication;
|
||||
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic;
|
||||
import org.eclipse.jetty.client.http.HttpClientConnectionFactory;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.client.util.AsyncRequestContent;
|
||||
import org.eclipse.jetty.client.util.BasicAuthentication;
|
||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||
import org.eclipse.jetty.client.util.BytesRequestContent;
|
||||
import org.eclipse.jetty.client.util.DigestAuthentication;
|
||||
import org.eclipse.jetty.client.util.FutureResponseListener;
|
||||
import org.eclipse.jetty.client.util.InputStreamRequestContent;
|
||||
import org.eclipse.jetty.client.util.InputStreamResponseListener;
|
||||
import org.eclipse.jetty.client.util.OutputStreamRequestContent;
|
||||
import org.eclipse.jetty.client.util.PathRequestContent;
|
||||
import org.eclipse.jetty.client.util.StringRequestContent;
|
||||
import org.eclipse.jetty.fcgi.client.http.HttpClientTransportOverFCGI;
|
||||
import org.eclipse.jetty.client.StringRequestContent;
|
||||
import org.eclipse.jetty.client.transport.HttpClientConnectionFactory;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportDynamic;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.fcgi.client.transport.HttpClientTransportOverFCGI;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
@ -870,13 +870,11 @@ public class HTTPClientDocs
|
|||
httpClient.start();
|
||||
|
||||
ConnectionPool connectionPool = httpClient.getDestinations().stream()
|
||||
// Cast to HttpDestination.
|
||||
.map(HttpDestination.class::cast)
|
||||
// Find the destination by filtering on the Origin.
|
||||
.filter(destination -> destination.getOrigin().getAddress().getHost().equals("domain.com"))
|
||||
.findAny()
|
||||
// Get the ConnectionPool.
|
||||
.map(HttpDestination::getConnectionPool)
|
||||
.map(Destination::getConnectionPool)
|
||||
.orElse(null);
|
||||
// end::getConnectionPool[]
|
||||
}
|
||||
|
@ -901,7 +899,6 @@ public class HTTPClientDocs
|
|||
transport.setConnectionPoolFactory(destination ->
|
||||
new RoundRobinConnectionPool(destination,
|
||||
maxConnectionsPerDestination,
|
||||
destination,
|
||||
maxRequestsPerConnection));
|
||||
// end::setConnectionPool[]
|
||||
}
|
||||
|
|
|
@ -19,9 +19,9 @@ import java.util.concurrent.CompletableFuture;
|
|||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpProxy;
|
||||
import org.eclipse.jetty.client.HttpRequest;
|
||||
import org.eclipse.jetty.client.HttpResponse;
|
||||
import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportDynamic;
|
||||
import org.eclipse.jetty.ee10.websocket.api.Session;
|
||||
import org.eclipse.jetty.ee10.websocket.client.ClientUpgradeRequest;
|
||||
import org.eclipse.jetty.ee10.websocket.client.JettyUpgradeListener;
|
||||
|
@ -175,7 +175,7 @@ public class WebSocketClientDocs
|
|||
JettyUpgradeListener listener = new JettyUpgradeListener()
|
||||
{
|
||||
@Override
|
||||
public void onHandshakeResponse(HttpRequest request, HttpResponse response)
|
||||
public void onHandshakeResponse(Request request, Response response)
|
||||
{
|
||||
// Inspect the HTTP response here.
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ import java.security.Security;
|
|||
|
||||
import org.conscrypt.OpenSSLProvider;
|
||||
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.http2.client.HTTP2Client;
|
||||
import org.eclipse.jetty.http2.client.transport.HttpClientTransportOverHTTP2;
|
||||
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
|
||||
|
|
|
@ -25,11 +25,13 @@ module org.eclipse.jetty.client
|
|||
requires static org.eclipse.jetty.jmx;
|
||||
|
||||
exports org.eclipse.jetty.client;
|
||||
exports org.eclipse.jetty.client.api;
|
||||
exports org.eclipse.jetty.client.dynamic;
|
||||
exports org.eclipse.jetty.client.http;
|
||||
exports org.eclipse.jetty.client.util;
|
||||
exports org.eclipse.jetty.client.transport;
|
||||
|
||||
exports org.eclipse.jetty.client.jmx to
|
||||
org.eclipse.jetty.jmx;
|
||||
|
||||
exports org.eclipse.jetty.client.internal to
|
||||
org.eclipse.jetty.fcgi.client,
|
||||
org.eclipse.jetty.http2.client.transport,
|
||||
org.eclipse.jetty.http3.client.transport;
|
||||
}
|
||||
|
|
|
@ -11,13 +11,10 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.Authentication;
|
||||
|
||||
public abstract class AbstractAuthentication implements Authentication
|
||||
{
|
||||
private final URI uri;
|
|
@ -25,9 +25,8 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.util.Attachable;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.NanoTime;
|
||||
import org.eclipse.jetty.util.Pool;
|
||||
|
@ -49,17 +48,15 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
|
||||
private final AtomicInteger pending = new AtomicInteger();
|
||||
private final HttpDestination destination;
|
||||
private final Callback requester;
|
||||
private final Pool<Connection> pool;
|
||||
private boolean maximizeConnections;
|
||||
private volatile long maxDurationNanos;
|
||||
private volatile int maxUsage;
|
||||
private volatile int initialMaxMultiplex;
|
||||
|
||||
protected AbstractConnectionPool(HttpDestination destination, Pool<Connection> pool, Callback requester, int initialMaxMultiplex)
|
||||
protected AbstractConnectionPool(Destination destination, Pool<Connection> pool, int initialMaxMultiplex)
|
||||
{
|
||||
this.destination = destination;
|
||||
this.requester = requester;
|
||||
this.destination = (HttpDestination)destination;
|
||||
this.pool = pool;
|
||||
this.initialMaxMultiplex = initialMaxMultiplex;
|
||||
addBean(pool);
|
||||
|
@ -307,7 +304,7 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
|
||||
protected void proceed()
|
||||
{
|
||||
requester.succeeded();
|
||||
destination.succeeded();
|
||||
}
|
||||
|
||||
protected Connection activate()
|
||||
|
@ -587,7 +584,7 @@ public abstract class AbstractConnectionPool extends ContainerLifeCycle implemen
|
|||
pending.decrementAndGet();
|
||||
reserved.remove();
|
||||
completeExceptionally(x);
|
||||
requester.failed(x);
|
||||
destination.failed(x);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ import java.time.Duration;
|
|||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
|
|
|
@ -15,7 +15,6 @@ package org.eclipse.jetty.client;
|
|||
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
|
|
|
@ -11,12 +11,11 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.io.content.AsyncContent;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.api;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
@ -54,7 +54,7 @@ public interface Authentication
|
|||
|
||||
/**
|
||||
* Executes the authentication mechanism for the given request, returning a {@link Result} that can be
|
||||
* used to actually authenticate the request via {@link org.eclipse.jetty.client.api.Authentication.Result#apply(Request)}.
|
||||
* used to actually authenticate the request via {@link Authentication.Result#apply(Request)}.
|
||||
* <p>
|
||||
* If a request for {@code "/secure"} returns a {@link Result}, then the result may be used for other
|
||||
* requests such as {@code "/secure/foo"} or {@code "/secure/bar"}, unless those resources are protected
|
||||
|
@ -136,7 +136,7 @@ public interface Authentication
|
|||
}
|
||||
|
||||
/**
|
||||
* {@link Result} holds the information needed to authenticate a {@link Request} via {@link org.eclipse.jetty.client.api.Authentication.Result#apply(org.eclipse.jetty.client.api.Request)}.
|
||||
* {@link Result} holds the information needed to authenticate a {@link Request} via {@link Authentication.Result#apply(Request)}.
|
||||
*/
|
||||
public static interface Result
|
||||
{
|
|
@ -23,14 +23,11 @@ import java.util.concurrent.TimeoutException;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.client.api.Authentication;
|
||||
import org.eclipse.jetty.client.api.Authentication.HeaderInfo;
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||
import org.eclipse.jetty.client.Authentication.HeaderInfo;
|
||||
import org.eclipse.jetty.client.internal.HttpContentResponse;
|
||||
import org.eclipse.jetty.client.internal.HttpConversation;
|
||||
import org.eclipse.jetty.client.internal.HttpRequest;
|
||||
import org.eclipse.jetty.client.internal.ResponseNotifier;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
@ -42,13 +39,13 @@ import org.slf4j.LoggerFactory;
|
|||
public abstract class AuthenticationProtocolHandler implements ProtocolHandler
|
||||
{
|
||||
public static final int DEFAULT_MAX_CONTENT_LENGTH = 16 * 1024;
|
||||
public static final Logger LOG = LoggerFactory.getLogger(AuthenticationProtocolHandler.class);
|
||||
private static final Logger LOG = LoggerFactory.getLogger(AuthenticationProtocolHandler.class);
|
||||
private static final Pattern CHALLENGE_PATTERN = Pattern.compile("(?<schemeOnly>[!#$%&'*+\\-.^_`|~0-9A-Za-z]+)|(?:(?<scheme>[!#$%&'*+\\-.^_`|~0-9A-Za-z]+)\\s+)?(?:(?<token68>[a-zA-Z0-9\\-._~+/]+=*)|(?<paramName>[!#$%&'*+\\-.^_`|~0-9A-Za-z]+)\\s*=\\s*(?:(?<paramValue>.*)))");
|
||||
|
||||
private final HttpClient client;
|
||||
private final int maxContentLength;
|
||||
private final ResponseNotifier notifier;
|
||||
|
||||
private static final Pattern CHALLENGE_PATTERN = Pattern.compile("(?<schemeOnly>[!#$%&'*+\\-.^_`|~0-9A-Za-z]+)|(?:(?<scheme>[!#$%&'*+\\-.^_`|~0-9A-Za-z]+)\\s+)?(?:(?<token68>[a-zA-Z0-9\\-._~+/]+=*)|(?<paramName>[!#$%&'*+\\-.^_`|~0-9A-Za-z]+)\\s*=\\s*(?:(?<paramValue>.*)))");
|
||||
|
||||
protected AuthenticationProtocolHandler(HttpClient client, int maxContentLength)
|
||||
{
|
||||
this.client = client;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.api;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.net.URI;
|
||||
|
|
@ -11,17 +11,13 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
|
||||
|
@ -68,7 +64,7 @@ public class BasicAuthentication extends AbstractAuthentication
|
|||
* Basic authentication result.
|
||||
* <p>
|
||||
* Application may utilize this class directly via
|
||||
* {@link org.eclipse.jetty.client.api.AuthenticationStore#addAuthenticationResult(Result)}
|
||||
* {@link AuthenticationStore#addAuthenticationResult(Result)}
|
||||
* to perform preemptive authentication, that is immediately
|
||||
* sending the authorization header based on the fact that the
|
||||
* URI is known to require authentication and that username
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
|
@ -20,10 +20,7 @@ import java.nio.charset.Charset;
|
|||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Response.Listener;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.Response.Listener;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
|
@ -112,6 +109,8 @@ public abstract class BufferingResponseListener extends Listener.Adapter
|
|||
public void onContent(Response response, ByteBuffer content)
|
||||
{
|
||||
int length = content.remaining();
|
||||
if (length == 0)
|
||||
return;
|
||||
if (length > BufferUtil.space(buffer))
|
||||
{
|
||||
int remaining = buffer == null ? 0 : buffer.remaining();
|
|
@ -11,13 +11,12 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.io.content.ByteBufferContentSource;
|
||||
|
||||
/**
|
|
@ -11,13 +11,11 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
|
||||
/**
|
||||
* A {@link Request.Content} for byte arrays.
|
||||
*/
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.api;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.Closeable;
|
||||
|
|
@ -16,8 +16,6 @@ package org.eclipse.jetty.client;
|
|||
import java.io.Closeable;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
|
||||
/**
|
||||
* <p>Client-side connection pool abstraction.</p>
|
||||
*/
|
||||
|
@ -102,7 +100,7 @@ public interface ConnectionPool extends Closeable
|
|||
* @param destination the destination to create the ConnectionPool for
|
||||
* @return the newly created ConnectionPool
|
||||
*/
|
||||
ConnectionPool newConnectionPool(HttpDestination destination);
|
||||
ConnectionPool newConnectionPool(Destination destination);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -14,6 +14,12 @@
|
|||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
|
||||
/**
|
||||
* {@link ContentDecoder} decodes content bytes of a response.
|
||||
|
@ -89,4 +95,35 @@ public interface ContentDecoder
|
|||
*/
|
||||
public abstract ContentDecoder newContentDecoder();
|
||||
}
|
||||
|
||||
public static class Factories implements Iterable<ContentDecoder.Factory>
|
||||
{
|
||||
private final Map<String, Factory> factories = new LinkedHashMap<>();
|
||||
private HttpField acceptEncodingField;
|
||||
|
||||
public HttpField getAcceptEncodingField()
|
||||
{
|
||||
return acceptEncodingField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Factory> iterator()
|
||||
{
|
||||
return factories.values().iterator();
|
||||
}
|
||||
|
||||
public void clear()
|
||||
{
|
||||
factories.clear();
|
||||
acceptEncodingField = null;
|
||||
}
|
||||
|
||||
public Factory put(Factory factory)
|
||||
{
|
||||
Factory result = factories.put(factory.getEncoding(), factory);
|
||||
String value = String.join(",", factories.keySet());
|
||||
acceptEncodingField = new HttpField(HttpHeader.ACCEPT_ENCODING, value);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,13 +11,27 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.api;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.client.internal.HttpContentResponse;
|
||||
|
||||
/**
|
||||
* A specialized {@link Response} that can hold a limited content in memory.
|
||||
*/
|
||||
public interface ContentResponse extends Response
|
||||
{
|
||||
/**
|
||||
* @param response the Response with status code and headers
|
||||
* @param content the content bytes associated to the response
|
||||
* @param mediaType the media type of the content bytes
|
||||
* @param encoding the encoding of the content bytes
|
||||
* @return a new ContentResponse from the given arguments
|
||||
*/
|
||||
static ContentResponse from(Response response, byte[] content, String mediaType, String encoding)
|
||||
{
|
||||
return new HttpContentResponse(response, content, mediaType, encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the media type of the content, such as "text/html" or "application/octet-stream"
|
||||
*/
|
|
@ -15,10 +15,11 @@ package org.eclipse.jetty.client;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||
import org.eclipse.jetty.client.internal.HttpContentResponse;
|
||||
import org.eclipse.jetty.client.internal.HttpConversation;
|
||||
import org.eclipse.jetty.client.internal.HttpExchange;
|
||||
import org.eclipse.jetty.client.internal.HttpRequest;
|
||||
import org.eclipse.jetty.client.internal.ResponseNotifier;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpHeaderValue;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
|
||||
/**
|
||||
* <p>A {@link Destination} represents the receiver of HTTP requests, and it is
|
||||
* identified by an {@link Origin}.</p>
|
||||
* <p>{@link Destination} holds a pool of {@link Connection}s, but allows to create unpooled
|
||||
* connections if the application wants full control over connection management via
|
||||
* {@link #newConnection(Promise)}.</p>
|
||||
* <p>{@link Destination}s may be obtained via {@link HttpClient#resolveDestination(Request)}.</p>
|
||||
*/
|
||||
public interface Destination
|
||||
{
|
||||
/**
|
||||
* @return the origin of this destination
|
||||
*/
|
||||
Origin getOrigin();
|
||||
|
||||
/**
|
||||
* @return whether the communication with the destination is secure
|
||||
*/
|
||||
boolean isSecure();
|
||||
|
||||
/**
|
||||
* @return the proxy associated with this destination,
|
||||
* or {@code null} if there is no proxy
|
||||
*/
|
||||
ProxyConfiguration.Proxy getProxy();
|
||||
|
||||
/**
|
||||
* @return the connection pool associated with this destination
|
||||
*/
|
||||
ConnectionPool getConnectionPool();
|
||||
|
||||
/**
|
||||
* @return the {@code HttpClient} that manages this destination
|
||||
*/
|
||||
HttpClient getHttpClient();
|
||||
|
||||
/**
|
||||
* Creates asynchronously a new, unpooled, {@link Connection} that will be returned
|
||||
* at a later time through the given {@link Promise}.
|
||||
* <p>
|
||||
* Use {@link FuturePromise} to wait for the connection:
|
||||
* <pre>{@code
|
||||
* Destination destination = ...;
|
||||
* FuturePromise<Connection> futureConnection = new FuturePromise<>();
|
||||
* destination.newConnection(futureConnection);
|
||||
* Connection connection = futureConnection.get(5, TimeUnit.SECONDS);
|
||||
* }</pre>
|
||||
*
|
||||
* @param promise the promise of a new, unpooled, {@link Connection}
|
||||
*/
|
||||
void newConnection(Promise<Connection> promise);
|
||||
|
||||
/**
|
||||
* <p>Sends the given request to this destination.</p>
|
||||
* <p>You can use this method to send the request to a specific
|
||||
* destination that may be different from the request authority.</p>
|
||||
* <p>For example when {@link HttpClient} is used in a proxy, it may
|
||||
* receive a request with authority {@code yourserver.com} but the
|
||||
* proxy logic may want to forward the request to a specific backend
|
||||
* server, say {@code backend01}, therefore:</p>
|
||||
* <pre>{@code
|
||||
* // Resolve the backend destination.
|
||||
* Origin backendOrigin = new Origin(backendScheme, "backend01", backendPort);
|
||||
* Destination backendDestination = httpClient.resolveDestination(backendOrigin);
|
||||
*
|
||||
* // Create a request with the original authority.
|
||||
* Request request = httpClient.newRequest("https://yourserver.com/path");
|
||||
*
|
||||
* // Send the request to the specific backend.
|
||||
* backendDestination.send(request, result -> { ... });
|
||||
* }</pre>
|
||||
*
|
||||
* @param request the request to send to this destination
|
||||
* @param listener the listener that receives response events
|
||||
*/
|
||||
void send(Request request, Response.CompleteListener listener);
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -25,10 +25,6 @@ import java.util.Objects;
|
|||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
import org.eclipse.jetty.util.StringUtil;
|
|
@ -13,15 +13,14 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Pool;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
|
||||
@ManagedObject
|
||||
public class DuplexConnectionPool extends AbstractConnectionPool
|
||||
{
|
||||
public DuplexConnectionPool(HttpDestination destination, int maxConnections, Callback requester)
|
||||
public DuplexConnectionPool(Destination destination, int maxConnections)
|
||||
{
|
||||
super(destination, new Pool<>(Pool.StrategyType.FIRST, maxConnections, false), requester, 1);
|
||||
super(destination, new Pool<>(Pool.StrategyType.FIRST, maxConnections, false), 1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,11 @@ package org.eclipse.jetty.client;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||
import org.eclipse.jetty.client.internal.HttpContentResponse;
|
||||
import org.eclipse.jetty.client.internal.HttpConversation;
|
||||
import org.eclipse.jetty.client.internal.HttpExchange;
|
||||
import org.eclipse.jetty.client.internal.HttpRequest;
|
||||
import org.eclipse.jetty.client.internal.ResponseNotifier;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
||||
|
|
|
@ -11,13 +11,12 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.util.Fields;
|
||||
|
||||
/**
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
@ -21,10 +21,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.eclipse.jetty.client.HttpContentResponse;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.internal.HttpContentResponse;
|
||||
|
||||
/**
|
||||
* A {@link BufferingResponseListener} that is also a {@link Future}, to allow applications
|
|
@ -25,14 +25,11 @@ import java.nio.channels.SelectionKey;
|
|||
import java.nio.channels.SocketChannel;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
@ -40,14 +37,11 @@ import java.util.concurrent.Executor;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Destination;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.client.util.FormRequestContent;
|
||||
import org.eclipse.jetty.client.internal.HttpAuthenticationStore;
|
||||
import org.eclipse.jetty.client.internal.HttpConversation;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.client.internal.HttpRequest;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.http.HttpCompliance;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
|
@ -124,7 +118,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
private final ConcurrentMap<Origin, HttpDestination> destinations = new ConcurrentHashMap<>();
|
||||
private final ProtocolHandlers handlers = new ProtocolHandlers();
|
||||
private final List<Request.Listener> requestListeners = new ArrayList<>();
|
||||
private final Set<ContentDecoder.Factory> decoderFactories = new ContentDecoderFactorySet();
|
||||
private final ContentDecoder.Factories decoderFactories = new ContentDecoder.Factories();
|
||||
private final ProxyConfiguration proxyConfig = new ProxyConfiguration();
|
||||
private final HttpClientTransport transport;
|
||||
private final ClientConnector connector;
|
||||
|
@ -140,9 +134,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
private int responseBufferSize = 16384;
|
||||
private int maxRedirects = 8;
|
||||
private long addressResolutionTimeout = 15000;
|
||||
private boolean tcpNoDelay = true;
|
||||
private boolean strictEventOrdering = false;
|
||||
private HttpField encodingField;
|
||||
private long destinationIdleTimeout;
|
||||
private String name = getClass().getSimpleName() + "@" + Integer.toHexString(hashCode());
|
||||
private HttpCompliance httpCompliance = HttpCompliance.RFC7230;
|
||||
|
@ -232,7 +224,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
handlers.put(new ProxyAuthenticationProtocolHandler(this));
|
||||
handlers.put(new UpgradeProtocolHandler());
|
||||
|
||||
decoderFactories.add(new GZIPContentDecoder.Factory(byteBufferPool));
|
||||
decoderFactories.put(new GZIPContentDecoder.Factory(byteBufferPool));
|
||||
|
||||
cookieManager = newCookieManager();
|
||||
cookieStore = cookieManager.getCookieStore();
|
||||
|
@ -264,13 +256,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
|
||||
decoderFactories.clear();
|
||||
handlers.clear();
|
||||
|
||||
for (HttpDestination destination : destinations.values())
|
||||
{
|
||||
destination.close();
|
||||
}
|
||||
destinations.clear();
|
||||
|
||||
requestListeners.clear();
|
||||
authenticationStore.clearAuthentications();
|
||||
authenticationStore.clearAuthenticationResults();
|
||||
|
@ -279,10 +265,10 @@ public class HttpClient extends ContainerLifeCycle
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a <em>non</em> thread-safe list of {@link org.eclipse.jetty.client.api.Request.Listener}s that can be modified before
|
||||
* Returns a <em>non</em> thread-safe list of {@link Request.Listener}s that can be modified before
|
||||
* performing requests.
|
||||
*
|
||||
* @return a list of {@link org.eclipse.jetty.client.api.Request.Listener} that can be used to add and remove listeners
|
||||
* @return a list of {@link Request.Listener} that can be used to add and remove listeners
|
||||
*/
|
||||
public List<Request.Listener> getRequestListeners()
|
||||
{
|
||||
|
@ -308,20 +294,23 @@ public class HttpClient extends ContainerLifeCycle
|
|||
this.cookieManager = newCookieManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep this method package-private because its interface is so ugly
|
||||
* that we really don't want to expose it more than strictly needed.
|
||||
*
|
||||
* @return the cookie manager
|
||||
*/
|
||||
CookieManager getCookieManager()
|
||||
public void putCookie(URI uri, HttpField field)
|
||||
{
|
||||
return cookieManager;
|
||||
}
|
||||
|
||||
Sweeper getDestinationSweeper()
|
||||
{
|
||||
return destinationSweeper;
|
||||
try
|
||||
{
|
||||
String value = field.getValue();
|
||||
if (value != null)
|
||||
{
|
||||
Map<String, List<String>> header = new HashMap<>(1);
|
||||
header.put(field.getHeader().asString(), List.of(value));
|
||||
cookieManager.put(uri, header);
|
||||
}
|
||||
}
|
||||
catch (IOException x)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Unable to store cookies {} from {}", field, uri, x);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -348,7 +337,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
*
|
||||
* @return a set of {@link ContentDecoder.Factory} that can be used to add and remove content decoder factories
|
||||
*/
|
||||
public Set<ContentDecoder.Factory> getContentDecoderFactories()
|
||||
public ContentDecoder.Factories getContentDecoderFactories()
|
||||
{
|
||||
return decoderFactories;
|
||||
}
|
||||
|
@ -474,9 +463,9 @@ public class HttpClient extends ContainerLifeCycle
|
|||
return newHttpRequest(newConversation(), uri);
|
||||
}
|
||||
|
||||
protected Request copyRequest(HttpRequest oldRequest, URI newURI)
|
||||
protected Request copyRequest(Request oldRequest, URI newURI)
|
||||
{
|
||||
HttpRequest newRequest = newHttpRequest(oldRequest.getConversation(), newURI);
|
||||
HttpRequest newRequest = newHttpRequest(((HttpRequest)oldRequest).getConversation(), newURI);
|
||||
newRequest.method(oldRequest.getMethod())
|
||||
.version(oldRequest.getVersion())
|
||||
.body(oldRequest.getBody())
|
||||
|
@ -510,7 +499,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
return newRequest;
|
||||
}
|
||||
|
||||
protected HttpRequest newHttpRequest(HttpConversation conversation, URI uri)
|
||||
private HttpRequest newHttpRequest(HttpConversation conversation, URI uri)
|
||||
{
|
||||
return new HttpRequest(this, conversation, checkHost(uri));
|
||||
}
|
||||
|
@ -534,14 +523,14 @@ public class HttpClient extends ContainerLifeCycle
|
|||
public Destination resolveDestination(Request request)
|
||||
{
|
||||
HttpClientTransport transport = getTransport();
|
||||
Origin origin = transport.newOrigin((HttpRequest)request);
|
||||
HttpDestination destination = resolveDestination(origin);
|
||||
Origin origin = transport.newOrigin(request);
|
||||
Destination destination = resolveDestination(origin);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Resolved {} for {}", destination, request);
|
||||
return destination;
|
||||
}
|
||||
|
||||
public Origin createOrigin(HttpRequest request, Origin.Protocol protocol)
|
||||
public Origin createOrigin(Request request, Origin.Protocol protocol)
|
||||
{
|
||||
String scheme = request.getScheme();
|
||||
if (!HttpScheme.HTTP.is(scheme) && !HttpScheme.HTTPS.is(scheme) &&
|
||||
|
@ -561,15 +550,17 @@ public class HttpClient extends ContainerLifeCycle
|
|||
* @param origin the origin that identifies the destination
|
||||
* @return the destination for the given origin
|
||||
*/
|
||||
public HttpDestination resolveDestination(Origin origin)
|
||||
public Destination resolveDestination(Origin origin)
|
||||
{
|
||||
return destinations.compute(origin, (k, v) ->
|
||||
{
|
||||
if (v == null || v.stale())
|
||||
{
|
||||
HttpDestination newDestination = getTransport().newHttpDestination(k);
|
||||
HttpDestination newDestination = (HttpDestination)getTransport().newDestination(k);
|
||||
// Start the destination before it's published to other threads.
|
||||
addManaged(newDestination);
|
||||
if (destinationSweeper != null)
|
||||
destinationSweeper.offer(newDestination);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Created {}; existing: '{}'", newDestination, v);
|
||||
return newDestination;
|
||||
|
@ -578,10 +569,13 @@ public class HttpClient extends ContainerLifeCycle
|
|||
});
|
||||
}
|
||||
|
||||
protected boolean removeDestination(HttpDestination destination)
|
||||
public boolean removeDestination(Destination destination)
|
||||
{
|
||||
boolean removed = destinations.remove(destination.getOrigin(), destination);
|
||||
HttpDestination httpDestination = (HttpDestination)destination;
|
||||
boolean removed = destinations.remove(destination.getOrigin(), httpDestination);
|
||||
removeBean(destination);
|
||||
if (destinationSweeper != null)
|
||||
destinationSweeper.remove(httpDestination);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Removed {}; result: {}", destination, removed);
|
||||
return removed;
|
||||
|
@ -595,13 +589,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
return new ArrayList<>(destinations.values());
|
||||
}
|
||||
|
||||
protected void send(HttpRequest request, List<Response.ResponseListener> listeners)
|
||||
{
|
||||
HttpDestination destination = (HttpDestination)resolveDestination(request);
|
||||
destination.send(request, listeners);
|
||||
}
|
||||
|
||||
protected void newConnection(HttpDestination destination, Promise<Connection> promise)
|
||||
public void newConnection(Destination destination, Promise<Connection> promise)
|
||||
{
|
||||
// Multiple threads may access the map, especially with DEBUG logging enabled.
|
||||
Map<String, Object> context = new ConcurrentHashMap<>();
|
||||
|
@ -611,8 +599,9 @@ public class HttpClient extends ContainerLifeCycle
|
|||
List<String> protocols = protocol != null ? protocol.getProtocols() : List.of("http/1.1");
|
||||
context.put(ClientConnector.APPLICATION_PROTOCOLS_CONTEXT_KEY, protocols);
|
||||
|
||||
Origin.Address address = destination.getConnectAddress();
|
||||
resolver.resolve(address.getHost(), address.getPort(), new Promise<>()
|
||||
ProxyConfiguration.Proxy proxy = destination.getProxy();
|
||||
Origin.Address address = proxy == null ? destination.getOrigin().getAddress() : proxy.getAddress();
|
||||
getSocketAddressResolver().resolve(address.getHost(), address.getPort(), new Promise<>()
|
||||
{
|
||||
@Override
|
||||
public void succeeded(List<InetSocketAddress> socketAddresses)
|
||||
|
@ -655,7 +644,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
return handlers;
|
||||
}
|
||||
|
||||
protected ProtocolHandler findProtocolHandler(Request request, Response response)
|
||||
public ProtocolHandler findProtocolHandler(Request request, Response response)
|
||||
{
|
||||
return handlers.find(request, response);
|
||||
}
|
||||
|
@ -1002,7 +991,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
* Whether request/response events must be strictly ordered with respect to connection usage.
|
||||
* <p>
|
||||
* From the point of view of connection usage, the connection can be reused just before the
|
||||
* "complete" event notified to {@link org.eclipse.jetty.client.api.Response.CompleteListener}s
|
||||
* "complete" event notified to {@link Response.CompleteListener}s
|
||||
* (but after the "success" event).
|
||||
* <p>
|
||||
* When a request/response exchange is completing, the destination may have another request
|
||||
|
@ -1146,11 +1135,6 @@ public class HttpClient extends ContainerLifeCycle
|
|||
return proxyConfig;
|
||||
}
|
||||
|
||||
protected HttpField getAcceptEncodingField()
|
||||
{
|
||||
return encodingField;
|
||||
}
|
||||
|
||||
public static int normalizePort(String scheme, int port)
|
||||
{
|
||||
if (port > 0)
|
||||
|
@ -1168,145 +1152,10 @@ public class HttpClient extends ContainerLifeCycle
|
|||
return HttpScheme.HTTPS.is(scheme) || HttpScheme.WSS.is(scheme);
|
||||
}
|
||||
|
||||
protected ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory)
|
||||
public ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory)
|
||||
{
|
||||
if (sslContextFactory == null)
|
||||
sslContextFactory = getSslContextFactory();
|
||||
return new SslClientConnectionFactory(sslContextFactory, getByteBufferPool(), getExecutor(), connectionFactory);
|
||||
}
|
||||
|
||||
private class ContentDecoderFactorySet implements Set<ContentDecoder.Factory>
|
||||
{
|
||||
private final Set<ContentDecoder.Factory> set = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public boolean add(ContentDecoder.Factory e)
|
||||
{
|
||||
boolean result = set.add(e);
|
||||
invalidate();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(Collection<? extends ContentDecoder.Factory> c)
|
||||
{
|
||||
boolean result = set.addAll(c);
|
||||
invalidate();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o)
|
||||
{
|
||||
boolean result = set.remove(o);
|
||||
invalidate();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection<?> c)
|
||||
{
|
||||
boolean result = set.removeAll(c);
|
||||
invalidate();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection<?> c)
|
||||
{
|
||||
boolean result = set.retainAll(c);
|
||||
invalidate();
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear()
|
||||
{
|
||||
set.clear();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size()
|
||||
{
|
||||
return set.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return set.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o)
|
||||
{
|
||||
return set.contains(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c)
|
||||
{
|
||||
return set.containsAll(c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<ContentDecoder.Factory> iterator()
|
||||
{
|
||||
Iterator<ContentDecoder.Factory> iterator = set.iterator();
|
||||
return new Iterator<>()
|
||||
{
|
||||
@Override
|
||||
public boolean hasNext()
|
||||
{
|
||||
return iterator.hasNext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContentDecoder.Factory next()
|
||||
{
|
||||
return iterator.next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove()
|
||||
{
|
||||
iterator.remove();
|
||||
invalidate();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray()
|
||||
{
|
||||
return set.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a)
|
||||
{
|
||||
return set.toArray(a);
|
||||
}
|
||||
|
||||
private void invalidate()
|
||||
{
|
||||
if (set.isEmpty())
|
||||
{
|
||||
encodingField = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
StringBuilder value = new StringBuilder();
|
||||
for (Iterator<ContentDecoder.Factory> iterator = set.iterator(); iterator.hasNext(); )
|
||||
{
|
||||
ContentDecoder.Factory decoderFactory = iterator.next();
|
||||
value.append(decoderFactory.getEncoding());
|
||||
if (iterator.hasNext())
|
||||
value.append(",");
|
||||
}
|
||||
encodingField = new HttpField(HttpHeader.ACCEPT_ENCODING, value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.net.InetSocketAddress;
|
|||
import java.net.SocketAddress;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
|
||||
/**
|
||||
|
@ -52,7 +53,7 @@ public interface HttpClientTransport extends ClientConnectionFactory
|
|||
* @param request the request that triggers the creation of the Origin
|
||||
* @return an Origin that identifies a destination
|
||||
*/
|
||||
public Origin newOrigin(HttpRequest request);
|
||||
public Origin newOrigin(Request request);
|
||||
|
||||
/**
|
||||
* Creates a new, transport-specific, {@link HttpDestination} object.
|
||||
|
@ -63,7 +64,7 @@ public interface HttpClientTransport extends ClientConnectionFactory
|
|||
* @param origin the destination origin
|
||||
* @return a new, transport-specific, {@link HttpDestination} object
|
||||
*/
|
||||
public HttpDestination newHttpDestination(Origin origin);
|
||||
public Destination newDestination(Origin origin);
|
||||
|
||||
/**
|
||||
* Establishes a physical connection to the given {@code address}.
|
||||
|
|
|
@ -21,11 +21,10 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.api.Destination;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.internal.HttpConversation;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.client.internal.HttpRequest;
|
||||
import org.eclipse.jetty.client.internal.TunnelRequest;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
|
@ -142,7 +141,7 @@ public class HttpProxy extends ProxyConfiguration.Proxy
|
|||
// Replace the destination with the proxy destination.
|
||||
HttpDestination destination = (HttpDestination)context.get(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY);
|
||||
HttpClient client = destination.getHttpClient();
|
||||
HttpDestination proxyDestination = client.resolveDestination(getOrigin());
|
||||
Destination proxyDestination = client.resolveDestination(getOrigin());
|
||||
context.put(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY, proxyDestination);
|
||||
try
|
||||
{
|
||||
|
@ -194,7 +193,8 @@ public class HttpProxy extends ProxyConfiguration.Proxy
|
|||
private void tunnel(HttpDestination destination, Connection connection)
|
||||
{
|
||||
String target = destination.getOrigin().getAddress().asString();
|
||||
Origin.Address proxyAddress = destination.getConnectAddress();
|
||||
ProxyConfiguration.Proxy proxy = destination.getProxy();
|
||||
Origin.Address proxyAddress = proxy.getAddress();
|
||||
HttpClient httpClient = destination.getHttpClient();
|
||||
long connectTimeout = httpClient.getConnectTimeout();
|
||||
Request connect = new TunnelRequest(httpClient, proxyAddress)
|
||||
|
@ -204,7 +204,6 @@ public class HttpProxy extends ProxyConfiguration.Proxy
|
|||
// Use the connect timeout as a total timeout,
|
||||
// since this request is to "connect" to the server.
|
||||
.timeout(connectTimeout, TimeUnit.MILLISECONDS);
|
||||
ProxyConfiguration.Proxy proxy = destination.getProxy();
|
||||
if (proxy.isSecure())
|
||||
connect.scheme(HttpScheme.HTTPS.asString());
|
||||
|
||||
|
@ -223,7 +222,7 @@ public class HttpProxy extends ProxyConfiguration.Proxy
|
|||
// Don't want to do DNS resolution here.
|
||||
InetSocketAddress address = InetSocketAddress.createUnresolved(destination.getHost(), destination.getPort());
|
||||
context.put(ClientConnector.REMOTE_SOCKET_ADDRESS_CONTEXT_KEY, address);
|
||||
connectionFactory = destination.newSslClientConnectionFactory(null, connectionFactory);
|
||||
connectionFactory = destination.getHttpClient().newSslClientConnectionFactory(null, connectionFactory);
|
||||
}
|
||||
var oldConnection = endPoint.getConnection();
|
||||
var newConnection = connectionFactory.newConnection(endPoint, context);
|
||||
|
@ -360,12 +359,4 @@ public class HttpProxy extends ProxyConfiguration.Proxy
|
|||
conversation.setAttribute(EndPoint.class.getName(), endPoint);
|
||||
}
|
||||
}
|
||||
|
||||
public static class TunnelRequest extends HttpRequest
|
||||
{
|
||||
private TunnelRequest(HttpClient client, Origin.Address address)
|
||||
{
|
||||
super(client, new HttpConversation(), URI.create("http://" + address.asString()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,10 +24,10 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||
import org.eclipse.jetty.client.internal.HttpContentResponse;
|
||||
import org.eclipse.jetty.client.internal.HttpConversation;
|
||||
import org.eclipse.jetty.client.internal.HttpRequest;
|
||||
import org.eclipse.jetty.client.internal.ResponseNotifier;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
|
||||
public class HttpRequestException extends RuntimeException
|
||||
{
|
||||
private final Request request;
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
|
||||
public class HttpResponseException extends RuntimeException
|
||||
{
|
||||
private final Response response;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
@ -31,13 +30,19 @@ import org.eclipse.jetty.util.Callback;
|
|||
*/
|
||||
public interface HttpUpgrader
|
||||
{
|
||||
/**
|
||||
* <p>The request attribute key for the upgrade protocol,
|
||||
* used by the HTTP/2 extended CONNECT mechanism.</p>
|
||||
*/
|
||||
public static final String PROTOCOL_ATTRIBUTE = HttpUpgrader.class.getName() + ".protocol";
|
||||
|
||||
/**
|
||||
* <p>Prepares the request for the upgrade, for example by setting the HTTP method
|
||||
* or by setting HTTP headers required for the upgrade.</p>
|
||||
*
|
||||
* @param request the request to prepare
|
||||
*/
|
||||
public void prepare(HttpRequest request);
|
||||
public void prepare(Request request);
|
||||
|
||||
/**
|
||||
* <p>Upgrades the given {@code endPoint} to a different protocol.</p>
|
||||
|
@ -48,7 +53,7 @@ public interface HttpUpgrader
|
|||
* @param endPoint the EndPoint to upgrade
|
||||
* @param callback a callback to notify of the success or failure of the upgrade
|
||||
*/
|
||||
public void upgrade(HttpResponse response, EndPoint endPoint, Callback callback);
|
||||
public void upgrade(Response response, EndPoint endPoint, Callback callback);
|
||||
|
||||
/**
|
||||
* <p>A factory for {@link HttpUpgrader}s.</p>
|
||||
|
|
|
@ -11,11 +11,10 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.io.RetainableByteBufferPool;
|
||||
import org.eclipse.jetty.io.content.InputStreamContentSource;
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
@ -30,10 +30,7 @@ import java.util.concurrent.TimeoutException;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Response.Listener;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.Response.Listener;
|
||||
import org.eclipse.jetty.io.Content;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.eclipse.jetty.util.thread.AutoLock;
|
|
@ -13,8 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.LeakDetector;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -33,9 +31,9 @@ public class LeakTrackingConnectionPool extends DuplexConnectionPool
|
|||
}
|
||||
};
|
||||
|
||||
public LeakTrackingConnectionPool(HttpDestination destination, int maxConnections, Callback requester)
|
||||
public LeakTrackingConnectionPool(Destination destination, int maxConnections)
|
||||
{
|
||||
super(destination, maxConnections, requester);
|
||||
super(destination, maxConnections);
|
||||
addBean(leakDetector);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,8 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.MultiPart;
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Pool;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
|
@ -21,12 +20,12 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
|
|||
@ManagedObject
|
||||
public class MultiplexConnectionPool extends AbstractConnectionPool
|
||||
{
|
||||
public MultiplexConnectionPool(HttpDestination destination, int maxConnections, Callback requester, int initialMaxMultiplex)
|
||||
public MultiplexConnectionPool(Destination destination, int maxConnections, int initialMaxMultiplex)
|
||||
{
|
||||
this(destination, Pool.StrategyType.FIRST, maxConnections, false, requester, initialMaxMultiplex);
|
||||
this(destination, Pool.StrategyType.FIRST, maxConnections, false, initialMaxMultiplex);
|
||||
}
|
||||
|
||||
protected MultiplexConnectionPool(HttpDestination destination, Pool.StrategyType strategy, int maxConnections, boolean cache, Callback requester, int initialMaxMultiplex)
|
||||
protected MultiplexConnectionPool(Destination destination, Pool.StrategyType strategy, int maxConnections, boolean cache, int initialMaxMultiplex)
|
||||
{
|
||||
super(destination, new Pool<>(strategy, maxConnections, cache, connection ->
|
||||
{
|
||||
|
@ -34,7 +33,7 @@ public class MultiplexConnectionPool extends AbstractConnectionPool
|
|||
if (connection instanceof MaxMultiplexable maxMultiplexable)
|
||||
maxMultiplex = maxMultiplexable.getMaxMultiplex();
|
||||
return maxMultiplex;
|
||||
}), requester, initialMaxMultiplex);
|
||||
}), initialMaxMultiplex);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportDynamic;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.HostPort;
|
||||
|
|
|
@ -11,12 +11,10 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.io.content.OutputStreamContentSource;
|
||||
|
||||
/**
|
|
@ -11,12 +11,11 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.io.RetainableByteBufferPool;
|
||||
import org.eclipse.jetty.io.content.PathContentSource;
|
||||
|
|
@ -15,10 +15,11 @@ package org.eclipse.jetty.client;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||
import org.eclipse.jetty.client.internal.HttpContentResponse;
|
||||
import org.eclipse.jetty.client.internal.HttpConversation;
|
||||
import org.eclipse.jetty.client.internal.HttpExchange;
|
||||
import org.eclipse.jetty.client.internal.HttpRequest;
|
||||
import org.eclipse.jetty.client.internal.ResponseNotifier;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
|
||||
/**
|
||||
* <p>A protocol handler performs HTTP protocol operations on
|
||||
* behalf of the application, typically like a browser would.</p>
|
||||
|
|
|
@ -17,8 +17,6 @@ import java.io.IOException;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,8 +15,7 @@ package org.eclipse.jetty.client;
|
|||
|
||||
import java.net.URI;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Map;
|
|||
import java.util.Objects;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.io.AbstractConnection;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
import org.eclipse.jetty.io.Connection;
|
||||
|
@ -79,7 +80,7 @@ public abstract class ProxyProtocolClientConnectionFactory implements ClientConn
|
|||
|
||||
/**
|
||||
* <p>PROXY protocol version 1 metadata holder to be used in conjunction
|
||||
* with {@link org.eclipse.jetty.client.api.Request#tag(Object)}.</p>
|
||||
* with {@link Request#tag(Object)}.</p>
|
||||
* <p>Instances of this class are associated to a destination so that
|
||||
* all connections of that destination will initiate the communication
|
||||
* with the PROXY protocol version 1 bytes specified by this metadata.</p>
|
||||
|
@ -228,7 +229,7 @@ public abstract class ProxyProtocolClientConnectionFactory implements ClientConn
|
|||
|
||||
/**
|
||||
* <p>PROXY protocol version 2 metadata holder to be used in conjunction
|
||||
* with {@link org.eclipse.jetty.client.api.Request#tag(Object)}.</p>
|
||||
* with {@link Request#tag(Object)}.</p>
|
||||
* <p>Instances of this class are associated to a destination so that
|
||||
* all connections of that destination will initiate the communication
|
||||
* with the PROXY protocol version 2 bytes specified by this metadata.</p>
|
||||
|
@ -461,7 +462,7 @@ public abstract class ProxyProtocolClientConnectionFactory implements ClientConn
|
|||
|
||||
protected abstract static class ProxyProtocolConnection extends AbstractConnection implements Callback
|
||||
{
|
||||
protected static final Logger LOG = LoggerFactory.getLogger(ProxyProtocolConnection.class);
|
||||
static final Logger LOG = LoggerFactory.getLogger(ProxyProtocolConnection.class);
|
||||
|
||||
private final ClientConnectionFactory factory;
|
||||
private final Map<String, Object> context;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Pool;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
|
||||
|
@ -24,8 +23,8 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
|
|||
@ManagedObject
|
||||
public class RandomConnectionPool extends MultiplexConnectionPool
|
||||
{
|
||||
public RandomConnectionPool(HttpDestination destination, int maxConnections, Callback requester, int maxMultiplex)
|
||||
public RandomConnectionPool(Destination destination, int maxConnections, int maxMultiplex)
|
||||
{
|
||||
super(destination, Pool.StrategyType.RANDOM, maxConnections, false, requester, maxMultiplex);
|
||||
super(destination, Pool.StrategyType.RANDOM, maxConnections, false, maxMultiplex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,9 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.api;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpCookie;
|
||||
|
@ -30,8 +30,6 @@ import java.util.function.BiFunction;
|
|||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.util.InputStreamResponseListener;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
|
@ -11,14 +11,13 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.api;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.jetty.client.util.BufferingResponseListener;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
|
@ -44,7 +43,7 @@ public interface Response
|
|||
/**
|
||||
* @param listenerClass the listener class
|
||||
* @param <T> the type of class
|
||||
* @return the response listener passed to {@link org.eclipse.jetty.client.api.Request#send(org.eclipse.jetty.client.api.Response.CompleteListener)}
|
||||
* @return the response listener passed to {@link Request#send(Response.CompleteListener)}
|
||||
*/
|
||||
<T extends ResponseListener> List<T> getListeners(Class<T> listenerClass);
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.api;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
/**
|
||||
* The result of a request / response exchange, containing the {@link Request}, the {@link Response}
|
|
@ -13,7 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.Pool;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
|
||||
|
@ -44,14 +43,14 @@ import org.eclipse.jetty.util.annotation.ManagedObject;
|
|||
@ManagedObject
|
||||
public class RoundRobinConnectionPool extends MultiplexConnectionPool
|
||||
{
|
||||
public RoundRobinConnectionPool(HttpDestination destination, int maxConnections, Callback requester)
|
||||
public RoundRobinConnectionPool(Destination destination, int maxConnections)
|
||||
{
|
||||
this(destination, maxConnections, requester, 1);
|
||||
this(destination, maxConnections, 1);
|
||||
}
|
||||
|
||||
public RoundRobinConnectionPool(HttpDestination destination, int maxConnections, Callback requester, int maxMultiplex)
|
||||
public RoundRobinConnectionPool(Destination destination, int maxConnections, int maxMultiplex)
|
||||
{
|
||||
super(destination, Pool.StrategyType.ROUND_ROBIN, maxConnections, false, requester, maxMultiplex);
|
||||
super(destination, Pool.StrategyType.ROUND_ROBIN, maxConnections, false, maxMultiplex);
|
||||
// If there are queued requests and connections get
|
||||
// closed due to idle timeout or overuse, we want to
|
||||
// aggressively try to open new connections to replace
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
@ -30,10 +30,6 @@ import javax.security.auth.login.Configuration;
|
|||
import javax.security.auth.login.LoginContext;
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
import org.ietf.jgss.GSSContext;
|
|
@ -23,7 +23,7 @@ import java.util.concurrent.TimeoutException;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.io.AbstractConnection;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
|
@ -207,7 +207,7 @@ public class Socks4Proxy extends ProxyConfiguration.Proxy
|
|||
context.put(ClientConnector.REMOTE_SOCKET_ADDRESS_CONTEXT_KEY, address);
|
||||
ClientConnectionFactory connectionFactory = this.connectionFactory;
|
||||
if (destination.isSecure())
|
||||
connectionFactory = destination.newSslClientConnectionFactory(null, connectionFactory);
|
||||
connectionFactory = destination.getHttpClient().newSslClientConnectionFactory(null, connectionFactory);
|
||||
org.eclipse.jetty.io.Connection newConnection = connectionFactory.newConnection(getEndPoint(), context);
|
||||
getEndPoint().upgrade(newConnection);
|
||||
if (LOG.isDebugEnabled())
|
||||
|
|
|
@ -11,13 +11,11 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.util;
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
|
||||
/**
|
||||
* <p>A {@link Request.Content} for strings.</p>
|
||||
* <p>It is possible to specify, at the constructor, an encoding used to convert
|
|
@ -1,40 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
/**
|
||||
* <p>Implementations of this interface expose a lock object
|
||||
* via {@link #getLock()} so that callers can synchronize
|
||||
* externally on that lock:</p>
|
||||
* <pre>
|
||||
* if (iterator instanceof Synchronizable)
|
||||
* {
|
||||
* Object element = null;
|
||||
* synchronized (((Synchronizable)iterator).getLock())
|
||||
* {
|
||||
* if (iterator.hasNext())
|
||||
* element = iterator.next();
|
||||
* }
|
||||
* }
|
||||
* </pre>
|
||||
* <p>In the example above, the calls to {@code hasNext()} and
|
||||
* {@code next()} are performed "atomically".</p>
|
||||
*/
|
||||
public interface Synchronizable
|
||||
{
|
||||
/**
|
||||
* @return the lock object to synchronize on
|
||||
*/
|
||||
public Object getLock();
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.io.CyclicTimeout;
|
||||
import org.eclipse.jetty.io.CyclicTimeouts;
|
||||
import org.eclipse.jetty.util.NanoTime;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* @deprecated Do not use it, use {@link CyclicTimeouts} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public class TimeoutCompleteListener extends CyclicTimeout implements Response.CompleteListener
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(TimeoutCompleteListener.class);
|
||||
|
||||
private final AtomicReference<Request> requestTimeout = new AtomicReference<>();
|
||||
|
||||
public TimeoutCompleteListener(Scheduler scheduler)
|
||||
{
|
||||
super(scheduler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTimeoutExpired()
|
||||
{
|
||||
Request request = requestTimeout.getAndSet(null);
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Total timeout {} ms elapsed for {} on {}", request.getTimeout(), request, this);
|
||||
if (request != null)
|
||||
request.abort(new TimeoutException("Total timeout " + request.getTimeout() + " ms elapsed"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onComplete(Result result)
|
||||
{
|
||||
Request request = requestTimeout.getAndSet(null);
|
||||
if (request != null)
|
||||
{
|
||||
boolean cancelled = cancel();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Cancelled ({}) timeout for {} on {}", cancelled, request, this);
|
||||
}
|
||||
}
|
||||
|
||||
void schedule(HttpRequest request, long timeoutAt)
|
||||
{
|
||||
if (requestTimeout.compareAndSet(null, request))
|
||||
{
|
||||
long delay = Math.max(0, NanoTime.until(timeoutAt));
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Scheduling timeout in {} ms for {} on {}", TimeUnit.NANOSECONDS.toMillis(delay), request, this);
|
||||
schedule(delay, TimeUnit.NANOSECONDS);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,9 +15,10 @@ package org.eclipse.jetty.client;
|
|||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.internal.HttpConversation;
|
||||
import org.eclipse.jetty.client.internal.HttpRequest;
|
||||
import org.eclipse.jetty.client.internal.HttpResponse;
|
||||
import org.eclipse.jetty.client.internal.ResponseNotifier;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
|
|
@ -19,8 +19,6 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.NanoTime;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.component.Dumpable;
|
||||
|
@ -60,9 +58,9 @@ public class ValidatingConnectionPool extends DuplexConnectionPool
|
|||
private final long timeout;
|
||||
private final Map<Connection, Holder> quarantine;
|
||||
|
||||
public ValidatingConnectionPool(HttpDestination destination, int maxConnections, Callback requester, Scheduler scheduler, long timeout)
|
||||
public ValidatingConnectionPool(Destination destination, int maxConnections, Scheduler scheduler, long timeout)
|
||||
{
|
||||
super(destination, maxConnections, requester);
|
||||
super(destination, maxConnections);
|
||||
this.scheduler = scheduler;
|
||||
this.timeout = timeout;
|
||||
this.quarantine = new ConcurrentHashMap<>(maxConnections);
|
||||
|
|
|
@ -15,8 +15,6 @@ package org.eclipse.jetty.client;
|
|||
|
||||
import java.net.URI;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
||||
|
|
|
@ -1,61 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.api;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.util.FuturePromise;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
|
||||
/**
|
||||
* {@link Destination} represents the triple made of the {@link #getScheme}, the {@link #getHost}
|
||||
* and the {@link #getPort}.
|
||||
* <p>
|
||||
* {@link Destination} holds a pool of {@link Connection}s, but allows to create unpooled
|
||||
* connections if the application wants full control over connection management via {@link #newConnection(Promise)}.
|
||||
* <p>
|
||||
* {@link Destination}s may be obtained via {@link HttpClient#resolveDestination(Request)}
|
||||
*/
|
||||
public interface Destination
|
||||
{
|
||||
/**
|
||||
* @return the scheme of this destination, such as "http" or "https"
|
||||
*/
|
||||
String getScheme();
|
||||
|
||||
/**
|
||||
* @return the host of this destination, such as "127.0.0.1" or "google.com"
|
||||
*/
|
||||
String getHost();
|
||||
|
||||
/**
|
||||
* @return the port of this destination such as 80 or 443
|
||||
*/
|
||||
int getPort();
|
||||
|
||||
/**
|
||||
* Creates asynchronously a new, unpooled, {@link Connection} that will be returned
|
||||
* at a later time through the given {@link Promise}.
|
||||
* <p>
|
||||
* Use {@link FuturePromise} to wait for the connection:
|
||||
* <pre>
|
||||
* Destination destination = ...;
|
||||
* FuturePromise<Connection> futureConnection = new FuturePromise<>();
|
||||
* destination.newConnection(futureConnection);
|
||||
* Connection connection = futureConnection.get(5, TimeUnit.SECONDS);
|
||||
* </pre>
|
||||
*
|
||||
* @param promise the promise of a new, unpooled, {@link Connection}
|
||||
*/
|
||||
void newConnection(Promise<Connection> promise);
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
@ -19,9 +19,9 @@ import java.util.Map;
|
|||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
import org.eclipse.jetty.client.api.Authentication;
|
||||
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||
import org.eclipse.jetty.client.util.AbstractAuthentication;
|
||||
import org.eclipse.jetty.client.AbstractAuthentication;
|
||||
import org.eclipse.jetty.client.Authentication;
|
||||
import org.eclipse.jetty.client.AuthenticationStore;
|
||||
|
||||
public class HttpAuthenticationStore implements AuthenticationStore
|
||||
{
|
|
@ -11,9 +11,9 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.Result;
|
||||
import org.eclipse.jetty.io.CyclicTimeouts;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.thread.AutoLock;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.net.CookieStore;
|
||||
import java.net.HttpCookie;
|
||||
|
@ -21,11 +21,15 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.client.api.Authentication;
|
||||
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.util.BytesRequestContent;
|
||||
import org.eclipse.jetty.client.Authentication;
|
||||
import org.eclipse.jetty.client.AuthenticationStore;
|
||||
import org.eclipse.jetty.client.BytesRequestContent;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpProxy;
|
||||
import org.eclipse.jetty.client.HttpRequestException;
|
||||
import org.eclipse.jetty.client.ProxyConfiguration;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -19,9 +19,9 @@ import java.nio.charset.UnsupportedCharsetException;
|
|||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
|
|
@ -11,15 +11,17 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.AuthenticationProtocolHandler;
|
||||
import org.eclipse.jetty.client.RedirectProtocolHandler;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.util.AttributesMap;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.slf4j.Logger;
|
|
@ -11,9 +11,8 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.AsynchronousCloseException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -23,10 +22,14 @@ import java.util.Queue;
|
|||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.api.Destination;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.Connection;
|
||||
import org.eclipse.jetty.client.ConnectionPool;
|
||||
import org.eclipse.jetty.client.Destination;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.Origin;
|
||||
import org.eclipse.jetty.client.ProxyConfiguration;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
|
@ -50,7 +53,7 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ManagedObject
|
||||
public class HttpDestination extends ContainerLifeCycle implements Destination, Closeable, Callback, Dumpable, Sweeper.Sweepable
|
||||
public class HttpDestination extends ContainerLifeCycle implements Destination, Callback, Dumpable, Sweeper.Sweepable
|
||||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HttpDestination.class);
|
||||
|
||||
|
@ -112,7 +115,7 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
|
||||
public boolean stale()
|
||||
{
|
||||
try (AutoLock l = staleLock.lock())
|
||||
try (AutoLock ignored = staleLock.lock())
|
||||
{
|
||||
boolean stale = this.stale;
|
||||
if (!stale)
|
||||
|
@ -129,7 +132,7 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Sweep check in progress on {}", this);
|
||||
boolean remove = false;
|
||||
try (AutoLock l = staleLock.lock())
|
||||
try (AutoLock ignored = staleLock.lock())
|
||||
{
|
||||
boolean stale = exchanges.isEmpty() && connectionPool.isEmpty();
|
||||
if (!stale)
|
||||
|
@ -161,22 +164,19 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
Sweeper connectionPoolSweeper = client.getBean(Sweeper.class);
|
||||
if (connectionPoolSweeper != null && connectionPool instanceof Sweeper.Sweepable)
|
||||
connectionPoolSweeper.offer((Sweeper.Sweepable)connectionPool);
|
||||
Sweeper destinationSweeper = getHttpClient().getDestinationSweeper();
|
||||
if (destinationSweeper != null)
|
||||
destinationSweeper.offer(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
Sweeper destinationSweeper = getHttpClient().getDestinationSweeper();
|
||||
if (destinationSweeper != null)
|
||||
destinationSweeper.remove(this);
|
||||
requestTimeouts.destroy();
|
||||
abort(new AsynchronousCloseException());
|
||||
Sweeper connectionPoolSweeper = client.getBean(Sweeper.class);
|
||||
if (connectionPoolSweeper != null && connectionPool instanceof Sweeper.Sweepable)
|
||||
connectionPoolSweeper.remove((Sweeper.Sweepable)connectionPool);
|
||||
super.doStop();
|
||||
removeBean(connectionPool);
|
||||
connectionPool.close();
|
||||
}
|
||||
|
||||
protected ConnectionPool newConnectionPool(HttpClient client)
|
||||
|
@ -192,21 +192,24 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
return new BlockingArrayQueue<>(maxCapacity);
|
||||
}
|
||||
|
||||
protected ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory)
|
||||
private ClientConnectionFactory newSslClientConnectionFactory(SslContextFactory.Client sslContextFactory, ClientConnectionFactory connectionFactory)
|
||||
{
|
||||
return client.newSslClientConnectionFactory(sslContextFactory, connectionFactory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure()
|
||||
{
|
||||
return HttpClient.isSchemeSecure(getScheme());
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpClient getHttpClient()
|
||||
{
|
||||
return client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Origin getOrigin()
|
||||
{
|
||||
return origin;
|
||||
|
@ -227,6 +230,7 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
return responseNotifier;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProxyConfiguration.Proxy getProxy()
|
||||
{
|
||||
return proxy;
|
||||
|
@ -237,14 +241,12 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
return connectionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ManagedAttribute(value = "The destination scheme", readonly = true)
|
||||
public String getScheme()
|
||||
{
|
||||
return getOrigin().getScheme();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ManagedAttribute(value = "The destination host", readonly = true)
|
||||
public String getHost()
|
||||
{
|
||||
|
@ -253,7 +255,6 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
return getOrigin().getAddress().getHost();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ManagedAttribute(value = "The destination port", readonly = true)
|
||||
public int getPort()
|
||||
{
|
||||
|
@ -266,11 +267,6 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
return exchanges.size();
|
||||
}
|
||||
|
||||
public Origin.Address getConnectAddress()
|
||||
{
|
||||
return proxy == null ? getOrigin().getAddress() : proxy.getAddress();
|
||||
}
|
||||
|
||||
public HttpField getHostField()
|
||||
{
|
||||
return hostField;
|
||||
|
@ -294,12 +290,13 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
abort(x);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void send(Request request, Response.CompleteListener listener)
|
||||
{
|
||||
((HttpRequest)request).sendAsync(this, listener);
|
||||
}
|
||||
|
||||
protected void send(HttpRequest request, List<Response.ResponseListener> listeners)
|
||||
void send(HttpRequest request, List<Response.ResponseListener> listeners)
|
||||
{
|
||||
send(new HttpExchange(this, request, listeners));
|
||||
}
|
||||
|
@ -456,16 +453,6 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
return exchanges.remove(exchange);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
abort(new AsynchronousCloseException());
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Closed {}", this);
|
||||
connectionPool.close();
|
||||
requestTimeouts.destroy();
|
||||
}
|
||||
|
||||
public void release(Connection connection)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -547,7 +534,7 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
{
|
||||
if (getHttpClient().getDestinationIdleTimeout() <= 0L)
|
||||
return -1;
|
||||
try (AutoLock l = staleLock.lock())
|
||||
try (AutoLock ignored = staleLock.lock())
|
||||
{
|
||||
return NanoTime.millisSince(activeNanoTime);
|
||||
}
|
||||
|
@ -556,7 +543,7 @@ public class HttpDestination extends ContainerLifeCycle implements Destination,
|
|||
@ManagedAttribute("Whether this destinations is stale")
|
||||
public boolean isStale()
|
||||
{
|
||||
try (AutoLock l = staleLock.lock())
|
||||
try (AutoLock ignored = staleLock.lock())
|
||||
{
|
||||
return this.stale;
|
||||
}
|
|
@ -11,13 +11,13 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.client.Result;
|
||||
import org.eclipse.jetty.io.CyclicTimeouts;
|
||||
import org.eclipse.jetty.util.Promise;
|
||||
import org.eclipse.jetty.util.thread.AutoLock;
|
|
@ -11,19 +11,18 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.ContentDecoder;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.ProtocolHandler;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.client.Result;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
@ -131,7 +130,7 @@ public abstract class HttpReceiver
|
|||
* Subclasses must have set the response status code on the {@link Response} object of the {@link HttpExchange}
|
||||
* prior invoking this method.
|
||||
* <p>
|
||||
* This method takes case of notifying {@link org.eclipse.jetty.client.api.Response.BeginListener}s.
|
||||
* This method takes case of notifying {@link Response.BeginListener}s.
|
||||
*
|
||||
* @param exchange the HTTP exchange
|
||||
*/
|
||||
|
@ -176,7 +175,7 @@ public abstract class HttpReceiver
|
|||
* Subclasses must not have added the header to the {@link Response} object of the {@link HttpExchange}
|
||||
* prior invoking this method.
|
||||
* <p>
|
||||
* This method takes case of notifying {@link org.eclipse.jetty.client.api.Response.HeaderListener}s and storing cookies.
|
||||
* This method takes case of notifying {@link Response.HeaderListener}s and storing cookies.
|
||||
*
|
||||
* @param exchange the HTTP exchange
|
||||
* @param field the response HTTP field
|
||||
|
@ -223,27 +222,13 @@ public abstract class HttpReceiver
|
|||
|
||||
protected void storeCookie(URI uri, HttpField field)
|
||||
{
|
||||
try
|
||||
{
|
||||
String value = field.getValue();
|
||||
if (value != null)
|
||||
{
|
||||
Map<String, List<String>> header = new HashMap<>(1);
|
||||
header.put(field.getHeader().asString(), Collections.singletonList(value));
|
||||
getHttpDestination().getHttpClient().getCookieManager().put(uri, header);
|
||||
}
|
||||
}
|
||||
catch (IOException x)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Unable to store cookies {} from {}", field, uri, x);
|
||||
}
|
||||
getHttpDestination().getHttpClient().putCookie(uri, field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to be invoked after all response HTTP headers are available.
|
||||
* <p>
|
||||
* This method takes care of notifying {@link org.eclipse.jetty.client.api.Response.HeadersListener}s.
|
||||
* This method takes care of notifying {@link Response.HeadersListener}s.
|
||||
*
|
||||
* @param exchange the HTTP exchange
|
||||
*/
|
||||
|
@ -331,8 +316,8 @@ public abstract class HttpReceiver
|
|||
/**
|
||||
* Method to be invoked when the response is successful.
|
||||
* <p>
|
||||
* This method takes care of notifying {@link org.eclipse.jetty.client.api.Response.SuccessListener}s and possibly
|
||||
* {@link org.eclipse.jetty.client.api.Response.CompleteListener}s (if the exchange is completed).
|
||||
* This method takes care of notifying {@link Response.SuccessListener}s and possibly
|
||||
* {@link Response.CompleteListener}s (if the exchange is completed).
|
||||
*
|
||||
* @param exchange the HTTP exchange
|
||||
* @param afterSuccessTask an optional task to invoke afterwards
|
||||
|
@ -376,7 +361,7 @@ public abstract class HttpReceiver
|
|||
/**
|
||||
* Method to be invoked when the response is failed.
|
||||
* <p>
|
||||
* This method takes care of notifying {@link org.eclipse.jetty.client.api.Response.FailureListener}s.
|
||||
* This method takes care of notifying {@link Response.FailureListener}s.
|
||||
*
|
||||
* @param failure the response failure
|
||||
*/
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpCookie;
|
||||
|
@ -35,17 +35,19 @@ import java.util.concurrent.ExecutionException;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.FutureResponseListener;
|
||||
import org.eclipse.jetty.client.util.PathRequestContent;
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.client.Destination;
|
||||
import org.eclipse.jetty.client.FutureResponseListener;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.Origin;
|
||||
import org.eclipse.jetty.client.PathRequestContent;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.client.Result;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
|
@ -84,11 +86,10 @@ public class HttpRequest implements Request
|
|||
private List<RequestListener> requestListeners;
|
||||
private BiFunction<Request, Request, Response.CompleteListener> pushHandler;
|
||||
private Supplier<HttpFields> trailers;
|
||||
private String upgradeProtocol;
|
||||
private Object tag;
|
||||
private boolean normalized;
|
||||
|
||||
protected HttpRequest(HttpClient client, HttpConversation conversation, URI uri)
|
||||
public HttpRequest(HttpClient client, HttpConversation conversation, URI uri)
|
||||
{
|
||||
this.client = client;
|
||||
this.conversation = conversation;
|
||||
|
@ -100,7 +101,7 @@ public class HttpRequest implements Request
|
|||
extractParams(query);
|
||||
|
||||
followRedirects(client.isFollowRedirects());
|
||||
HttpField acceptEncodingField = client.getAcceptEncodingField();
|
||||
HttpField acceptEncodingField = client.getContentDecoderFactories().getAcceptEncodingField();
|
||||
if (acceptEncodingField != null)
|
||||
headers.put(acceptEncodingField);
|
||||
HttpField userAgentField = client.getUserAgentField();
|
||||
|
@ -627,12 +628,6 @@ public class HttpRequest implements Request
|
|||
return this;
|
||||
}
|
||||
|
||||
public HttpRequest upgradeProtocol(String upgradeProtocol)
|
||||
{
|
||||
this.upgradeProtocol = upgradeProtocol;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Content getBody()
|
||||
{
|
||||
|
@ -740,19 +735,15 @@ public class HttpRequest implements Request
|
|||
@Override
|
||||
public void send(Response.CompleteListener listener)
|
||||
{
|
||||
sendAsync(client::send, listener);
|
||||
Destination destination = client.resolveDestination(this);
|
||||
destination.send(this, listener);
|
||||
}
|
||||
|
||||
void sendAsync(HttpDestination destination, Response.CompleteListener listener)
|
||||
{
|
||||
sendAsync(destination::send, listener);
|
||||
}
|
||||
|
||||
private void sendAsync(BiConsumer<HttpRequest, List<Response.ResponseListener>> sender, Response.CompleteListener listener)
|
||||
{
|
||||
if (listener != null)
|
||||
responseListeners.add(listener);
|
||||
sender.accept(this, responseListeners);
|
||||
destination.send(this, responseListeners);
|
||||
}
|
||||
|
||||
void sent()
|
||||
|
@ -769,7 +760,7 @@ public class HttpRequest implements Request
|
|||
* @return The nanoTime at which the timeout expires or {@link Long#MAX_VALUE} if there is no timeout.
|
||||
* @see #timeout(long, TimeUnit)
|
||||
*/
|
||||
long getTimeoutNanoTime()
|
||||
public long getTimeoutNanoTime()
|
||||
{
|
||||
return timeoutNanoTime;
|
||||
}
|
||||
|
@ -790,11 +781,6 @@ public class HttpRequest implements Request
|
|||
return trailers;
|
||||
}
|
||||
|
||||
public String getUpgradeProtocol()
|
||||
{
|
||||
return upgradeProtocol;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Boolean> abort(Throwable cause)
|
||||
{
|
|
@ -11,15 +11,15 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -19,8 +19,8 @@ import java.util.concurrent.Executor;
|
|||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Result;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpHeaderValue;
|
||||
import org.eclipse.jetty.io.Content;
|
|
@ -11,9 +11,9 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.Connection;
|
||||
|
||||
public interface IConnection extends Connection
|
||||
{
|
|
@ -11,12 +11,13 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Iterator;
|
||||
|
@ -19,10 +19,10 @@ import java.util.List;
|
|||
import java.util.Objects;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.ContentResponse;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.client.Result;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.io.Content;
|
||||
import org.eclipse.jetty.io.content.ByteBufferContentSource;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
public class SendFailure
|
||||
{
|
|
@ -11,8 +11,17 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
/**
|
||||
* Jetty Client : API Classes
|
||||
*/
|
||||
package org.eclipse.jetty.client.api;
|
||||
package org.eclipse.jetty.client.internal;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.Origin;
|
||||
|
||||
public class TunnelRequest extends HttpRequest
|
||||
{
|
||||
public TunnelRequest(HttpClient client, Origin.Address address)
|
||||
{
|
||||
super(client, new HttpConversation(), URI.create("http://" + address.asString()));
|
||||
}
|
||||
}
|
|
@ -1,45 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
/**
|
||||
* Jetty Client : Implementation and Core Classes
|
||||
*
|
||||
* This package provides APIs, utility classes and an implementation of an asynchronous HTTP client.
|
||||
* <p>
|
||||
* The core class is {@link org.eclipse.jetty.client.HttpClient}, which acts as a central configuration object (for example
|
||||
* for {@link org.eclipse.jetty.client.HttpClient#setIdleTimeout(long) idle timeouts}, {@link org.eclipse.jetty.client.HttpClient#setMaxConnectionsPerDestination(int)
|
||||
* max connections per destination}, etc.) and as a factory for {@link org.eclipse.jetty.client.api.Request} objects.
|
||||
* <p>
|
||||
* The HTTP protocol is based on the request/response paradigm, a unit that in this implementation is called
|
||||
* <em>exchange</em> and is represented by {@link org.eclipse.jetty.client.HttpExchange}.
|
||||
* An initial request may trigger a sequence of exchanges with one or more servers, called a <em>conversation</em>
|
||||
* and represented by {@link org.eclipse.jetty.client.HttpConversation}. A typical example of a conversation is a redirect, where
|
||||
* upon a request for a resource URI, the server replies with a redirect (for example with the 303 status code)
|
||||
* to another URI. This conversation is made of a first exchange made of the original request and its 303 response,
|
||||
* and of a second exchange made of the request for the new URI and its 200 response.
|
||||
* <p>
|
||||
* {@link org.eclipse.jetty.client.HttpClient} holds a number of {@link org.eclipse.jetty.client.api.Destination destinations}, which in turn hold a number of
|
||||
* pooled {@link org.eclipse.jetty.client.api.Connection connections}.
|
||||
* <p>
|
||||
* When a request is sent, its exchange is associated to a connection, either taken from an idle queue or created
|
||||
* anew, and when both the request and response are completed, the exchange is disassociated from the connection.
|
||||
* Conversations may span multiple connections on different destinations, and therefore are maintained at the
|
||||
* {@link org.eclipse.jetty.client.HttpClient} level.
|
||||
* <p>
|
||||
* Applications may decide to send the request and wait for the response in a blocking way, using
|
||||
* {@link org.eclipse.jetty.client.api.Request#send()}.
|
||||
* Alternatively, application may ask to be notified of response events asynchronously, using
|
||||
* {@link org.eclipse.jetty.client.api.Request#send(org.eclipse.jetty.client.api.Response.CompleteListener)}.
|
||||
*/
|
||||
package org.eclipse.jetty.client;
|
||||
|
|
@ -11,12 +11,12 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.http;
|
||||
package org.eclipse.jetty.client.transport;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic;
|
||||
import org.eclipse.jetty.client.transport.internal.HttpConnectionOverHTTP;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.dynamic;
|
||||
package org.eclipse.jetty.client.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
|
@ -27,13 +27,14 @@ import java.util.stream.Stream;
|
|||
import org.eclipse.jetty.alpn.client.ALPNClientConnection;
|
||||
import org.eclipse.jetty.alpn.client.ALPNClientConnectionFactory;
|
||||
import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport;
|
||||
import org.eclipse.jetty.client.Destination;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpClientTransport;
|
||||
import org.eclipse.jetty.client.HttpDestination;
|
||||
import org.eclipse.jetty.client.HttpRequest;
|
||||
import org.eclipse.jetty.client.MultiplexConnectionPool;
|
||||
import org.eclipse.jetty.client.Origin;
|
||||
import org.eclipse.jetty.client.http.HttpClientConnectionFactory;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.client.internal.HttpRequest;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
|
@ -76,7 +77,7 @@ import org.slf4j.LoggerFactory;
|
|||
* Therefore a destination is identified by a {@link org.eclipse.jetty.client.Origin} and
|
||||
* applications can customize the creation of the origin (for example depending on request protocol
|
||||
* version, or request headers, or request attributes, or even request path) by overriding
|
||||
* {@link HttpClientTransport#newOrigin(HttpRequest)}.</p>
|
||||
* {@link HttpClientTransport#newOrigin(Request)}.</p>
|
||||
*/
|
||||
public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTransport
|
||||
{
|
||||
|
@ -117,7 +118,7 @@ public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTrans
|
|||
.collect(Collectors.toList());
|
||||
Arrays.stream(factoryInfos).forEach(this::addBean);
|
||||
setConnectionPoolFactory(destination ->
|
||||
new MultiplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), destination, 1));
|
||||
new MultiplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), 1));
|
||||
}
|
||||
|
||||
private static ClientConnector findClientConnector(ClientConnectionFactory.Info[] infos)
|
||||
|
@ -129,13 +130,13 @@ public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTrans
|
|||
}
|
||||
|
||||
@Override
|
||||
public Origin newOrigin(HttpRequest request)
|
||||
public Origin newOrigin(Request request)
|
||||
{
|
||||
boolean secure = HttpClient.isSchemeSecure(request.getScheme());
|
||||
String http1 = "http/1.1";
|
||||
String http2 = secure ? "h2" : "h2c";
|
||||
List<String> protocols = List.of();
|
||||
if (request.isVersionExplicit())
|
||||
if (((HttpRequest)request).isVersionExplicit())
|
||||
{
|
||||
HttpVersion version = request.getVersion();
|
||||
String desired = version == HttpVersion.HTTP_2 ? http2 : http1;
|
||||
|
@ -175,7 +176,7 @@ public class HttpClientTransportDynamic extends AbstractConnectorHttpClientTrans
|
|||
}
|
||||
|
||||
@Override
|
||||
public HttpDestination newHttpDestination(Origin origin)
|
||||
public Destination newDestination(Origin origin)
|
||||
{
|
||||
SocketAddress address = origin.getAddress().getSocketAddress();
|
||||
return new HttpDestination(getHttpClient(), origin, getClientConnector().isIntrinsicallySecure(address));
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.http;
|
||||
package org.eclipse.jetty.client.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
|
@ -19,10 +19,11 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.client.AbstractConnectorHttpClientTransport;
|
||||
import org.eclipse.jetty.client.Destination;
|
||||
import org.eclipse.jetty.client.DuplexConnectionPool;
|
||||
import org.eclipse.jetty.client.HttpDestination;
|
||||
import org.eclipse.jetty.client.HttpRequest;
|
||||
import org.eclipse.jetty.client.Origin;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.io.ClientConnectionFactory;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
|
@ -56,17 +57,17 @@ public class HttpClientTransportOverHTTP extends AbstractConnectorHttpClientTran
|
|||
public HttpClientTransportOverHTTP(ClientConnector connector)
|
||||
{
|
||||
super(connector);
|
||||
setConnectionPoolFactory(destination -> new DuplexConnectionPool(destination, getHttpClient().getMaxConnectionsPerDestination(), destination));
|
||||
setConnectionPoolFactory(destination -> new DuplexConnectionPool(destination, getHttpClient().getMaxConnectionsPerDestination()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Origin newOrigin(HttpRequest request)
|
||||
public Origin newOrigin(Request request)
|
||||
{
|
||||
return getHttpClient().createOrigin(request, HTTP11);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpDestination newHttpDestination(Origin origin)
|
||||
public Destination newDestination(Origin origin)
|
||||
{
|
||||
SocketAddress address = origin.getAddress().getSocketAddress();
|
||||
return new HttpDestination(getHttpClient(), origin, getClientConnector().isIntrinsicallySecure(address));
|
|
@ -11,14 +11,14 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.http;
|
||||
package org.eclipse.jetty.client.transport.internal;
|
||||
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
|
||||
import org.eclipse.jetty.client.HttpChannel;
|
||||
import org.eclipse.jetty.client.HttpExchange;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.client.Result;
|
||||
import org.eclipse.jetty.client.internal.HttpChannel;
|
||||
import org.eclipse.jetty.client.internal.HttpExchange;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpHeaderValue;
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.http;
|
||||
package org.eclipse.jetty.client.transport.internal;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.AsynchronousCloseException;
|
||||
|
@ -24,20 +24,20 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.LongAdder;
|
||||
|
||||
import org.eclipse.jetty.client.HttpChannel;
|
||||
import org.eclipse.jetty.client.Connection;
|
||||
import org.eclipse.jetty.client.HttpClientTransport;
|
||||
import org.eclipse.jetty.client.HttpConnection;
|
||||
import org.eclipse.jetty.client.HttpConversation;
|
||||
import org.eclipse.jetty.client.HttpDestination;
|
||||
import org.eclipse.jetty.client.HttpExchange;
|
||||
import org.eclipse.jetty.client.HttpProxy;
|
||||
import org.eclipse.jetty.client.HttpRequest;
|
||||
import org.eclipse.jetty.client.HttpUpgrader;
|
||||
import org.eclipse.jetty.client.IConnection;
|
||||
import org.eclipse.jetty.client.SendFailure;
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.client.internal.HttpChannel;
|
||||
import org.eclipse.jetty.client.internal.HttpConnection;
|
||||
import org.eclipse.jetty.client.internal.HttpConversation;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.client.internal.HttpExchange;
|
||||
import org.eclipse.jetty.client.internal.HttpRequest;
|
||||
import org.eclipse.jetty.client.internal.IConnection;
|
||||
import org.eclipse.jetty.client.internal.SendFailure;
|
||||
import org.eclipse.jetty.client.internal.TunnelRequest;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.io.AbstractConnection;
|
||||
|
@ -204,7 +204,7 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne
|
|||
void onResponseHeaders(HttpExchange exchange)
|
||||
{
|
||||
HttpRequest request = exchange.getRequest();
|
||||
if (request instanceof HttpProxy.TunnelRequest)
|
||||
if (request instanceof TunnelRequest)
|
||||
{
|
||||
// Restore idle timeout
|
||||
getEndPoint().setIdleTimeout(idleTimeout);
|
||||
|
@ -309,7 +309,7 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne
|
|||
{
|
||||
super.normalizeRequest(request);
|
||||
|
||||
if (request instanceof HttpProxy.TunnelRequest)
|
||||
if (request instanceof TunnelRequest)
|
||||
{
|
||||
// Override the idle timeout in case it is shorter than the connect timeout.
|
||||
request.idleTimeout(2 * getHttpClient().getConnectTimeout(), TimeUnit.MILLISECONDS);
|
||||
|
@ -319,9 +319,10 @@ public class HttpConnectionOverHTTP extends AbstractConnection implements IConne
|
|||
HttpUpgrader upgrader = (HttpUpgrader)conversation.getAttribute(HttpUpgrader.class.getName());
|
||||
if (upgrader == null)
|
||||
{
|
||||
if (request instanceof HttpUpgrader.Factory)
|
||||
HttpUpgrader.Factory upgraderFactory = (HttpUpgrader.Factory)request.getAttributes().get(HttpUpgrader.Factory.class.getName());
|
||||
if (upgraderFactory != null)
|
||||
{
|
||||
upgrader = ((HttpUpgrader.Factory)request).newHttpUpgrader(HttpVersion.HTTP_1_1);
|
||||
upgrader = upgraderFactory.newHttpUpgrader(HttpVersion.HTTP_1_1);
|
||||
conversation.setAttribute(HttpUpgrader.class.getName(), upgrader);
|
||||
upgrader.prepare(request);
|
||||
}
|
|
@ -11,7 +11,7 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.http;
|
||||
package org.eclipse.jetty.client.transport.internal;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
@ -19,10 +19,11 @@ import java.util.concurrent.atomic.LongAdder;
|
|||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpClientTransport;
|
||||
import org.eclipse.jetty.client.HttpExchange;
|
||||
import org.eclipse.jetty.client.HttpReceiver;
|
||||
import org.eclipse.jetty.client.HttpResponse;
|
||||
import org.eclipse.jetty.client.HttpResponseException;
|
||||
import org.eclipse.jetty.client.internal.HttpExchange;
|
||||
import org.eclipse.jetty.client.internal.HttpReceiver;
|
||||
import org.eclipse.jetty.client.internal.HttpResponse;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.http.BadMessageException;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
|
@ -11,15 +11,15 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.http;
|
||||
package org.eclipse.jetty.client.transport.internal;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpExchange;
|
||||
import org.eclipse.jetty.client.HttpRequest;
|
||||
import org.eclipse.jetty.client.HttpRequestException;
|
||||
import org.eclipse.jetty.client.HttpSender;
|
||||
import org.eclipse.jetty.client.internal.HttpExchange;
|
||||
import org.eclipse.jetty.client.internal.HttpRequest;
|
||||
import org.eclipse.jetty.client.internal.HttpSender;
|
||||
import org.eclipse.jetty.http.HttpGenerator;
|
||||
import org.eclipse.jetty.http.HttpURI;
|
||||
import org.eclipse.jetty.http.MetaData;
|
|
@ -11,21 +11,23 @@
|
|||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.client.http;
|
||||
package org.eclipse.jetty.client.transport.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.client.Destination;
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.HttpClientTransport;
|
||||
import org.eclipse.jetty.client.HttpDestination;
|
||||
import org.eclipse.jetty.client.HttpRequest;
|
||||
import org.eclipse.jetty.client.HttpResponse;
|
||||
import org.eclipse.jetty.client.HttpResponseException;
|
||||
import org.eclipse.jetty.client.HttpUpgrader;
|
||||
import org.eclipse.jetty.client.Origin;
|
||||
import org.eclipse.jetty.client.dynamic.HttpClientTransportDynamic;
|
||||
import org.eclipse.jetty.client.Request;
|
||||
import org.eclipse.jetty.client.Response;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.client.internal.HttpResponse;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportDynamic;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.io.EndPoint;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
|
@ -54,12 +56,12 @@ public class ProtocolHttpUpgrader implements HttpUpgrader
|
|||
}
|
||||
|
||||
@Override
|
||||
public void prepare(HttpRequest request)
|
||||
public void prepare(Request request)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upgrade(HttpResponse response, EndPoint endPoint, Callback callback)
|
||||
public void upgrade(Response response, EndPoint endPoint, Callback callback)
|
||||
{
|
||||
if (response.getHeaders().contains(HttpHeader.UPGRADE, protocol))
|
||||
{
|
||||
|
@ -71,7 +73,7 @@ public class ProtocolHttpUpgrader implements HttpUpgrader
|
|||
|
||||
Origin origin = destination.getOrigin();
|
||||
Origin newOrigin = new Origin(origin.getScheme(), origin.getAddress(), origin.getTag(), new Origin.Protocol(List.of(protocol), false));
|
||||
HttpDestination newDestination = httpClient.resolveDestination(newOrigin);
|
||||
Destination newDestination = httpClient.resolveDestination(newOrigin);
|
||||
|
||||
Map<String, Object> context = new HashMap<>();
|
||||
context.put(HttpClientTransport.HTTP_DESTINATION_CONTEXT_KEY, newDestination);
|
|
@ -1,18 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2022 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
/**
|
||||
* Jetty Client : Utility Classes
|
||||
*/
|
||||
package org.eclipse.jetty.client.util;
|
||||
|
|
@ -18,7 +18,7 @@ import java.util.function.Consumer;
|
|||
import java.util.function.Function;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
|
|
|
@ -18,10 +18,9 @@ import java.nio.ByteBuffer;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.http.HttpConnectionOverHTTP;
|
||||
import org.eclipse.jetty.client.util.AsyncRequestContent;
|
||||
import org.eclipse.jetty.client.util.StringRequestContent;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.client.internal.HttpResponse;
|
||||
import org.eclipse.jetty.client.transport.internal.HttpConnectionOverHTTP;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpHeaderValue;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
|
|
|
@ -13,8 +13,6 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
|
||||
public class ConnectionPoolHelper
|
||||
{
|
||||
public static Connection acquire(AbstractConnectionPool connectionPool, boolean create)
|
||||
|
|
|
@ -17,8 +17,7 @@ import java.util.HashSet;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.io.Content;
|
||||
|
@ -76,7 +75,7 @@ public class ConnectionPoolMaxUsageTest
|
|||
|
||||
String host = "localhost";
|
||||
int port = connector.getLocalPort();
|
||||
HttpDestination destination = httpClient.resolveDestination(new Origin("http", host, port, null, HttpClientTransportOverHTTP.HTTP11));
|
||||
Destination destination = httpClient.resolveDestination(new Origin("http", host, port, null, HttpClientTransportOverHTTP.HTTP11));
|
||||
AbstractConnectionPool connectionPool = (AbstractConnectionPool)destination.getConnectionPool();
|
||||
int maxUsage = 3;
|
||||
connectionPool.setMaxUsage(maxUsage);
|
||||
|
@ -119,7 +118,7 @@ public class ConnectionPoolMaxUsageTest
|
|||
|
||||
String host = "localhost";
|
||||
int port = connector.getLocalPort();
|
||||
HttpDestination destination = httpClient.resolveDestination(new Origin("http", host, port, null, HttpClientTransportOverHTTP.HTTP11));
|
||||
Destination destination = httpClient.resolveDestination(new Origin("http", host, port, null, HttpClientTransportOverHTTP.HTTP11));
|
||||
AbstractConnectionPool connectionPool = (AbstractConnectionPool)destination.getConnectionPool();
|
||||
int maxUsage = 3;
|
||||
connectionPool.setMaxUsage(maxUsage);
|
||||
|
|
|
@ -25,13 +25,8 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||
import java.util.stream.IntStream;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Destination;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.client.util.BytesRequestContent;
|
||||
import org.eclipse.jetty.client.util.FutureResponseListener;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpHeaderValue;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
|
@ -65,16 +60,16 @@ public class ConnectionPoolTest
|
|||
{
|
||||
private static final Logger LOG = LoggerFactory.getLogger(ConnectionPoolTest.class);
|
||||
|
||||
private static final ConnectionPoolFactory DUPLEX = new ConnectionPoolFactory("duplex", destination -> new DuplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), destination));
|
||||
private static final ConnectionPoolFactory MULTIPLEX = new ConnectionPoolFactory("multiplex", destination -> new MultiplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), destination, 1));
|
||||
private static final ConnectionPoolFactory RANDOM = new ConnectionPoolFactory("random", destination -> new RandomConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), destination, 1));
|
||||
private static final ConnectionPoolFactory DUPLEX = new ConnectionPoolFactory("duplex", destination -> new DuplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination()));
|
||||
private static final ConnectionPoolFactory MULTIPLEX = new ConnectionPoolFactory("multiplex", destination -> new MultiplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), 1));
|
||||
private static final ConnectionPoolFactory RANDOM = new ConnectionPoolFactory("random", destination -> new RandomConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), 1));
|
||||
private static final ConnectionPoolFactory DUPLEX_MAX_DURATION = new ConnectionPoolFactory("duplex-maxDuration", destination ->
|
||||
{
|
||||
DuplexConnectionPool pool = new DuplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), destination);
|
||||
DuplexConnectionPool pool = new DuplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination());
|
||||
pool.setMaxDuration(10);
|
||||
return pool;
|
||||
});
|
||||
private static final ConnectionPoolFactory ROUND_ROBIN = new ConnectionPoolFactory("round-robin", destination -> new RoundRobinConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), destination));
|
||||
private static final ConnectionPoolFactory ROUND_ROBIN = new ConnectionPoolFactory("round-robin", destination -> new RoundRobinConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination()));
|
||||
|
||||
public static Stream<ConnectionPoolFactory> pools()
|
||||
{
|
||||
|
@ -487,7 +482,7 @@ public class ConnectionPoolTest
|
|||
ConnectionPoolFactory factory = new ConnectionPoolFactory("duplex-maxDuration", destination ->
|
||||
{
|
||||
// Constrain the max pool size to 1.
|
||||
DuplexConnectionPool pool = new DuplexConnectionPool(destination, maxConnections, destination)
|
||||
DuplexConnectionPool pool = new DuplexConnectionPool(destination, maxConnections)
|
||||
{
|
||||
@Override
|
||||
protected void onCreated(Connection connection)
|
||||
|
@ -541,7 +536,7 @@ public class ConnectionPoolTest
|
|||
AtomicInteger poolRemoveCounter = new AtomicInteger();
|
||||
ConnectionPoolFactory factory = new ConnectionPoolFactory("duplex-maxDuration", destination ->
|
||||
{
|
||||
DuplexConnectionPool pool = new DuplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), destination)
|
||||
DuplexConnectionPool pool = new DuplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination())
|
||||
{
|
||||
@Override
|
||||
protected void onCreated(Connection connection)
|
||||
|
@ -652,7 +647,7 @@ public class ConnectionPoolTest
|
|||
client.setIdleTimeout(idleTimeout);
|
||||
|
||||
// Trigger the creation of a destination, that will create the connection pool.
|
||||
HttpDestination destination = client.resolveDestination(new Origin("http", "localhost", connector.getLocalPort()));
|
||||
Destination destination = client.resolveDestination(new Origin("http", "localhost", connector.getLocalPort()));
|
||||
AbstractConnectionPool connectionPool = (AbstractConnectionPool)destination.getConnectionPool();
|
||||
if (DUPLEX_MAX_DURATION == factory)
|
||||
assertThat(connectionPool.getConnectionCount(), lessThanOrEqualTo(1)); // The connections can expire upon release.
|
||||
|
|
|
@ -17,7 +17,6 @@ import java.nio.ByteBuffer;
|
|||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.io.Content;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
|
|
|
@ -20,10 +20,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import java.util.function.Supplier;
|
||||
|
||||
import org.awaitility.Awaitility;
|
||||
import org.eclipse.jetty.client.api.Connection;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Destination;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.internal.HttpDestination;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpHeaderValue;
|
||||
import org.eclipse.jetty.util.NanoTime;
|
||||
|
@ -48,7 +45,8 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
start(scenario, new EmptyServerHandler());
|
||||
|
||||
try (HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false))
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false);
|
||||
try
|
||||
{
|
||||
destination.start();
|
||||
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
|
||||
|
@ -60,6 +58,10 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
}
|
||||
assertNotNull(connection);
|
||||
}
|
||||
finally
|
||||
{
|
||||
destination.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
@ -68,7 +70,8 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
start(scenario, new EmptyServerHandler());
|
||||
|
||||
try (HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false))
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false);
|
||||
try
|
||||
{
|
||||
destination.start();
|
||||
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
|
||||
|
@ -84,6 +87,10 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
}
|
||||
assertNotNull(connection);
|
||||
}
|
||||
finally
|
||||
{
|
||||
destination.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
@ -92,7 +99,8 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
start(scenario, new EmptyServerHandler());
|
||||
|
||||
try (HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false))
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false);
|
||||
try
|
||||
{
|
||||
destination.start();
|
||||
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
|
||||
|
@ -111,6 +119,10 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
assertSame(connection1, connection2);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
destination.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
@ -121,12 +133,12 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
|
||||
CountDownLatch idleLatch = new CountDownLatch(1);
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
try (HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false)
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false)
|
||||
{
|
||||
@Override
|
||||
protected ConnectionPool newConnectionPool(HttpClient client)
|
||||
{
|
||||
return new DuplexConnectionPool(this, client.getMaxConnectionsPerDestination(), this)
|
||||
return new DuplexConnectionPool(this, client.getMaxConnectionsPerDestination())
|
||||
{
|
||||
@Override
|
||||
protected void onCreated(Connection connection)
|
||||
|
@ -144,7 +156,8 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
}
|
||||
};
|
||||
}
|
||||
})
|
||||
};
|
||||
try
|
||||
{
|
||||
destination.start();
|
||||
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
|
||||
|
@ -175,6 +188,10 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
connection = peekIdleConnection(connectionPool, 5, TimeUnit.SECONDS);
|
||||
assertNotNull(connection);
|
||||
}
|
||||
finally
|
||||
{
|
||||
destination.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
@ -183,7 +200,8 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
{
|
||||
start(scenario, new EmptyServerHandler());
|
||||
|
||||
try (HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false))
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false);
|
||||
try
|
||||
{
|
||||
destination.start();
|
||||
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
|
||||
|
@ -209,6 +227,10 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
Connection connection2 = connectionPool.acquire(true);
|
||||
assertSame(connection1, connection2, "After release");
|
||||
}
|
||||
finally
|
||||
{
|
||||
destination.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
@ -220,7 +242,8 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
long idleTimeout = 1000;
|
||||
startClient(scenario, httpClient -> httpClient.setIdleTimeout(idleTimeout));
|
||||
|
||||
try (HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false))
|
||||
HttpDestination destination = new HttpDestination(client, new Origin("http", "localhost", connector.getLocalPort()), false);
|
||||
try
|
||||
{
|
||||
destination.start();
|
||||
DuplexConnectionPool connectionPool = (DuplexConnectionPool)destination.getConnectionPool();
|
||||
|
@ -241,6 +264,10 @@ public class DuplexHttpDestinationTest extends AbstractHttpClientServerTest
|
|||
assertNull(connection1);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
destination.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
|
|
|
@ -17,9 +17,6 @@ import java.net.Socket;
|
|||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
|
|
@ -17,7 +17,7 @@ import java.security.cert.CertificateException;
|
|||
import java.util.concurrent.ExecutionException;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
|
||||
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.client.transport.HttpClientTransportOverHTTP;
|
||||
import org.eclipse.jetty.io.ClientConnector;
|
||||
import org.eclipse.jetty.io.Content;
|
||||
import org.eclipse.jetty.server.Handler;
|
||||
|
|
|
@ -15,11 +15,7 @@ package org.eclipse.jetty.client;
|
|||
|
||||
import java.net.URI;
|
||||
|
||||
import org.eclipse.jetty.client.api.Authentication;
|
||||
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.util.BasicAuthentication;
|
||||
import org.eclipse.jetty.client.util.DigestAuthentication;
|
||||
import org.eclipse.jetty.client.internal.HttpAuthenticationStore;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
|
|
@ -24,11 +24,6 @@ import java.util.concurrent.CountDownLatch;
|
|||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.api.Result;
|
||||
import org.eclipse.jetty.client.util.FutureResponseListener;
|
||||
import org.eclipse.jetty.util.Callback;
|
||||
import org.eclipse.jetty.util.thread.QueuedThreadPool;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
|
@ -15,8 +15,6 @@ package org.eclipse.jetty.client;
|
|||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.server.Response;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue