Merged branch 'cowwoc-jetty-12.0.x-8723-provide-a-thread-safe-way-to-modify-proxies-at-runtime' into 'jetty-12.0.x'.

Signed-off-by: Simone Bordet <simone.bordet@gmail.com>
This commit is contained in:
Simone Bordet 2022-10-25 10:32:07 +02:00
commit 67c36207c2
No known key found for this signature in database
GPG Key ID: 1677D141BCF3584D
22 changed files with 318 additions and 228 deletions

View File

@ -40,16 +40,6 @@ public class ProxyConfiguration
{
private final List<Proxy> proxies = new BlockingArrayQueue<>();
/**
* @deprecated use {@link #addProxy(Proxy)} and {@link #removeProxy(Proxy)} instead
* @return the forward proxies to use
*/
@Deprecated(forRemoval = true)
public List<Proxy> getProxies()
{
return proxies;
}
/**
* Adds a proxy.
*

View File

@ -480,7 +480,7 @@ public abstract class ProxyHandler extends Handler.Processor
* <p>Forward proxies are configured in client applications that use
* {@link HttpClient} in this way:</p>
* <pre>{@code
* httpClient.getProxyConfiguration().getProxies().add(new HttpProxy(proxyHost, proxyPort));
* httpClient.getProxyConfiguration().addProxy(new HttpProxy(proxyHost, proxyPort));
* }</pre>
*
* @see org.eclipse.jetty.client.ProxyConfiguration

View File

@ -78,83 +78,81 @@ public interface ConnectionMetaData extends Attributes
class Wrapper extends Attributes.Wrapper implements ConnectionMetaData
{
private final ConnectionMetaData _wrapped;
public Wrapper(ConnectionMetaData wrapped)
{
super(wrapped);
_wrapped = wrapped;
}
protected ConnectionMetaData getWrappedConnectionMetaData()
@Override
public ConnectionMetaData getWrapped()
{
return _wrapped;
return (ConnectionMetaData)super.getWrapped();
}
@Override
public String getId()
{
return _wrapped.getId();
return getWrapped().getId();
}
@Override
public HttpConfiguration getHttpConfiguration()
{
return _wrapped.getHttpConfiguration();
return getWrapped().getHttpConfiguration();
}
@Override
public HttpVersion getHttpVersion()
{
return _wrapped.getHttpVersion();
return getWrapped().getHttpVersion();
}
@Override
public String getProtocol()
{
return _wrapped.getProtocol();
return getWrapped().getProtocol();
}
@Override
public Connection getConnection()
{
return _wrapped.getConnection();
return getWrapped().getConnection();
}
@Override
public Connector getConnector()
{
return _wrapped.getConnector();
return getWrapped().getConnector();
}
@Override
public boolean isPersistent()
{
return _wrapped.isPersistent();
return getWrapped().isPersistent();
}
@Override
public boolean isSecure()
{
return _wrapped.isSecure();
return getWrapped().isSecure();
}
@Override
public SocketAddress getRemoteSocketAddress()
{
return _wrapped.getRemoteSocketAddress();
return getWrapped().getRemoteSocketAddress();
}
@Override
public SocketAddress getLocalSocketAddress()
{
return _wrapped.getLocalSocketAddress();
return getWrapped().getLocalSocketAddress();
}
@Override
public HostPort getServerAuthority()
{
return _wrapped.getServerAuthority();
return getWrapped().getServerAuthority();
}
}
}

View File

@ -597,7 +597,7 @@ public class ForwardedRequestCustomizer implements HttpConfiguration.Customizer
getId(),
remote,
authority,
getWrappedConnectionMetaData()
getWrapped()
);
}
};

View File

@ -1,71 +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.server;
import java.nio.ByteBuffer;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.util.Callback;
/**
* Abstraction of the outbound HTTP transport.
*/
public interface HttpTransport
{
String UPGRADE_CONNECTION_ATTRIBUTE = HttpTransport.class.getName() + ".UPGRADE";
/**
* Asynchronous call to send a response (or part) over the transport
*
* @param request True if the response if for a HEAD request (and the data should not be sent).
* @param response The header info to send, or null if just sending more data.
* The first call to send for a response must have a non null info.
* @param content A buffer of content to be sent.
* @param lastContent True if the content is the last content for the current response.
* @param callback The Callback instance that success or failure of the send is notified on
*/
void send(MetaData.Request request, MetaData.Response response, ByteBuffer content, boolean lastContent, Callback callback);
/**
* @return true if responses can be pushed over this transport
*/
boolean isPushSupported();
/**
* @param request A request to use as the basis for generating a pushed response.
*/
void push(MetaData.Request request);
/**
* Called to indicated the end of the current request/response cycle (which may be
* some time after the last content is sent).
*/
void onCompleted();
/**
* Aborts this transport.
* <p>
* This method should terminate the transport in a way that
* can indicate an abnormal response to the client, for example
* by abruptly close the connection.
* <p>
* This method is called when an error response needs to be sent,
* but the response is already committed, or when a write failure
* is detected. If abort is called, {@link #onCompleted()} is not
* called
*
* @param failure the failure that caused the abort.
*/
void abort(Throwable failure);
}

View File

@ -110,7 +110,7 @@ public class ErrorProcessor implements Request.Processor
try
{
generateAcceptableResponse(request, response, code, message, cause, callback);
generateResponse(request, response, code, message, cause, callback);
}
catch (Throwable x)
{
@ -120,7 +120,7 @@ public class ErrorProcessor implements Request.Processor
}
}
protected void generateAcceptableResponse(Request request, Response response, int code, String message, Throwable cause, Callback callback) throws IOException
protected void generateResponse(Request request, Response response, int code, String message, Throwable cause, Callback callback) throws IOException
{
List<String> acceptable = request.getHeaders().getQualityCSV(HttpHeader.ACCEPT, QuotedQualityCSV.MOST_SPECIFIC_MIME_ORDERING);
if (acceptable.isEmpty())

View File

@ -0,0 +1,146 @@
//
// ========================================================================
// 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.server.handler;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.ExceptionUtil;
import org.eclipse.jetty.util.URIUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* An ErrorProcessor that can re-handle a request at an error page location.
*/
public abstract class ReHandlingErrorProcessor extends ErrorProcessor
{
private static final Logger LOG = LoggerFactory.getLogger(ReHandlingErrorProcessor.class);
private final Handler _handler;
protected ReHandlingErrorProcessor(Handler handler)
{
_handler = handler;
}
@Override
public InvocationType getInvocationType()
{
return _handler.getInvocationType();
}
@Override
protected void generateResponse(Request request, Response response, int code, String message, Throwable cause, Callback callback) throws IOException
{
if (request.getAttribute(ReHandlingErrorProcessor.class.getName()) == null)
{
String pathInContext = getReHandlePathInContext(request, code, cause);
if (pathInContext != null)
{
request.setAttribute(ReHandlingErrorProcessor.class.getName(), pathInContext);
HttpURI uri = HttpURI.build(request.getHttpURI()).path(URIUtil.addPaths(request.getContext().getContextPath(), pathInContext)).asImmutable();
Request.Wrapper wrapper = new ReHandleRequestWrapper(request, uri, uri.getCanonicalPath());
try
{
Request.Processor processor = _handler.handle(wrapper);
if (processor != null)
{
response.setStatus(200);
processor.process(wrapper, response, callback);
return;
}
}
catch (Exception e)
{
if (LOG.isDebugEnabled())
LOG.debug("Unable to process error {}", wrapper, e);
if (cause != null && ExceptionUtil.areNotAssociated(cause, e))
cause.addSuppressed(e);
response.setStatus(code);
}
}
}
super.generateResponse(request, response, code, message, cause, callback);
}
protected abstract String getReHandlePathInContext(Request request, int code, Throwable cause);
/**
* An ErrorPageErrorProcessor that uses a map of error codes to select a page.
*/
public static class ByHttpStatus extends ReHandlingErrorProcessor
{
private final Map<Integer, String> _statusMap = new ConcurrentHashMap<>();
public ByHttpStatus(Handler handler)
{
super(handler);
}
@Override
protected String getReHandlePathInContext(Request request, int code, Throwable cause)
{
return get(code);
}
public String put(int code, String pathInContext)
{
return _statusMap.put(code, pathInContext);
}
public String get(int code)
{
return _statusMap.get(code);
}
public String remove(int code)
{
return _statusMap.remove(code);
}
}
private static class ReHandleRequestWrapper extends Request.Wrapper
{
private final HttpURI _uri;
private final String _pathInContext;
public ReHandleRequestWrapper(Request request, HttpURI uri, String pathInContext)
{
super(request);
_uri = uri;
_pathInContext = pathInContext;
}
@Override
public HttpURI getHttpURI()
{
return _uri;
}
@Override
public String getPathInContext()
{
return _pathInContext;
}
}
}

View File

@ -796,7 +796,7 @@ public class HttpChannelState implements HttpChannel, Components
return _loggedRequest == null ? this : _loggedRequest;
}
HttpStream getStream()
HttpStream getHttpStream()
{
return getHttpChannel()._stream;
}
@ -1013,7 +1013,7 @@ public class HttpChannelState implements HttpChannel, Components
@Override
public void push(MetaData.Request request)
{
getStream().push(request);
getHttpStream().push(request);
}
@Override
@ -1047,7 +1047,7 @@ public class HttpChannelState implements HttpChannel, Components
@Override
public TunnelSupport getTunnelSupport()
{
return getStream().getTunnelSupport();
return getHttpStream().getTunnelSupport();
}
@Override
@ -1468,7 +1468,7 @@ public class HttpChannelState implements HttpChannel, Components
public InvocationType getInvocationType()
{
// TODO review this as it is probably not correct
return _request.getStream().getInvocationType();
return _request.getHttpStream().getInvocationType();
}
}

