Performance improvements to HTTP client after profiling session.
The profiling suggested to reduce the number of unneeded allocations and this required a couple of API changes.
This commit is contained in:
parent
c9f4513a89
commit
b6e4f98cf7
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -98,7 +99,7 @@ public class AuthenticationProtocolHandler implements ProtocolHandler
|
|||
return;
|
||||
}
|
||||
|
||||
final String uri = request.getURI();
|
||||
final URI uri = request.getURI();
|
||||
Authentication authentication = null;
|
||||
WWWAuthenticate wwwAuthenticate = null;
|
||||
for (WWWAuthenticate wwwAuthn : wwwAuthenticates)
|
||||
|
@ -125,7 +126,7 @@ public class AuthenticationProtocolHandler implements ProtocolHandler
|
|||
return;
|
||||
}
|
||||
|
||||
Request newRequest = client.copyRequest(request, request.getURI());
|
||||
Request newRequest = client.copyRequest(request, uri);
|
||||
authnResult.apply(newRequest);
|
||||
newRequest.onResponseSuccess(new Response.SuccessListener()
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -29,7 +30,7 @@ import org.eclipse.jetty.client.api.AuthenticationStore;
|
|||
public class HttpAuthenticationStore implements AuthenticationStore
|
||||
{
|
||||
private final List<Authentication> authentications = new CopyOnWriteArrayList<>();
|
||||
private final Map<String, Authentication.Result> results = new ConcurrentHashMap<>();
|
||||
private final Map<URI, Authentication.Result> results = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public void addAuthentication(Authentication authentication)
|
||||
|
@ -50,7 +51,7 @@ public class HttpAuthenticationStore implements AuthenticationStore
|
|||
}
|
||||
|
||||
@Override
|
||||
public Authentication findAuthentication(String type, String uri, String realm)
|
||||
public Authentication findAuthentication(String type, URI uri, String realm)
|
||||
{
|
||||
for (Authentication authentication : authentications)
|
||||
{
|
||||
|
@ -79,12 +80,12 @@ public class HttpAuthenticationStore implements AuthenticationStore
|
|||
}
|
||||
|
||||
@Override
|
||||
public Authentication.Result findAuthenticationResult(String uri)
|
||||
public Authentication.Result findAuthenticationResult(URI uri)
|
||||
{
|
||||
// TODO: I should match the longest URI
|
||||
for (Map.Entry<String, Authentication.Result> entry : results.entrySet())
|
||||
for (Map.Entry<URI, Authentication.Result> entry : results.entrySet())
|
||||
{
|
||||
if (uri.startsWith(entry.getKey()))
|
||||
if (uri.toString().startsWith(entry.getKey().toString()))
|
||||
return entry.getValue();
|
||||
}
|
||||
return null;
|
||||
|
|
|
@ -30,14 +30,15 @@ import java.nio.channels.SelectionKey;
|
|||
import java.nio.channels.SocketChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Future;
|
||||
|
@ -111,10 +112,10 @@ public class HttpClient extends ContainerLifeCycle
|
|||
|
||||
private final ConcurrentMap<String, HttpDestination> destinations = new ConcurrentHashMap<>();
|
||||
private final ConcurrentMap<Long, HttpConversation> conversations = new ConcurrentHashMap<>();
|
||||
private final List<ProtocolHandler> handlers = new CopyOnWriteArrayList<>();
|
||||
private final List<Request.Listener> requestListeners = new CopyOnWriteArrayList<>();
|
||||
private final List<ProtocolHandler> handlers = new ArrayList<>();
|
||||
private final List<Request.Listener> requestListeners = new ArrayList<>();
|
||||
private final AuthenticationStore authenticationStore = new HttpAuthenticationStore();
|
||||
private final Set<ContentDecoder.Factory> decoderFactories = Collections.newSetFromMap(new ConcurrentHashMap<ContentDecoder.Factory, Boolean>());
|
||||
private final Set<ContentDecoder.Factory> decoderFactories = new ContentDecoderFactorySet();
|
||||
private final SslContextFactory sslContextFactory;
|
||||
private volatile CookieManager cookieManager;
|
||||
private volatile CookieStore cookieStore;
|
||||
|
@ -122,7 +123,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
private volatile ByteBufferPool byteBufferPool;
|
||||
private volatile Scheduler scheduler;
|
||||
private volatile SelectorManager selectorManager;
|
||||
private volatile String agent = "Jetty/" + Jetty.VERSION;
|
||||
private volatile HttpField agentField = new HttpField(HttpHeader.USER_AGENT, "Jetty/" + Jetty.VERSION);
|
||||
private volatile boolean followRedirects = true;
|
||||
private volatile int maxConnectionsPerDestination = 64;
|
||||
private volatile int maxRequestsQueuedPerDestination = 1024;
|
||||
|
@ -135,6 +136,7 @@ public class HttpClient extends ContainerLifeCycle
|
|||
private volatile boolean tcpNoDelay = true;
|
||||
private volatile boolean dispatchIO = true;
|
||||
private volatile ProxyConfiguration proxyConfig;
|
||||
private volatile HttpField encodingField;
|
||||
|
||||
/**
|
||||
* Creates a {@link HttpClient} instance that can perform requests to non-TLS destinations only
|
||||
|
@ -249,6 +251,9 @@ public class HttpClient extends ContainerLifeCycle
|
|||
}
|
||||
|
||||
/**
|
||||
* 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 Request.Listener} that can be used to add and remove listeners
|
||||
*/
|
||||
public List<Request.Listener> getRequestListeners()
|
||||
|
@ -293,6 +298,9 @@ public class HttpClient extends ContainerLifeCycle
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a <em>non</em> thread-safe set of {@link ContentDecoder.Factory}s that can be modified before
|
||||
* performing requests.
|
||||
*
|
||||
* @return a set of {@link ContentDecoder.Factory} that can be used to add and remove content decoder factories
|
||||
*/
|
||||
public Set<ContentDecoder.Factory> getContentDecoderFactories()
|
||||
|
@ -381,9 +389,9 @@ public class HttpClient extends ContainerLifeCycle
|
|||
return new HttpRequest(this, uri);
|
||||
}
|
||||
|
||||
protected Request copyRequest(Request oldRequest, String newURI)
|
||||
protected Request copyRequest(Request oldRequest, URI newURI)
|
||||
{
|
||||
Request newRequest = new HttpRequest(this, oldRequest.getConversationID(), URI.create(newURI));
|
||||
Request newRequest = new HttpRequest(this, oldRequest.getConversationID(), newURI);
|
||||
newRequest.method(oldRequest.getMethod())
|
||||
.version(oldRequest.getVersion())
|
||||
.content(oldRequest.getContent());
|
||||
|
@ -537,8 +545,11 @@ public class HttpClient extends ContainerLifeCycle
|
|||
|
||||
protected ProtocolHandler findProtocolHandler(Request request, Response response)
|
||||
{
|
||||
for (ProtocolHandler handler : getProtocolHandlers())
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
List<ProtocolHandler> protocolHandlers = getProtocolHandlers();
|
||||
for (int i = 0; i < protocolHandlers.size(); ++i)
|
||||
{
|
||||
ProtocolHandler handler = protocolHandlers.get(i);
|
||||
if (handler.accept(request, response))
|
||||
return handler;
|
||||
}
|
||||
|
@ -614,19 +625,21 @@ public class HttpClient extends ContainerLifeCycle
|
|||
}
|
||||
|
||||
/**
|
||||
* @return the "User-Agent" HTTP header string of this {@link HttpClient}
|
||||
* @return the "User-Agent" HTTP field of this {@link HttpClient}
|
||||
*/
|
||||
public String getUserAgent()
|
||||
public HttpField getUserAgentField()
|
||||
{
|
||||
return agent;
|
||||
return agentField;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param agent the "User-Agent" HTTP header string of this {@link HttpClient}
|
||||
*/
|
||||
public void setUserAgent(String agent)
|
||||
public void setUserAgentField(HttpField agent)
|
||||
{
|
||||
this.agent = agent;
|
||||
if (agent.getHeader() != HttpHeader.USER_AGENT)
|
||||
throw new IllegalArgumentException();
|
||||
this.agentField = agent;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -844,6 +857,11 @@ public class HttpClient extends ContainerLifeCycle
|
|||
this.proxyConfig = proxyConfig;
|
||||
}
|
||||
|
||||
protected HttpField getAcceptEncodingField()
|
||||
{
|
||||
return encodingField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(Appendable out, String indent) throws IOException
|
||||
{
|
||||
|
@ -930,4 +948,118 @@ public class HttpClient extends ContainerLifeCycle
|
|||
this.promise = promise;
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
return set.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray()
|
||||
{
|
||||
return set.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T[] toArray(T[] a)
|
||||
{
|
||||
return set.toArray(a);
|
||||
}
|
||||
|
||||
protected 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,14 +20,12 @@ package org.eclipse.jetty.client;
|
|||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.HttpCookie;
|
||||
import java.net.URI;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
@ -37,8 +35,10 @@ import org.eclipse.jetty.client.api.ContentProvider;
|
|||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.client.api.Response;
|
||||
import org.eclipse.jetty.client.util.StringContentProvider;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpFields;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpHeaderValue;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpVersion;
|
||||
import org.eclipse.jetty.http.MimeTypes;
|
||||
|
@ -51,6 +51,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
public class HttpConnection extends AbstractConnection implements Connection
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(HttpConnection.class);
|
||||
private static final HttpField CHUNKED_FIELD = new HttpField(HttpHeader.TRANSFER_ENCODING, HttpHeaderValue.CHUNKED);
|
||||
|
||||
private final AtomicReference<HttpExchange> exchange = new AtomicReference<>();
|
||||
private final HttpClient client;
|
||||
|
@ -139,9 +140,6 @@ public class HttpConnection extends AbstractConnection implements Connection
|
|||
if (request.getVersion() == null)
|
||||
request.version(HttpVersion.HTTP_1_1);
|
||||
|
||||
if (request.getAgent() == null)
|
||||
request.agent(client.getUserAgent());
|
||||
|
||||
if (request.getIdleTimeout() <= 0)
|
||||
request.idleTimeout(client.getIdleTimeout(), TimeUnit.MILLISECONDS);
|
||||
|
||||
|
@ -150,16 +148,19 @@ public class HttpConnection extends AbstractConnection implements Connection
|
|||
HttpFields headers = request.getHeaders();
|
||||
ContentProvider content = request.getContent();
|
||||
|
||||
if (request.getAgent() == null)
|
||||
headers.put(client.getUserAgentField());
|
||||
|
||||
// Make sure the path is there
|
||||
String path = request.getPath();
|
||||
if (path.matches("\\s*"))
|
||||
if (path.trim().length() == 0)
|
||||
{
|
||||
path = "/";
|
||||
request.path(path);
|
||||
}
|
||||
if (destination.isProxied() && HttpMethod.CONNECT != request.getMethod())
|
||||
{
|
||||
path = request.getURI();
|
||||
path = request.getURI().toString();
|
||||
request.path(path);
|
||||
}
|
||||
|
||||
|
@ -208,13 +209,7 @@ public class HttpConnection extends AbstractConnection implements Connection
|
|||
if (version.getVersion() > 10)
|
||||
{
|
||||
if (!headers.containsKey(HttpHeader.HOST.asString()))
|
||||
{
|
||||
String value = request.getHost();
|
||||
int port = request.getPort();
|
||||
if (port > 0)
|
||||
value += ":" + port;
|
||||
headers.put(HttpHeader.HOST, value);
|
||||
}
|
||||
headers.put(getDestination().getHostField());
|
||||
}
|
||||
|
||||
// Add content headers
|
||||
|
@ -229,12 +224,12 @@ public class HttpConnection extends AbstractConnection implements Connection
|
|||
else
|
||||
{
|
||||
if (!headers.containsKey(HttpHeader.TRANSFER_ENCODING.asString()))
|
||||
headers.put(HttpHeader.TRANSFER_ENCODING, "chunked");
|
||||
headers.put(CHUNKED_FIELD);
|
||||
}
|
||||
}
|
||||
|
||||
// Cookies
|
||||
List<HttpCookie> cookies = client.getCookieStore().get(URI.create(request.getURI()));
|
||||
List<HttpCookie> cookies = client.getCookieStore().get(request.getURI());
|
||||
StringBuilder cookieString = null;
|
||||
for (int i = 0; i < cookies.size(); ++i)
|
||||
{
|
||||
|
@ -255,19 +250,9 @@ public class HttpConnection extends AbstractConnection implements Connection
|
|||
|
||||
if (!headers.containsKey(HttpHeader.ACCEPT_ENCODING.asString()))
|
||||
{
|
||||
Set<ContentDecoder.Factory> decoderFactories = client.getContentDecoderFactories();
|
||||
if (!decoderFactories.isEmpty())
|
||||
{
|
||||
StringBuilder value = new StringBuilder();
|
||||
for (Iterator<ContentDecoder.Factory> iterator = decoderFactories.iterator(); iterator.hasNext();)
|
||||
{
|
||||
ContentDecoder.Factory decoderFactory = iterator.next();
|
||||
value.append(decoderFactory.getEncoding());
|
||||
if (iterator.hasNext())
|
||||
value.append(",");
|
||||
}
|
||||
headers.put(HttpHeader.ACCEPT_ENCODING, value.toString());
|
||||
}
|
||||
HttpField acceptEncodingField = client.getAcceptEncodingField();
|
||||
if (acceptEncodingField != null)
|
||||
headers.put(acceptEncodingField);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -38,6 +38,7 @@ 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.TimedResponseListener;
|
||||
import org.eclipse.jetty.http.HttpField;
|
||||
import org.eclipse.jetty.http.HttpHeader;
|
||||
import org.eclipse.jetty.http.HttpMethod;
|
||||
import org.eclipse.jetty.http.HttpScheme;
|
||||
|
@ -63,6 +64,7 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
private final RequestNotifier requestNotifier;
|
||||
private final ResponseNotifier responseNotifier;
|
||||
private final InetSocketAddress proxyAddress;
|
||||
private final HttpField hostField;
|
||||
|
||||
public HttpDestination(HttpClient client, String scheme, String host, int port)
|
||||
{
|
||||
|
@ -79,6 +81,12 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
ProxyConfiguration proxyConfig = client.getProxyConfiguration();
|
||||
proxyAddress = proxyConfig != null && proxyConfig.matches(host, port) ?
|
||||
new InetSocketAddress(proxyConfig.getHost(), proxyConfig.getPort()) : null;
|
||||
|
||||
String hostValue = host;
|
||||
if ("https".equalsIgnoreCase(scheme) && port != 443 ||
|
||||
"http".equalsIgnoreCase(scheme) && port != 80)
|
||||
hostValue += ":" + port;
|
||||
hostField = new HttpField(HttpHeader.HOST, hostValue);
|
||||
}
|
||||
|
||||
protected BlockingQueue<Connection> getIdleConnections()
|
||||
|
@ -121,6 +129,11 @@ public class HttpDestination implements Destination, AutoCloseable, Dumpable
|
|||
return proxyAddress != null;
|
||||
}
|
||||
|
||||
public HttpField getHostField()
|
||||
{
|
||||
return hostField;
|
||||
}
|
||||
|
||||
public void send(Request request, List<Response.ResponseListener> listeners)
|
||||
{
|
||||
if (!scheme.equals(request.getScheme()))
|
||||
|
|
|
@ -224,13 +224,13 @@ public class HttpReceiver implements HttpParser.ResponseHandler<ByteBuffer>
|
|||
return false;
|
||||
}
|
||||
|
||||
private void storeCookie(String uri, HttpField field)
|
||||
private void storeCookie(URI uri, HttpField field)
|
||||
{
|
||||
try
|
||||
{
|
||||
Map<String, List<String>> header = new HashMap<>(1);
|
||||
header.put(field.getHeader().asString(), Collections.singletonList(field.getValue()));
|
||||
connection.getHttpClient().getCookieManager().put(URI.create(uri), header);
|
||||
connection.getHttpClient().getCookieManager().put(uri, header);
|
||||
}
|
||||
catch (IOException x)
|
||||
{
|
||||
|
|
|
@ -59,6 +59,7 @@ public class HttpRequest implements Request
|
|||
private final long conversation;
|
||||
private final String host;
|
||||
private final int port;
|
||||
private URI uri;
|
||||
private String scheme;
|
||||
private String path;
|
||||
private HttpMethod method;
|
||||
|
@ -91,6 +92,7 @@ public class HttpRequest implements Request
|
|||
param(parts[0], parts.length < 2 ? "" : urlDecode(parts[1]));
|
||||
}
|
||||
}
|
||||
this.uri = buildURI();
|
||||
followRedirects(client.isFollowRedirects());
|
||||
}
|
||||
|
||||
|
@ -123,6 +125,7 @@ public class HttpRequest implements Request
|
|||
public Request scheme(String scheme)
|
||||
{
|
||||
this.scheme = scheme;
|
||||
this.uri = buildURI();
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -161,19 +164,14 @@ public class HttpRequest implements Request
|
|||
public Request path(String path)
|
||||
{
|
||||
this.path = path;
|
||||
this.uri = buildURI();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getURI()
|
||||
public URI getURI()
|
||||
{
|
||||
String scheme = getScheme();
|
||||
String result = scheme + "://" + getHost();
|
||||
int port = getPort();
|
||||
result += "http".equals(scheme) && port != 80 ? ":" + port : "";
|
||||
result += "https".equals(scheme) && port != 443 ? ":" + port : "";
|
||||
result += getPath();
|
||||
return result;
|
||||
return uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -247,9 +245,14 @@ public class HttpRequest implements Request
|
|||
@Override
|
||||
public <T extends RequestListener> List<T> getRequestListeners(Class<T> type)
|
||||
{
|
||||
// This method is invoked often in a request/response conversation,
|
||||
// so we avoid allocation if there is no need to filter.
|
||||
if (type == null)
|
||||
return (List<T>)requestListeners;
|
||||
|
||||
ArrayList<T> result = new ArrayList<>();
|
||||
for (RequestListener listener : requestListeners)
|
||||
if (type == null || type.isInstance(listener))
|
||||
if (type.isInstance(listener))
|
||||
result.add((T)listener);
|
||||
return result;
|
||||
}
|
||||
|
@ -466,6 +469,11 @@ public class HttpRequest implements Request
|
|||
return aborted;
|
||||
}
|
||||
|
||||
private URI buildURI()
|
||||
{
|
||||
return URI.create(getScheme() + "://" + getHost() + ":" + getPort() + getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
|
@ -65,7 +66,7 @@ public class RedirectProtocolHandler extends Response.Listener.Empty implements
|
|||
{
|
||||
Request request = result.getRequest();
|
||||
Response response = result.getResponse();
|
||||
String location = response.getHeaders().get("location");
|
||||
URI location = URI.create(response.getHeaders().get("location"));
|
||||
int status = response.getStatus();
|
||||
switch (status)
|
||||
{
|
||||
|
@ -103,7 +104,7 @@ public class RedirectProtocolHandler extends Response.Listener.Empty implements
|
|||
}
|
||||
}
|
||||
|
||||
private void redirect(Result result, HttpMethod method, String location)
|
||||
private void redirect(Result result, HttpMethod method, URI location)
|
||||
{
|
||||
final Request request = result.getRequest();
|
||||
HttpConversation conversation = client.getConversation(request.getConversationID(), false);
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -35,18 +37,27 @@ public class RequestNotifier
|
|||
|
||||
public void notifyQueued(Request request)
|
||||
{
|
||||
for (Request.QueuedListener listener : request.getRequestListeners(Request.QueuedListener.class))
|
||||
notifyQueued(listener, request);
|
||||
for (Request.Listener listener : client.getRequestListeners())
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
List<Request.RequestListener> requestListeners = request.getRequestListeners(null);
|
||||
for (int i = 0; i < requestListeners.size(); ++i)
|
||||
{
|
||||
Request.RequestListener listener = requestListeners.get(i);
|
||||
if (listener instanceof Request.QueuedListener)
|
||||
notifyQueued((Request.QueuedListener)listener, request);
|
||||
}
|
||||
List<Request.Listener> listeners = client.getRequestListeners();
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Request.Listener listener = listeners.get(i);
|
||||
notifyQueued(listener, request);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyQueued(Request.QueuedListener listener, Request request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (listener != null)
|
||||
listener.onQueued(request);
|
||||
listener.onQueued(request);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
|
@ -56,18 +67,27 @@ public class RequestNotifier
|
|||
|
||||
public void notifyBegin(Request request)
|
||||
{
|
||||
for (Request.BeginListener listener : request.getRequestListeners(Request.BeginListener.class))
|
||||
notifyBegin(listener, request);
|
||||
for (Request.Listener listener : client.getRequestListeners())
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
List<Request.RequestListener> requestListeners = request.getRequestListeners(null);
|
||||
for (int i = 0; i < requestListeners.size(); ++i)
|
||||
{
|
||||
Request.RequestListener listener = requestListeners.get(i);
|
||||
if (listener instanceof Request.BeginListener)
|
||||
notifyBegin((Request.BeginListener)listener, request);
|
||||
}
|
||||
List<Request.Listener> listeners = client.getRequestListeners();
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Request.Listener listener = listeners.get(i);
|
||||
notifyBegin(listener, request);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyBegin(Request.BeginListener listener, Request request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (listener != null)
|
||||
listener.onBegin(request);
|
||||
listener.onBegin(request);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
|
@ -77,18 +97,27 @@ public class RequestNotifier
|
|||
|
||||
public void notifyHeaders(Request request)
|
||||
{
|
||||
for (Request.HeadersListener listener : request.getRequestListeners(Request.HeadersListener.class))
|
||||
notifyHeaders(listener, request);
|
||||
for (Request.Listener listener : client.getRequestListeners())
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
List<Request.RequestListener> requestListeners = request.getRequestListeners(null);
|
||||
for (int i = 0; i < requestListeners.size(); ++i)
|
||||
{
|
||||
Request.RequestListener listener = requestListeners.get(i);
|
||||
if (listener instanceof Request.HeadersListener)
|
||||
notifyHeaders((Request.HeadersListener)listener, request);
|
||||
}
|
||||
List<Request.Listener> listeners = client.getRequestListeners();
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Request.Listener listener = listeners.get(i);
|
||||
notifyHeaders(listener, request);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyHeaders(Request.HeadersListener listener, Request request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (listener != null)
|
||||
listener.onHeaders(request);
|
||||
listener.onHeaders(request);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
|
@ -98,18 +127,27 @@ public class RequestNotifier
|
|||
|
||||
public void notifyCommit(Request request)
|
||||
{
|
||||
for (Request.CommitListener listener : request.getRequestListeners(Request.CommitListener.class))
|
||||
notifyCommit(listener, request);
|
||||
for (Request.Listener listener : client.getRequestListeners())
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
List<Request.RequestListener> requestListeners = request.getRequestListeners(null);
|
||||
for (int i = 0; i < requestListeners.size(); ++i)
|
||||
{
|
||||
Request.RequestListener listener = requestListeners.get(i);
|
||||
if (listener instanceof Request.CommitListener)
|
||||
notifyCommit((Request.CommitListener)listener, request);
|
||||
}
|
||||
List<Request.Listener> listeners = client.getRequestListeners();
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Request.Listener listener = listeners.get(i);
|
||||
notifyCommit(listener, request);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyCommit(Request.CommitListener listener, Request request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (listener != null)
|
||||
listener.onCommit(request);
|
||||
listener.onCommit(request);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
|
@ -119,18 +157,27 @@ public class RequestNotifier
|
|||
|
||||
public void notifySuccess(Request request)
|
||||
{
|
||||
for (Request.SuccessListener listener : request.getRequestListeners(Request.SuccessListener.class))
|
||||
notifySuccess(listener, request);
|
||||
for (Request.Listener listener : client.getRequestListeners())
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
List<Request.RequestListener> requestListeners = request.getRequestListeners(null);
|
||||
for (int i = 0; i < requestListeners.size(); ++i)
|
||||
{
|
||||
Request.RequestListener listener = requestListeners.get(i);
|
||||
if (listener instanceof Request.SuccessListener)
|
||||
notifySuccess((Request.SuccessListener)listener, request);
|
||||
}
|
||||
List<Request.Listener> listeners = client.getRequestListeners();
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Request.Listener listener = listeners.get(i);
|
||||
notifySuccess(listener, request);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifySuccess(Request.SuccessListener listener, Request request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (listener != null)
|
||||
listener.onSuccess(request);
|
||||
listener.onSuccess(request);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
|
@ -140,18 +187,27 @@ public class RequestNotifier
|
|||
|
||||
public void notifyFailure(Request request, Throwable failure)
|
||||
{
|
||||
for (Request.FailureListener listener : request.getRequestListeners(Request.FailureListener.class))
|
||||
notifyFailure(listener, request, failure);
|
||||
for (Request.Listener listener : client.getRequestListeners())
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
List<Request.RequestListener> requestListeners = request.getRequestListeners(null);
|
||||
for (int i = 0; i < requestListeners.size(); ++i)
|
||||
{
|
||||
Request.RequestListener listener = requestListeners.get(i);
|
||||
if (listener instanceof Request.FailureListener)
|
||||
notifyFailure((Request.FailureListener)listener, request, failure);
|
||||
}
|
||||
List<Request.Listener> listeners = client.getRequestListeners();
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Request.Listener listener = listeners.get(i);
|
||||
notifyFailure(listener, request, failure);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyFailure(Request.FailureListener listener, Request request, Throwable failure)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (listener != null)
|
||||
listener.onFailure(request, failure);
|
||||
listener.onFailure(request, failure);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
|
|
|
@ -42,9 +42,13 @@ public class ResponseNotifier
|
|||
|
||||
public void notifyBegin(List<Response.ResponseListener> listeners, Response response)
|
||||
{
|
||||
for (Response.ResponseListener listener : listeners)
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Response.ResponseListener listener = listeners.get(i);
|
||||
if (listener instanceof Response.BeginListener)
|
||||
notifyBegin((Response.BeginListener)listener, response);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyBegin(Response.BeginListener listener, Response response)
|
||||
|
@ -62,9 +66,13 @@ public class ResponseNotifier
|
|||
public boolean notifyHeader(List<Response.ResponseListener> listeners, Response response, HttpField field)
|
||||
{
|
||||
boolean result = true;
|
||||
for (Response.ResponseListener listener : listeners)
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Response.ResponseListener listener = listeners.get(i);
|
||||
if (listener instanceof Response.HeaderListener)
|
||||
result &= notifyHeader((Response.HeaderListener)listener, response, field);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -83,9 +91,13 @@ public class ResponseNotifier
|
|||
|
||||
public void notifyHeaders(List<Response.ResponseListener> listeners, Response response)
|
||||
{
|
||||
for (Response.ResponseListener listener : listeners)
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Response.ResponseListener listener = listeners.get(i);
|
||||
if (listener instanceof Response.HeadersListener)
|
||||
notifyHeaders((Response.HeadersListener)listener, response);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyHeaders(Response.HeadersListener listener, Response response)
|
||||
|
@ -102,10 +114,13 @@ public class ResponseNotifier
|
|||
|
||||
public void notifyContent(List<Response.ResponseListener> listeners, Response response, ByteBuffer buffer)
|
||||
{
|
||||
for (Response.ResponseListener listener : listeners)
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Response.ResponseListener listener = listeners.get(i);
|
||||
if (listener instanceof Response.ContentListener)
|
||||
notifyContent((Response.ContentListener)listener, response, buffer);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyContent(Response.ContentListener listener, Response response, ByteBuffer buffer)
|
||||
|
@ -122,9 +137,13 @@ public class ResponseNotifier
|
|||
|
||||
public void notifySuccess(List<Response.ResponseListener> listeners, Response response)
|
||||
{
|
||||
for (Response.ResponseListener listener : listeners)
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Response.ResponseListener listener = listeners.get(i);
|
||||
if (listener instanceof Response.SuccessListener)
|
||||
notifySuccess((Response.SuccessListener)listener, response);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifySuccess(Response.SuccessListener listener, Response response)
|
||||
|
@ -141,9 +160,13 @@ public class ResponseNotifier
|
|||
|
||||
public void notifyFailure(List<Response.ResponseListener> listeners, Response response, Throwable failure)
|
||||
{
|
||||
for (Response.ResponseListener listener : listeners)
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Response.ResponseListener listener = listeners.get(i);
|
||||
if (listener instanceof Response.FailureListener)
|
||||
notifyFailure((Response.FailureListener)listener, response, failure);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyFailure(Response.FailureListener listener, Response response, Throwable failure)
|
||||
|
@ -160,9 +183,13 @@ public class ResponseNotifier
|
|||
|
||||
public void notifyComplete(List<Response.ResponseListener> listeners, Result result)
|
||||
{
|
||||
for (Response.ResponseListener listener : listeners)
|
||||
// Optimized to avoid allocations of iterator instances
|
||||
for (int i = 0; i < listeners.size(); ++i)
|
||||
{
|
||||
Response.ResponseListener listener = listeners.get(i);
|
||||
if (listener instanceof Response.CompleteListener)
|
||||
notifyComplete((Response.CompleteListener)listener, result);
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyComplete(Response.CompleteListener listener, Result result)
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
package org.eclipse.jetty.client.api;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.eclipse.jetty.util.Attributes;
|
||||
|
||||
/**
|
||||
|
@ -42,7 +44,7 @@ public interface Authentication
|
|||
* @param realm the authentication realm as provided in the {@code WWW-Authenticate} response header
|
||||
* @return true if this authentication matches, false otherwise
|
||||
*/
|
||||
boolean matches(String type, String uri, String realm);
|
||||
boolean matches(String type, URI uri, String realm);
|
||||
|
||||
/**
|
||||
* Executes the authentication mechanism for the given request, returning a {@link Result} that can be
|
||||
|
@ -70,7 +72,7 @@ public interface Authentication
|
|||
/**
|
||||
* @return the URI of the request that has been used to generate this {@link Result}
|
||||
*/
|
||||
String getURI();
|
||||
URI getURI();
|
||||
|
||||
/**
|
||||
* Applies the authentication result to the given request.
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
package org.eclipse.jetty.client.api;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* A store for {@link Authentication}s and {@link Authentication.Result}s.
|
||||
*/
|
||||
|
@ -48,7 +50,7 @@ public interface AuthenticationStore
|
|||
* @param realm the authentication realm
|
||||
* @return the authentication that matches the given parameters, or null
|
||||
*/
|
||||
public Authentication findAuthentication(String type, String uri, String realm);
|
||||
public Authentication findAuthentication(String type, URI uri, String realm);
|
||||
|
||||
/**
|
||||
* @param result the {@link Authentication.Result} to add
|
||||
|
@ -72,5 +74,5 @@ public interface AuthenticationStore
|
|||
* @param uri the request URI
|
||||
* @return the {@link Authentication.Result} that matches the given URI, or null
|
||||
*/
|
||||
public Authentication.Result findAuthenticationResult(String uri);
|
||||
public Authentication.Result findAuthenticationResult(URI uri);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.client.api;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.file.Path;
|
||||
import java.util.EventListener;
|
||||
import java.util.List;
|
||||
|
@ -96,7 +97,7 @@ public interface Request
|
|||
/**
|
||||
* @return the full URI of this request such as "http://host:port/path"
|
||||
*/
|
||||
String getURI();
|
||||
URI getURI();
|
||||
|
||||
/**
|
||||
* @return the HTTP version of this request, such as "HTTP/1.1"
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
package org.eclipse.jetty.client.util;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.Authentication;
|
||||
import org.eclipse.jetty.client.api.AuthenticationStore;
|
||||
|
@ -37,7 +39,7 @@ import org.eclipse.jetty.util.StringUtil;
|
|||
*/
|
||||
public class BasicAuthentication implements Authentication
|
||||
{
|
||||
private final String uri;
|
||||
private final URI uri;
|
||||
private final String realm;
|
||||
private final String user;
|
||||
private final String password;
|
||||
|
@ -48,7 +50,7 @@ public class BasicAuthentication implements Authentication
|
|||
* @param user the user that wants to authenticate
|
||||
* @param password the password of the user
|
||||
*/
|
||||
public BasicAuthentication(String uri, String realm, String user, String password)
|
||||
public BasicAuthentication(URI uri, String realm, String user, String password)
|
||||
{
|
||||
this.uri = uri;
|
||||
this.realm = realm;
|
||||
|
@ -57,12 +59,12 @@ public class BasicAuthentication implements Authentication
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(String type, String uri, String realm)
|
||||
public boolean matches(String type, URI uri, String realm)
|
||||
{
|
||||
if (!"basic".equalsIgnoreCase(type))
|
||||
return false;
|
||||
|
||||
if (!uri.startsWith(this.uri))
|
||||
if (!uri.toString().startsWith(this.uri.toString()))
|
||||
return false;
|
||||
|
||||
return this.realm.equals(realm);
|
||||
|
@ -78,17 +80,17 @@ public class BasicAuthentication implements Authentication
|
|||
|
||||
private static class BasicResult implements Result
|
||||
{
|
||||
private final String uri;
|
||||
private final URI uri;
|
||||
private final String value;
|
||||
|
||||
public BasicResult(String uri, String value)
|
||||
public BasicResult(URI uri, String value)
|
||||
{
|
||||
this.uri = uri;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getURI()
|
||||
public URI getURI()
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
|
@ -96,7 +98,7 @@ public class BasicAuthentication implements Authentication
|
|||
@Override
|
||||
public void apply(Request request)
|
||||
{
|
||||
if (request.getURI().startsWith(uri))
|
||||
if (request.getURI().toString().startsWith(uri.toString()))
|
||||
request.header(HttpHeader.AUTHORIZATION.asString(), value);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.eclipse.jetty.client.util;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
@ -52,7 +53,7 @@ public class DigestAuthentication implements Authentication
|
|||
{
|
||||
private static final Pattern PARAM_PATTERN = Pattern.compile("([^=]+)=(.*)");
|
||||
|
||||
private final String uri;
|
||||
private final URI uri;
|
||||
private final String realm;
|
||||
private final String user;
|
||||
private final String password;
|
||||
|
@ -63,7 +64,7 @@ public class DigestAuthentication implements Authentication
|
|||
* @param user the user that wants to authenticate
|
||||
* @param password the password of the user
|
||||
*/
|
||||
public DigestAuthentication(String uri, String realm, String user, String password)
|
||||
public DigestAuthentication(URI uri, String realm, String user, String password)
|
||||
{
|
||||
this.uri = uri;
|
||||
this.realm = realm;
|
||||
|
@ -72,12 +73,12 @@ public class DigestAuthentication implements Authentication
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(String type, String uri, String realm)
|
||||
public boolean matches(String type, URI uri, String realm)
|
||||
{
|
||||
if (!"digest".equalsIgnoreCase(type))
|
||||
return false;
|
||||
|
||||
if (!uri.startsWith(this.uri))
|
||||
if (!uri.toString().startsWith(this.uri.toString()))
|
||||
return false;
|
||||
|
||||
return this.realm.equals(realm);
|
||||
|
@ -180,7 +181,7 @@ public class DigestAuthentication implements Authentication
|
|||
private class DigestResult implements Result
|
||||
{
|
||||
private final AtomicInteger nonceCount = new AtomicInteger();
|
||||
private final String uri;
|
||||
private final URI uri;
|
||||
private final byte[] content;
|
||||
private final String realm;
|
||||
private final String user;
|
||||
|
@ -190,7 +191,7 @@ public class DigestAuthentication implements Authentication
|
|||
private final String qop;
|
||||
private final String opaque;
|
||||
|
||||
public DigestResult(String uri, byte[] content, String realm, String user, String password, String algorithm, String nonce, String qop, String opaque)
|
||||
public DigestResult(URI uri, byte[] content, String realm, String user, String password, String algorithm, String nonce, String qop, String opaque)
|
||||
{
|
||||
this.uri = uri;
|
||||
this.content = content;
|
||||
|
@ -204,7 +205,7 @@ public class DigestAuthentication implements Authentication
|
|||
}
|
||||
|
||||
@Override
|
||||
public String getURI()
|
||||
public URI getURI()
|
||||
{
|
||||
return uri;
|
||||
}
|
||||
|
@ -212,7 +213,7 @@ public class DigestAuthentication implements Authentication
|
|||
@Override
|
||||
public void apply(Request request)
|
||||
{
|
||||
if (!request.getURI().startsWith(uri))
|
||||
if (!request.getURI().toString().startsWith(uri.toString()))
|
||||
return;
|
||||
|
||||
MessageDigest digester = getMessageDigest(algorithm);
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.client;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
@ -34,7 +35,6 @@ import org.eclipse.jetty.client.api.ContentResponse;
|
|||
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.http.HttpHeader;
|
||||
import org.eclipse.jetty.security.Authenticator;
|
||||
import org.eclipse.jetty.security.ConstraintMapping;
|
||||
import org.eclipse.jetty.security.ConstraintSecurityHandler;
|
||||
|
@ -99,7 +99,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
public void test_BasicAuthentication() throws Exception
|
||||
{
|
||||
startBasic(new EmptyServerHandler());
|
||||
String uri = scheme + "://localhost:" + connector.getLocalPort();
|
||||
URI uri = URI.create(scheme + "://localhost:" + connector.getLocalPort());
|
||||
test_Authentication(new BasicAuthentication(uri, realm, "basic", "basic"));
|
||||
}
|
||||
|
||||
|
@ -107,7 +107,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
public void test_DigestAuthentication() throws Exception
|
||||
{
|
||||
startDigest(new EmptyServerHandler());
|
||||
String uri = scheme + "://localhost:" + connector.getLocalPort();
|
||||
URI uri = URI.create(scheme + "://localhost:" + connector.getLocalPort());
|
||||
test_Authentication(new DigestAuthentication(uri, realm, "digest", "digest"));
|
||||
}
|
||||
|
||||
|
@ -148,6 +148,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
client.getRequestListeners().add(requestListener);
|
||||
|
||||
// Request with authentication causes a 401 (no previous successful authentication) + 200
|
||||
request = client.newRequest("localhost", connector.getLocalPort()).scheme(scheme).path("/secure");
|
||||
response = request.timeout(5, TimeUnit.SECONDS).send();
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals(200, response.getStatus());
|
||||
|
@ -167,7 +168,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
|
||||
// Further requests do not trigger 401 because there is a previous successful authentication
|
||||
// Remove existing header to be sure it's added by the implementation
|
||||
request.header(HttpHeader.AUTHORIZATION.asString(), null);
|
||||
request = client.newRequest("localhost", connector.getLocalPort()).scheme(scheme).path("/secure");
|
||||
response = request.timeout(5, TimeUnit.SECONDS).send();
|
||||
Assert.assertNotNull(response);
|
||||
Assert.assertEquals(200, response.getStatus());
|
||||
|
@ -191,7 +192,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
}
|
||||
});
|
||||
|
||||
String uri = scheme + "://localhost:" + connector.getLocalPort();
|
||||
URI uri = URI.create(scheme + "://localhost:" + connector.getLocalPort());
|
||||
client.getAuthenticationStore().addAuthentication(new BasicAuthentication(uri, realm, "basic", "basic"));
|
||||
|
||||
final CountDownLatch requests = new CountDownLatch(3);
|
||||
|
@ -230,7 +231,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
}
|
||||
});
|
||||
|
||||
String uri = scheme + "://localhost:" + connector.getLocalPort();
|
||||
URI uri = URI.create(scheme + "://localhost:" + connector.getLocalPort());
|
||||
client.getAuthenticationStore().addAuthentication(new BasicAuthentication(uri, realm, "basic", "basic"));
|
||||
|
||||
final CountDownLatch requests = new CountDownLatch(3);
|
||||
|
@ -272,7 +273,7 @@ public class HttpClientAuthenticationTest extends AbstractHttpClientServerTest
|
|||
client.getRequestListeners().add(requestListener);
|
||||
|
||||
AuthenticationStore authenticationStore = client.getAuthenticationStore();
|
||||
String uri = scheme + "://localhost:" + connector.getLocalPort();
|
||||
URI uri = URI.create(scheme + "://localhost:" + connector.getLocalPort());
|
||||
BasicAuthentication authentication = new BasicAuthentication(uri, realm, "basic", "basic");
|
||||
authenticationStore.addAuthentication(authentication);
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
package org.eclipse.jetty.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -113,13 +114,14 @@ public class HttpClientLoadTest extends AbstractHttpClientServerTest
|
|||
Assert.assertTrue(failures.toString(), failures.isEmpty());
|
||||
}
|
||||
|
||||
private void test(Random random, final CountDownLatch latch, final List<String> failures)
|
||||
private void test(Random random, final CountDownLatch latch, final List<String> failures) throws InterruptedException
|
||||
{
|
||||
int maxContentLength = 64 * 1024;
|
||||
|
||||
// Choose a random destination
|
||||
String host = random.nextBoolean() ? "localhost" : "127.0.0.1";
|
||||
Request request = client.newRequest(host, connector.getLocalPort()).scheme(scheme);
|
||||
URI uri = URI.create(scheme + "://" + host + ":" + connector.getLocalPort());
|
||||
Request request = client.newRequest(uri);
|
||||
|
||||
// Choose a random method
|
||||
HttpMethod method = random.nextBoolean() ? HttpMethod.GET : HttpMethod.POST;
|
||||
|
@ -147,6 +149,7 @@ public class HttpClientLoadTest extends AbstractHttpClientServerTest
|
|||
break;
|
||||
}
|
||||
|
||||
final CountDownLatch requestLatch = new CountDownLatch(1);
|
||||
request.send(new Response.Listener.Empty()
|
||||
{
|
||||
private final AtomicInteger contentLength = new AtomicInteger();
|
||||
|
@ -175,9 +178,11 @@ public class HttpClientLoadTest extends AbstractHttpClientServerTest
|
|||
}
|
||||
if (contentLength.get() != 0)
|
||||
failures.add("Content length mismatch " + contentLength);
|
||||
requestLatch.countDown();
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
requestLatch.await(5, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private class LoadHandler extends AbstractHandler
|
||||
|
|
|
@ -192,7 +192,7 @@ public class Usage
|
|||
HttpClient client = new HttpClient();
|
||||
client.start();
|
||||
|
||||
String uri = "http://localhost:8080/secure";
|
||||
URI uri = URI.create("http://localhost:8080/secure");
|
||||
|
||||
// Setup Basic authentication credentials for TestRealm
|
||||
client.getAuthenticationStore().addAuthentication(new BasicAuthentication(uri, "TestRealm", "username", "password"));
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.io.FileOutputStream;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URLDecoder;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
|
@ -301,7 +302,7 @@ public class JdbcLoginServiceTest
|
|||
executor.setName(executor.getName() + "-client");
|
||||
_client.setExecutor(executor);
|
||||
AuthenticationStore authStore = _client.getAuthenticationStore();
|
||||
authStore.addAuthentication(new BasicAuthentication(_baseUrl, __realm, "jetty", "jetty"));
|
||||
authStore.addAuthentication(new BasicAuthentication(URI.create(_baseUrl), __realm, "jetty", "jetty"));
|
||||
_client.start();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue