Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/jetty-12.0.x' into fix/12.0.x/ur…
Browse files Browse the repository at this point in the history
…icompliance-reject-backslash
  • Loading branch information
joakime committed Mar 22, 2024
2 parents c6c2fb9 + ae6f98e commit 50d8c94
Show file tree
Hide file tree
Showing 135 changed files with 2,569 additions and 636 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ Configured in this way, `HttpClient` makes requests to the HTTP proxy (for plain

Proxying is supported for any version of the HTTP protocol.

The communication between the client and the proxy may be encrypted, so that it would not be possible for another party on the same network as the client to know what servers the client connects to.

[[pg-client-http-proxy-socks5]]
===== SOCKS5 Proxy Support

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1386,14 +1386,14 @@ protected void onBeforeHandling(Request request)
}

@Override
protected void onComplete(Request request, Throwable failure)
protected void onComplete(Request request, int status, HttpFields headers, Throwable failure)
{
// Retrieve the before handling nanoTime.
long beforeHandlingNanoTime = (long)request.getAttribute("beforeHandlingNanoTime");

// Record the request processing time.
// Record the request processing time and the status that was sent back to the client.
long processingTime = NanoTime.millisSince(beforeHandlingNanoTime);
System.getLogger("trackTime").log(INFO, "processing request %s took %d ms", request, processingTime);
System.getLogger("trackTime").log(INFO, "processing request %s took %d ms and ended with status code %d", request, processingTime, status);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -434,32 +434,71 @@ public boolean remove(Connection connection)
if (removed)
{
released(connection);
removed(connection);
onRemoved(connection);
}
return removed;
}

/**
* <p>Callback method invoked when a new {@link Connection} has been created.</p>
*
* @param connection the {@link Connection} that has been created
* @see #onRemoved(Connection)
*/
protected void onCreated(Connection connection)
{
}

/**
* @param connection the {@link Connection} that become idle
* @param close whether this pool is closing
* @return {@code true} to indicate that the connection is idle, {@code false} otherwise
* @deprecated Racy API. Do not use. There is no replacement.
*/
@Deprecated(since = "12.0.8", forRemoval = true)
protected boolean idle(Connection connection, boolean close)
{
return !close;
}

/**
* @param connection the {@link Connection} that was acquired
* @deprecated Racy API. Do not use. There is no replacement.
*/
@Deprecated(since = "12.0.8", forRemoval = true)
protected void acquired(Connection connection)
{
}

/**
* @param connection the {@link Connection} that was released
* @deprecated Racy API. Do not use. There is no replacement.
*/
@Deprecated(since = "12.0.8", forRemoval = true)
protected void released(Connection connection)
{
}

/**
* @param connection the {@link Connection} that was removed
* @deprecated replaced by {@link #onRemoved(Connection)}
*/
@Deprecated(since = "12.0.8", forRemoval = true)
protected void removed(Connection connection)
{
}

/**
* <p>Callback method invoked when a {@link Connection} has been removed from this pool.</p>
*
* @param connection the {@link Connection} that was removed
* @see #onCreated(Connection)
*/
protected void onRemoved(Connection connection)
{
removed(connection);
}