View File

@ -25,11 +25,13 @@ import javax.xml.parsers.DocumentBuilderFactory;
import org.eclipse.jetty.http.BadMessageException;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpTester;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.io.QuietException;
import org.eclipse.jetty.logging.StacklessLogging;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.ErrorProcessor;
import org.eclipse.jetty.server.handler.ReHandlingErrorProcessor;
import org.eclipse.jetty.server.internal.HttpChannelState;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
@ -111,6 +113,17 @@ public class ErrorProcessorTest
throw new TestException(message);
}
// 200 response
if (request.getPathInContext().startsWith("/ok/"))
{
Content.Sink.write(
response,
true,
"%s Error %s : %s%n".formatted(request.getPathInContext(), request.getAttribute(ErrorProcessor.ERROR_STATUS), request.getAttribute(ErrorProcessor.ERROR_MESSAGE)),
callback);
return;
}
Response.writeError(request, response, callback, 404);
}
});
@ -689,6 +702,104 @@ public class ErrorProcessorTest
assertThat(response, containsString("Server Error"));
}
@Test
public void testRootReHandlingErrorProcessor() throws Exception
{
ReHandlingErrorProcessor.ByHttpStatus errorProcessor = new ReHandlingErrorProcessor.ByHttpStatus(server);
errorProcessor.put(400, "/ok/badMessage");
server.setErrorProcessor(errorProcessor);
String rawResponse = connector.getResponse("""
GET /no/host HTTP/1.1
""");
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertThat(response.getStatus(), is(200));
assertThat(response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0));
assertThat(response.getContent(), containsString("/ok/badMessage Error 400 : No Host"));
}
@Test
public void testRootReHandlingErrorProcessorLoop() throws Exception
{
ReHandlingErrorProcessor.ByHttpStatus errorProcessor = new ReHandlingErrorProcessor.ByHttpStatus(server);
errorProcessor.put(404, "/not/found");
server.setErrorProcessor(errorProcessor);
String rawResponse = connector.getResponse("""
GET /not/found HTTP/1.1
Host: localhost
""");
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertThat(response.getStatus(), is(404));
assertThat(response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0));
assertThat(response.getContent(), containsString("<title>Error 404 Not Found</title>"));
}
@Test
public void testRootReHandlingErrorProcessorExceptionLoop() throws Exception
{
ReHandlingErrorProcessor.ByHttpStatus errorProcessor = new ReHandlingErrorProcessor.ByHttpStatus(server);
errorProcessor.put(444, "/badmessage/444");
server.setErrorProcessor(errorProcessor);
String rawResponse = connector.getResponse("""
GET /badmessage/444 HTTP/1.1
Host: localhost
""");
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertThat(response.getStatus(), is(444));
assertThat(response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0));
assertThat(response.getContent(), containsString("<title>Error 444</title>"));
}
@Test
public void testContextReHandlingErrorProcessor() throws Exception
{
server.stop();
ContextHandler context = new ContextHandler("/ctx");
context.setHandler(server.getHandler());
ContextHandlerCollection contexts = new ContextHandlerCollection();
contexts.addHandler(context);
server.setHandler(contexts);
server.setErrorProcessor(new ErrorProcessor()
{
@Override
public void process(Request request, Response response, Callback callback)
{
throw new UnsupportedOperationException();
}
});
server.start();
ReHandlingErrorProcessor.ByHttpStatus errorProcessor = new ReHandlingErrorProcessor.ByHttpStatus(context);
errorProcessor.put(444, "/ok/badMessage");
context.setErrorProcessor(errorProcessor);
String rawResponse = connector.getResponse("""
GET /ctx/badmessage/444 HTTP/1.1
Host: localhost
""");
HttpTester.Response response = HttpTester.parseResponse(rawResponse);
assertThat(response.getStatus(), is(200));
assertThat(response.getField(HttpHeader.CONTENT_LENGTH).getIntValue(), greaterThan(0));
assertThat(response.getContent(), containsString("/ok/badMessage Error 444"));
}
static class TestException extends RuntimeException implements QuietException
{
public TestException(String message)

View File

@ -261,7 +261,7 @@ public class ForwardProxyWithDynamicTransportTest
int proxyPort = proxySecure ? proxyTLSConnector.getLocalPort() : proxyConnector.getLocalPort();
Origin.Address proxyAddress = new Origin.Address("localhost", proxyPort);
HttpProxy proxy = new HttpProxy(proxyAddress, proxySecure, proxyProtocol);
client.getProxyConfiguration().getProxies().add(proxy);
client.getProxyConfiguration().addProxy(proxy);
String scheme = serverSecure ? "https" : "http";
int serverPort = serverSecure ? serverTLSConnector.getLocalPort() : serverConnector.getLocalPort();
@ -298,7 +298,7 @@ public class ForwardProxyWithDynamicTransportTest
int proxyPort = proxyConnector.getLocalPort();
Origin.Address proxyAddress = new Origin.Address("localhost", proxyPort);
HttpProxy proxy = new HttpProxy(proxyAddress, false, new Origin.Protocol(List.of("h2c"), false));
client.getProxyConfiguration().getProxies().add(proxy);
client.getProxyConfiguration().addProxy(proxy);
long idleTimeout = 1000;
http2Client.setStreamIdleTimeout(idleTimeout);
@ -339,7 +339,7 @@ public class ForwardProxyWithDynamicTransportTest
int proxyPort = proxyConnector.getLocalPort();
Origin.Address proxyAddress = new Origin.Address("localhost", proxyPort);
HttpProxy httpProxy = new HttpProxy(proxyAddress, false, new Origin.Protocol(List.of("h2c"), false));
client.getProxyConfiguration().getProxies().add(httpProxy);
client.getProxyConfiguration().addProxy(httpProxy);
proxy.stop();
CountDownLatch latch = new CountDownLatch(1);
@ -376,7 +376,7 @@ public class ForwardProxyWithDynamicTransportTest
int proxyPort = proxyConnector.getLocalPort();
Origin.Address proxyAddress = new Origin.Address("localhost", proxyPort);
HttpProxy httpProxy = new HttpProxy(proxyAddress, false, new Origin.Protocol(List.of("h2c"), false));
client.getProxyConfiguration().getProxies().add(httpProxy);
client.getProxyConfiguration().addProxy(httpProxy);
CountDownLatch latch = new CountDownLatch(1);
client.newRequest("localhost", serverConnector.getLocalPort())

View File

@ -42,7 +42,7 @@ public class ProxyServerTest extends AbstractEmbeddedTest
server.start();
URI uri = server.getURI();
client.getProxyConfiguration().getProxies().add(new HttpProxy("localhost", uri.getPort()));
client.getProxyConfiguration().addProxy(new HttpProxy("localhost", uri.getPort()));
}
@AfterEach

View File

@ -153,7 +153,7 @@ public class AsyncMiddleManServletTest
clientPool.setName("client");
client = new HttpClient();
client.setExecutor(clientPool);
client.getProxyConfiguration().getProxies().add(new HttpProxy("localhost", proxyConnector.getLocalPort()));
client.getProxyConfiguration().addProxy(new HttpProxy("localhost", proxyConnector.getLocalPort()));
client.start();
}

View File

@ -116,7 +116,7 @@ public class ProxyServletFailureTest
QueuedThreadPool executor = new QueuedThreadPool();
executor.setName("client");
result.setExecutor(executor);
result.getProxyConfiguration().getProxies().add(new HttpProxy("localhost", proxyConnector.getLocalPort()));
result.getProxyConfiguration().addProxy(new HttpProxy("localhost", proxyConnector.getLocalPort()));
result.start();
return result;
}

View File

@ -109,7 +109,7 @@ public class ProxyServletLoadTest
clientPool.setName("client");
HttpClient result = new HttpClient();
result.setExecutor(clientPool);
result.getProxyConfiguration().getProxies().add(new HttpProxy("localhost", proxyConnector.getLocalPort()));
result.getProxyConfiguration().addProxy(new HttpProxy("localhost", proxyConnector.getLocalPort()));
result.start();
client = result;
}