Collection<Connection> getIdleConnections()
{
return pool.stream()
Expand Down Expand Up @@ -493,7 +532,7 @@ private void close(Pool.Entry<Connection> entry)
{
if (LOG.isDebugEnabled())
LOG.debug("Removed terminated entry {}", entry);
removed(connection);
onRemoved(connection);
IO.close(connection);
}
if (!entry.isInUse())
Expand Down Expand Up @@ -572,12 +611,11 @@ public void succeeded(Connection connection)
pending.decrementAndGet();
reserved.enable(connection, false);
idle(connection, false);
complete(null);
super.succeeded(connection);
proceed();
}
else
{
// reduce pending on failure and if not multiplexing also reduce demand
failed(new IllegalArgumentException("Invalid connection object: " + connection));
}
}
Expand All @@ -587,10 +625,9 @@ public void failed(Throwable x)
{
if (LOG.isDebugEnabled())
LOG.debug("Connection creation failed {}", reserved, x);
// reduce pending on failure and if not multiplexing also reduce demand
pending.decrementAndGet();
reserved.remove();
completeExceptionally(x);
super.failed(x);
destination.failed(x);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public abstract class AbstractConnectorHttpClientTransport extends AbstractHttpC
protected AbstractConnectorHttpClientTransport(ClientConnector connector)
{
this.connector = Objects.requireNonNull(connector);
addBean(connector);
installBean(connector);
}

public ClientConnector getClientConnector()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,11 @@ public HttpClient()
public HttpClient(HttpClientTransport transport)
{
this.transport = Objects.requireNonNull(transport);
addBean(transport);
installBean(transport);
this.connector = ((AbstractHttpClientTransport)transport).getContainedBeans(ClientConnector.class).stream().findFirst().orElseThrow();
addBean(requestListeners);
addBean(handlers);
addBean(decoderFactories);
installBean(requestListeners);
installBean(handlers);
installBean(decoderFactories);
}

public HttpClientTransport getTransport()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,35 +38,92 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* <p>Client-side proxy configuration for HTTP proxying, as specified by
* <a href="https://www.rfc-editor.org/rfc/rfc9110.html">RFC 9110</a>.</p>
* <p>By default the communication between client and proxy happens using
* the HTTP/1.1 protocol, but it may be configured to use
* also other HTTP protocol versions, such as HTTP/2.</p>
*/
public class HttpProxy extends ProxyConfiguration.Proxy
{
private static final Logger LOG = LoggerFactory.getLogger(HttpProxy.class);

/**
* <p>Creates a new instance with the given HTTP proxy host and port.</p>
*
* @param host the HTTP proxy host name
* @param port the HTTP proxy port
*/
public HttpProxy(String host, int port)
{
this(new Origin.Address(host, port), false);
}

/**
* <p>Creates a new instance with the given HTTP proxy address.</p>
* <p>When {@code secure=true} the communication between the client and the
* proxy will be encrypted (using this proxy {@link #getSslContextFactory()}
* which typically defaults to that of {@link HttpClient}.</p>
*
* @param address the HTTP proxy address (host and port)
* @param secure whether the communication between the client and the HTTP proxy should be secure
*/
public HttpProxy(Origin.Address address, boolean secure)
{
this(address, secure, new Origin.Protocol(List.of("http/1.1"), false));
}

/**
* <p>Creates a new instance with the given HTTP proxy address and protocol.</p>
*
* @param address the HTTP proxy address (host and port)
* @param secure whether the communication between the client and the HTTP proxy should be secure
* @param protocol the protocol to use to communicate with the HTTP proxy
*/
public HttpProxy(Origin.Address address, boolean secure, Origin.Protocol protocol)
{
this(new Origin(secure ? "https" : "http", address, null, protocol, Transport.TCP_IP), null);
}

/**
* <p>Creates a new instance with the given HTTP proxy address and TLS configuration.</p>
* <p>The {@link SslContextFactory} could have a different configuration from the
* one configured in {@link HttpClient}, and it is used to communicate with the HTTP
* proxy only (not to communicate with the servers).</p>
*
* @param address the HTTP proxy address (host and port)
* @param sslContextFactory the {@link SslContextFactory.Client} to use to communicate with the HTTP proxy
*/
public HttpProxy(Origin.Address address, SslContextFactory.Client sslContextFactory)
{
this(address, sslContextFactory, new Origin.Protocol(List.of("http/1.1"), false));
}

/**
* <p>Creates a new instance with the given HTTP proxy address, TLS configuration and protocol.</p>
* <p>The {@link SslContextFactory} could have a different configuration from the
* one configured in {@link HttpClient} and it is used to communicate with the HTTP
* proxy only (not to communicate with the servers).</p>
*
* @param address the HTTP proxy address (host and port)
* @param sslContextFactory the {@link SslContextFactory.Client} to use to communicate with the HTTP proxy
* @param protocol the protocol to use to communicate with the HTTP proxy
*/
public HttpProxy(Origin.Address address, SslContextFactory.Client sslContextFactory, Origin.Protocol protocol)
{
this(new Origin(sslContextFactory == null ? "http" : "https", address, null, protocol, Transport.TCP_IP), sslContextFactory);
}

/**
* <p>Creates a new instance with the given HTTP proxy {@link Origin} and TLS configuration.</p>
* <p>The {@link SslContextFactory} could have a different configuration from the
* one configured in {@link HttpClient} and it is used to communicate with the HTTP
* proxy only (not to communicate with the servers).</p>
*
* @param origin the HTTP proxy {@link Origin} information
* @param sslContextFactory the {@link SslContextFactory.Client} to use to communicate with the HTTP proxy
*/
public HttpProxy(Origin origin, SslContextFactory.Client sslContextFactory)
{
super(origin, sslContextFactory);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,35 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* <p>Client-side proxy configuration for SOCKS4, a de-facto standard.</p>
* <p>Consider using SOCK5 instead, a protocol that has been standardized
* by IETF.</p>
*
* @see Socks5Proxy
*/
public class Socks4Proxy extends ProxyConfiguration.Proxy
{
/**
* <p>Creates a new instance with the given SOCKS4 proxy host and port.</p>
*
* @param host the SOCKS4 proxy host name
* @param port the SOCKS4 proxy port
*/
public Socks4Proxy(String host, int port)
{
this(new Origin.Address(host, port), false);
}

/**
* <p>Creates a new instance with the given SOCKS4 proxy address.</p>
* <p>When {@code secure=true} the communication between the client and the
* proxy will be encrypted (using this proxy {@link #getSslContextFactory()}
* which typically defaults to that of {@link HttpClient}.</p>
*
* @param address the SOCKS4 proxy address (host and port)
* @param secure whether the communication between the client and the SOCKS4 proxy should be secure
*/
public Socks4Proxy(Origin.Address address, boolean secure)
{
super(address, secure, null, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,26 @@ public class Socks5Proxy extends Proxy

private final Map<Byte, Socks5.Authentication.Factory> authentications = new LinkedHashMap<>();

/**
* <p>Creates a new instance with the given SOCKS5 proxy host and port.</p>
*
* @param host the SOCKS5 proxy host name
* @param port the SOCKS5 proxy port
*/
public Socks5Proxy(String host, int port)
{
this(new Origin.Address(host, port), false);
}

/**
* <p>Creates a new instance with the given SOCKS5 proxy address.</p>
* <p>When {@code secure=true} the communication between the client and the
* proxy will be encrypted (using this proxy {@link #getSslContextFactory()}
* which typically defaults to that of {@link HttpClient}.</p>
*
* @param address the SOCKS5 proxy address (host and port)
* @param secure whether the communication between the client and the SOCKS5 proxy should be secure
*/
public Socks5Proxy(Origin.Address address, boolean secure)
{
super(address, secure, null, null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public HttpClientTransportDynamic(ClientConnector connector, ClientConnectionFac
{
super(connector);
this.infos = infos.length == 0 ? List.of(HttpClientConnectionFactory.HTTP11) : List.of(infos);
this.infos.forEach(this::addBean);
this.infos.forEach(this::installBean);
setConnectionPoolFactory(destination ->
new MultiplexConnectionPool(destination, destination.getHttpClient().getMaxConnectionsPerDestination(), 1)
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ protected void onCreated(Connection connection)
}

@Override
protected void removed(Connection connection)
protected void onRemoved(Connection connection)
{
poolRemoveCounter.incrementAndGet();
}
Expand Down Expand Up @@ -548,7 +548,7 @@ protected void onCreated(Connection connection)
}

@Override
protected void removed(Connection connection)
protected void onRemoved(Connection connection)
{
poolRemoveCounter.incrementAndGet();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ protected ScanningAppProvider()
protected ScanningAppProvider(FilenameFilter filter)
{
_filenameFilter = filter;
addBean(_appMap);
installBean(_appMap);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public DelegatingThreadPool(Executor executor)
{
_executor = executor;
_tryExecutor = TryExecutor.asTryExecutor(executor);
addBean(_executor);
installBean(_executor);
}

public Executor getExecutor()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ public CookieCache(CookieCompliance compliance)
_parser = CookieParser.newParser(this, compliance, this);
}

@Deprecated(forRemoval = true)
public CookieCache(CookieCompliance compliance, ComplianceViolation.Listener complianceListener)
{
this(compliance);
}

@Override
public void onComplianceViolation(ComplianceViolation.Event event)
{
Expand Down
Loading

0 comments on commit 50d8c94

Please sign in to comment.