View File

@ -62,6 +62,7 @@ import org.eclipse.jetty.client.ConnectionPool;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpDestination;
import org.eclipse.jetty.client.HttpProxy;
import org.eclipse.jetty.client.ProxyConfiguration.Proxy;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
@ -124,6 +125,7 @@ public class ProxyServletTest
}
private HttpClient client;
private Proxy clientProxy;
private Server proxy;
private ServerConnector proxyConnector;
private ServletContextHandler proxyContext;
@ -198,6 +200,7 @@ public class ProxyServletTest
private void startClient(Consumer<HttpClient> consumer) throws Exception
{
clientProxy = new HttpProxy("localhost", proxyConnector.getLocalPort());
client = prepareClient(consumer);
}
@ -207,7 +210,7 @@ public class ProxyServletTest
clientPool.setName("client");
HttpClient result = new HttpClient();
result.setExecutor(clientPool);
result.getProxyConfiguration().getProxies().add(new HttpProxy("localhost", proxyConnector.getLocalPort()));
result.getProxyConfiguration().addProxy(clientProxy);
if (consumer != null)
consumer.accept(result);
result.start();
@ -730,7 +733,7 @@ public class ProxyServletTest
startProxy(proxyServletClass);
startClient();
int port = serverConnector.getLocalPort();
client.getProxyConfiguration().getProxies().get(0).getExcludedAddresses().add("127.0.0.1:" + port);
clientProxy.getExcludedAddresses().add("127.0.0.1:" + port);
// Try with a proxied host
ContentResponse response = client.newRequest("localhost", port)

View File

@ -52,20 +52,13 @@ import org.eclipse.jetty.http.HttpFields;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpHeaderValue;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.http.MetaData;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.io.ByteBufferInputStream;
import org.eclipse.jetty.io.Content;
import org.eclipse.jetty.server.Components;
import org.eclipse.jetty.server.ConnectionMetaData;
import org.eclipse.jetty.server.Context;
import org.eclipse.jetty.server.HttpStream;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.ResourceContentFactory;
import org.eclipse.jetty.server.ResourceService;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.TunnelSupport;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Blocker;
import org.eclipse.jetty.util.BufferUtil;
@ -372,7 +365,7 @@ public class DefaultServlet extends HttpServlet
if (coreResponse.isCommitted())
{
if (LOG.isDebugEnabled())
LOG.debug("Response already committed for {}", coreRequest._request.getHttpURI());
LOG.debug("Response already committed for {}", coreRequest.getHttpURI());
return;
}
@ -419,19 +412,18 @@ public class DefaultServlet extends HttpServlet
doGet(req, resp);
}
private static class ServletCoreRequest implements Request
private static class ServletCoreRequest extends Request.Wrapper
{
// TODO fully implement this class and move it to the top level
// TODO Some methods are directed to core that probably should be intercepted
private final HttpServletRequest _servletRequest;
private final Request _request;
private final HttpFields _httpFields;
ServletCoreRequest(HttpServletRequest request)
{
super(ServletContextRequest.getServletContextRequest(request));
_servletRequest = request;
_request = ServletContextRequest.getServletContextRequest(request);
HttpFields.Mutable fields = HttpFields.build();
@ -455,108 +447,36 @@ public class DefaultServlet extends HttpServlet
return _httpFields;
}
@Override
public HttpFields getTrailers()
{
return _request.getTrailers();
}
@Override
public HttpURI getHttpURI()
{
return _request.getHttpURI();
}
@Override
public String getPathInContext()
{
return URIUtil.addPaths(_servletRequest.getServletPath(), _servletRequest.getPathInfo());
}
@Override
public void demand(Runnable demandCallback)
{
_request.demand(demandCallback);
}
@Override
public void fail(Throwable failure)
{
_request.fail(failure);
}
@Override
public String getId()
{
return _servletRequest.getRequestId();
}
@Override
public Components getComponents()
{
return _request.getComponents();
}
@Override
public ConnectionMetaData getConnectionMetaData()
{
return _request.getConnectionMetaData();
}
@Override
public String getMethod()
{
return _servletRequest.getMethod();
}
@Override
public Context getContext()
{
return _request.getContext();
}
@Override
public long getTimeStamp()
{
return _request.getTimeStamp();
}
@Override
public boolean isSecure()
{
return _servletRequest.isSecure();
}
@Override
public Content.Chunk read()
{
return _request.read();
}
@Override
public boolean isPushSupported()
{
return _request.isPushSupported();
}
@Override
public void push(MetaData.Request request)
{
this._request.push(request);
}
@Override
public boolean addErrorListener(Predicate<Throwable> onError)
{
return false;
}
@Override
public TunnelSupport getTunnelSupport()
{
return _request.getTunnelSupport();
}
@Override
public void addHttpStreamWrapper(Function<HttpStream, HttpStream.Wrapper> wrapper)
{

View File

@ -838,8 +838,6 @@ public class ServletChannel implements Runnable
/**
* If a write or similar operation to this channel fails,
* then this method should be called.
* <p>
* The standard implementation calls {@code HttpTransport#abort(Throwable)}.
*
* @param failure the failure that caused the abort.
*/

View File

@ -65,13 +65,8 @@ import org.slf4j.LoggerFactory;
import static org.eclipse.jetty.util.thread.Invocable.InvocationType.NON_BLOCKING;
/**
* HttpChannel represents a single endpoint for HTTP semantic processing.
* The HttpChannel is both an HttpParser.RequestHandler, where it passively receives events from
* an incoming HTTP request, and a Runnable, where it actively takes control of the request/response
* life cycle and calls the application (perhaps suspending and resuming with multiple calls to run).
* The HttpChannel signals the switch from passive mode to active mode by returning true to one of the
* HttpParser.RequestHandler callbacks. The completion of the active phase is signalled by a call to
* HttpTransport.completed().
* <p>The state machine that processes a request/response
* cycle interpreting the HTTP and Servlet semantic.</p>
*/
public class HttpChannel implements Runnable, HttpOutput.Interceptor
{

View File

@ -35,15 +35,15 @@ import org.slf4j.LoggerFactory;
public class PushBuilderImpl implements PushBuilder
{
private static final Logger LOG = LoggerFactory.getLogger(PushBuilderImpl.class);
private static final HttpField JETTY_PUSH = new HttpField("x-http2-push", "PushBuilder");
private static EnumSet<HttpMethod> UNSAFE_METHODS = EnumSet.of(
private static final EnumSet<HttpMethod> UNSAFE_METHODS = EnumSet.of(
HttpMethod.POST,
HttpMethod.PUT,
HttpMethod.DELETE,
HttpMethod.CONNECT,
HttpMethod.OPTIONS,
HttpMethod.TRACE);
HttpMethod.TRACE
);
private final Request _request;
private final HttpFields.Mutable _fields;
@ -51,7 +51,6 @@ public class PushBuilderImpl implements PushBuilder
private String _queryString;
private String _sessionId;
private String _path;
private String _lastModified;
public PushBuilderImpl(Request request, HttpFields fields, String method, String queryString, String sessionId)
{
@ -190,6 +189,5 @@ public class PushBuilderImpl implements PushBuilder
_request.getHttpChannel().getCoreRequest().push(push);
_path = null;
_lastModified = null;
}
}

View File

@ -205,7 +205,7 @@ public class ForwardProxyServerTest
ClientConnector clientConnector = new ClientConnector();
clientConnector.setSslContextFactory(clientTLS);
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
httpClient.getProxyConfiguration().addProxy(newHttpProxy());
httpClient.start();
try
@ -253,7 +253,7 @@ public class ForwardProxyServerTest
});
HttpClient httpClient = new HttpClient();
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
httpClient.getProxyConfiguration().addProxy(newHttpProxy());
httpClient.start();
ContentResponse response = httpClient.newRequest("[::1]", serverConnector.getLocalPort())
@ -291,7 +291,7 @@ public class ForwardProxyServerTest
});
HttpClient httpClient = new HttpClient();
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
httpClient.getProxyConfiguration().addProxy(newHttpProxy());
httpClient.start();
ContentResponse response = httpClient.newRequest("[::1]", serverConnector.getLocalPort())

View File

@ -196,7 +196,7 @@ public class ForwardProxyTLSServerTest
startProxy(proxyTLS);
HttpClient httpClient = newHttpClient();
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
httpClient.getProxyConfiguration().addProxy(newHttpProxy());
httpClient.start();
try
@ -231,7 +231,7 @@ public class ForwardProxyTLSServerTest
startProxy(proxyTLS);
HttpClient httpClient = newHttpClient();
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
httpClient.getProxyConfiguration().addProxy(newHttpProxy());
httpClient.start();
try
@ -278,7 +278,7 @@ public class ForwardProxyTLSServerTest
startProxy(proxyTLS);
HttpClient httpClient = newHttpClient();
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
httpClient.getProxyConfiguration().addProxy(newHttpProxy());
httpClient.start();
try
@ -363,7 +363,7 @@ public class ForwardProxyTLSServerTest
});
HttpClient httpClient = newHttpClient();
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
httpClient.getProxyConfiguration().addProxy(newHttpProxy());
// Short idle timeout for HttpClient.
httpClient.setIdleTimeout(idleTimeout);
httpClient.start();
@ -401,7 +401,7 @@ public class ForwardProxyTLSServerTest
stopProxy();
HttpClient httpClient = newHttpClient();
httpClient.getProxyConfiguration().getProxies().add(new HttpProxy(new Origin.Address("localhost", proxyPort), proxySslContextFactory != null));
httpClient.getProxyConfiguration().addProxy(new HttpProxy(new Origin.Address("localhost", proxyPort), proxySslContextFactory != null));
httpClient.start();
ExecutionException x = assertThrows(ExecutionException.class, () ->
@ -429,7 +429,7 @@ public class ForwardProxyTLSServerTest
startProxy(proxyTLS);
HttpClient httpClient = newHttpClient();
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
httpClient.getProxyConfiguration().addProxy(newHttpProxy());
httpClient.start();
assertThrows(ExecutionException.class, () ->
@ -461,7 +461,7 @@ public class ForwardProxyTLSServerTest
});
HttpClient httpClient = newHttpClient();
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
httpClient.getProxyConfiguration().addProxy(newHttpProxy());
httpClient.start();
assertThrows(ExecutionException.class, () ->
@ -484,7 +484,7 @@ public class ForwardProxyTLSServerTest
HttpClient httpClient = newHttpClient();
HttpProxy httpProxy = new HttpProxy(new Origin.Address("[::1]", proxyConnector.getLocalPort()), proxyTLS != null);
httpClient.getProxyConfiguration().getProxies().add(httpProxy);
httpClient.getProxyConfiguration().addProxy(httpProxy);
httpClient.start();
try
@ -617,7 +617,7 @@ public class ForwardProxyTLSServerTest
HttpProxy httpProxy = newHttpProxy();
if (includeAddress)
httpProxy.getIncludedAddresses().add("localhost:" + serverConnector.getLocalPort());
httpClient.getProxyConfiguration().getProxies().add(httpProxy);
httpClient.getProxyConfiguration().addProxy(httpProxy);
URI uri = URI.create((proxySslContextFactory == null ? "http" : "https") + "://localhost:" + proxyConnector.getLocalPort());
httpClient.getAuthenticationStore().addAuthentication(new BasicAuthentication(uri, realm, "proxyUser", "proxyPassword"));
httpClient.start();
@ -698,7 +698,7 @@ public class ForwardProxyTLSServerTest
clientConnector.setSelectors(1);
clientConnector.setSslContextFactory(clientSslContextFactory);
HttpClient httpClient = new HttpClient(new HttpClientTransportOverHTTP(clientConnector));
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
httpClient.getProxyConfiguration().addProxy(newHttpProxy());
httpClient.start();
try
@ -769,7 +769,7 @@ public class ForwardProxyTLSServerTest
proxyClientTLS.setEndpointIdentificationAlgorithm(null);
proxyClientTLS.start();
HttpProxy httpProxy = new HttpProxy(new Origin.Address("localhost", proxyConnector.getLocalPort()), proxyClientTLS);
httpClient.getProxyConfiguration().getProxies().add(httpProxy);
httpClient.getProxyConfiguration().addProxy(httpProxy);
httpClient.start();
try
@ -800,7 +800,7 @@ public class ForwardProxyTLSServerTest
startProxy(proxyTLS);
HttpClient httpClient = newHttpClient();
httpClient.getProxyConfiguration().getProxies().add(newHttpProxy());
httpClient.getProxyConfiguration().addProxy(newHttpProxy());
httpClient.start();
try
@ -851,7 +851,7 @@ public class ForwardProxyTLSServerTest
}
HttpClient httpClient = newHttpClient();
httpClient.getProxyConfiguration().getProxies().add(new HttpProxy(proxyHost, proxyPort));
httpClient.getProxyConfiguration().addProxy(new HttpProxy(proxyHost, proxyPort));
httpClient.start();
try

View File

@ -26,7 +26,9 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;