Skip to content
Commits on Source (44)
......@@ -18,3 +18,4 @@ test-output
/META-INF/MANIFEST.MF
work
atlassian-ide-plugin.xml
/nb-configuration.xml
\ No newline at end of file
......@@ -9,7 +9,7 @@
<groupId>com.ning</groupId>
<artifactId>async-http-client</artifactId>
<name>Asynchronous Http Client</name>
<version>1.8.12</version>
<version>1.9.40</version>
<packaging>jar</packaging>
<description>
Async Http Client library purpose is to allow Java applications to easily execute HTTP requests and
......@@ -81,13 +81,32 @@
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
<version>3.9.2.Final</version>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.grizzly</groupId>
<artifactId>connection-pool</artifactId>
<version>${grizzly.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.glassfish.grizzly</groupId>
<artifactId>grizzly-websockets</artifactId>
<version>${grizzly.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.glassfish.grizzly</groupId>
<artifactId>grizzly-http-server</artifactId>
<version>${grizzly.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
<version>1.7.12</version>
</dependency>
<dependency>
......@@ -101,21 +120,26 @@
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
<version>1.1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.13</version>
<version>1.2.17</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>5.8</version>
<version>6.8.8</version>
<scope>test</scope>
<classifier>jdk15</classifier>
<exclusions>
<exclusion>
<groupId>org.beanshell</groupId>
<artifactId>bsh</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
......@@ -178,26 +202,6 @@
<version>1.2.2</version>
<scope>test</scope>
</dependency>
<!-- Optional Apache Http Client -->
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<extensions>
......@@ -230,15 +234,7 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${source.property}</source>
<target>${target.property}</target>
<maxmem>1024m</maxmem>
<excludes>
<exclude>${compiler.exclude}</exclude>
</excludes>
<testExcludes>
<testExclude>${test.compiler.exclude}</testExclude>
</testExcludes>
</configuration>
</plugin>
<plugin>
......@@ -250,20 +246,28 @@
<redirectTestOutputToFile>${surefire.redirectTestOutputToFile}</redirectTestOutputToFile>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-plugin</artifactId>
<version>1.6</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>1.6</version>
<version>1.14</version>
<configuration>
<signature>
<groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java15</artifactId>
<artifactId>java17</artifactId>
<version>1.0</version>
</signature>
<ignores>
<ignore>sun.misc.Unsafe</ignore>
</ignores>
</configuration>
<executions>
<execution>
<id>check-java-1.5-compat</id>
<id>check-java-1.7-compat</id>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
......@@ -319,7 +323,7 @@
<version>2.0.9</version>
</requireMavenVersion>
<requireJavaVersion>
<version>1.5</version>
<version>${maven.compiler.source}</version>
</requireJavaVersion>
</rules>
</configuration>
......@@ -376,13 +380,12 @@
<version>2.8.1</version>
<configuration>
<aggregate>true</aggregate>
<source>1.6</source>
<source>${maven.compiler.source}</source>
<encoding>UTF-8</encoding>
<maxmemory>1g</maxmemory>
<links>
<link>http://java.sun.com/javase/6/docs/api/</link>
</links>
<excludePackageNames>${javadoc.package.exclude}</excludePackageNames>
</configuration>
<executions>
<execution>
......@@ -394,38 +397,6 @@
</execution>
</executions>
</plugin>
<!-- <plugin> -->
<!-- <groupId>org.apache.maven.plugins</groupId> -->
<!-- <artifactId>maven-shade-plugin</artifactId> -->
<!-- <version>1.2.1</version> -->
<!-- <executions> -->
<!-- <execution> -->
<!-- <phase>package</phase> -->
<!-- <goals> -->
<!-- <goal>shade</goal> -->
<!-- </goals> -->
<!-- <configuration> -->
<!-- <shadedArtifactAttached>true</shadedArtifactAttached> -->
<!-- <shadedClassifierName>shaded</shadedClassifierName> -->
<!-- <artifactSet> -->
<!-- <excludes> -->
<!-- <exclude>commons-codec:commons-codec</exclude> -->
<!-- <exclude>commons-lang:commons-lang</exclude> -->
<!-- <exclude>commons-logging:commons-logging</exclude> -->
<!-- <exclude>junit:junit</exclude> -->
<!-- <exclude>log4j:log4j</exclude> -->
<!-- <exclude>commons-httpclient:commons-httpclient</exclude> -->
<!-- </excludes> -->
<!-- </artifactSet> -->
<!-- <transformers> -->
<!-- <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" /> -->
<!-- <transformer implementation="org.apache.maven.plugins.shade.resource.ComponentsXmlResourceTransformer" /> -->
<!-- <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer" /> -->
<!-- </transformers> -->
<!-- </configuration> -->
<!-- </execution> -->
<!-- </executions> -->
<!-- </plugin> -->
</plugins>
</build>
<reporting>
......@@ -436,13 +407,12 @@
<version>2.8.1</version>
<configuration>
<aggregate>true</aggregate>
<source>1.6</source>
<source>${maven.compiler.source}</source>
<encoding>UTF-8</encoding>
<maxmemory>1g</maxmemory>
<links>
<link>http://java.sun.com/javase/6/docs/api/</link>
<link>http://java.sun.com/javase/7/docs/api/</link>
</links>
<excludePackageNames>${javadoc.package.exclude}</excludePackageNames>
<bootclasspath>${sun.boot.class.path}</bootclasspath>
<doclet>com.google.doclava.Doclava</doclet>
<useStandardDocletOptions>false</useStandardDocletOptions>
......@@ -474,32 +444,6 @@
</plugins>
</reporting>
<profiles>
<profile>
<id>grizzly</id>
<activation>
<jdk>[1.6,)</jdk>
</activation>
<properties>
<compiler.exclude>asdfasfd/**</compiler.exclude>
<test.compiler.exclude>asdfasdf/**</test.compiler.exclude>
<javadoc.package.exclude>asdfasdf</javadoc.package.exclude>
<target.property>1.5</target.property>
</properties>
<dependencies>
<dependency>
<groupId>org.glassfish.grizzly</groupId>
<artifactId>grizzly-websockets</artifactId>
<version>${grizzly.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.glassfish.grizzly</groupId>
<artifactId>grizzly-http-server</artifactId>
<version>${grizzly.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</profile>
<profile>
<id>release-sign-artifacts</id>
<activation>
......@@ -586,14 +530,13 @@
</repository>
</repositories>
<properties>
<additionalparam>-Xdoclint:none</additionalparam>
<distMgmtSnapshotsUrl>http://oss.sonatype.org/content/repositories/snapshots</distMgmtSnapshotsUrl>
<surefire.redirectTestOutputToFile>true</surefire.redirectTestOutputToFile>
<compiler.exclude>com/ning/http/client/providers/grizzly/*.java</compiler.exclude>
<test.compiler.exclude>com/ning/http/client/async/grizzly/*.java</test.compiler.exclude>
<javadoc.package.exclude>com.ning.http.client.providers.grizzly</javadoc.package.exclude>
<grizzly.version>2.3.14</grizzly.version>
<source.property>1.5</source.property>
<target.property>1.5</target.property>
<netty.version>3.10.6.Final</netty.version>
<grizzly.version>2.3.26</grizzly.version>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<surefire.version>2.12</surefire.version>
</properties>
</project>
......
......@@ -28,53 +28,40 @@ import org.slf4j.LoggerFactory;
*/
public abstract class AsyncCompletionHandler<T> implements AsyncHandler<T>, ProgressAsyncHandler<T> {
private final Logger log = LoggerFactory.getLogger(AsyncCompletionHandlerBase.class);
private static final Logger LOGGER = LoggerFactory.getLogger(AsyncCompletionHandler.class);
private final Response.ResponseBuilder builder = new Response.ResponseBuilder();
/**
* {@inheritDoc}
*/
@Override
public STATE onBodyPartReceived(final HttpResponseBodyPart content) throws Exception {
builder.accumulate(content);
return STATE.CONTINUE;
}
/**
* {@inheritDoc}
*/
@Override
public STATE onStatusReceived(final HttpResponseStatus status) throws Exception {
builder.reset();
builder.accumulate(status);
return STATE.CONTINUE;
}
/**
* {@inheritDoc}
*/
@Override
public STATE onHeadersReceived(final HttpResponseHeaders headers) throws Exception {
builder.accumulate(headers);
return STATE.CONTINUE;
}
/**
* {@inheritDoc}
*/
@Override
public final T onCompleted() throws Exception {
return onCompleted(builder.build());
}
/**
* {@inheritDoc}
*/
@Override
public void onThrowable(Throwable t) {
log.debug(t.getMessage(), t);
LOGGER.debug(t.getMessage(), t);
}
/**
* Invoked once the HTTP response processing is finished.
* <p/>
* <p/>
* Gets always invoked as last callback method.
*
* @param response The {@link Response}
* @return T Value that will be returned by the associated {@link java.util.concurrent.Future}
......@@ -88,6 +75,7 @@ public abstract class AsyncCompletionHandler<T> implements AsyncHandler<T>, Prog
*
* @return a {@link com.ning.http.client.AsyncHandler.STATE} telling to CONTINUE or ABORT the current processing.
*/
@Override
public STATE onHeaderWriteCompleted() {
return STATE.CONTINUE;
}
......@@ -98,6 +86,7 @@ public abstract class AsyncCompletionHandler<T> implements AsyncHandler<T>, Prog
*
* @return a {@link com.ning.http.client.AsyncHandler.STATE} telling to CONTINUE or ABORT the current processing.
*/
@Override
public STATE onContentWriteCompleted() {
return STATE.CONTINUE;
}
......@@ -110,6 +99,7 @@ public abstract class AsyncCompletionHandler<T> implements AsyncHandler<T>, Prog
* @param total The total number of bytes transferred
* @return a {@link com.ning.http.client.AsyncHandler.STATE} telling to CONTINUE or ABORT the current processing.
*/
@Override
public STATE onContentWriteProgress(long amount, long current, long total) {
return STATE.CONTINUE;
}
......
......@@ -23,21 +23,15 @@ import org.slf4j.LoggerFactory;
* Simple {@link AsyncHandler} of type {@link Response}
*/
public class AsyncCompletionHandlerBase extends AsyncCompletionHandler<Response> {
private final Logger log = LoggerFactory.getLogger(AsyncCompletionHandlerBase.class);
private static final Logger LOGGER = LoggerFactory.getLogger(AsyncCompletionHandlerBase.class);
/**
* {@inheritDoc}
*/
@Override
public Response onCompleted(Response response) throws Exception {
return response;
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public void onThrowable(Throwable t) {
log.debug(t.getMessage(), t);
LOGGER.debug(t.getMessage(), t);
}
}
......@@ -12,6 +12,8 @@
*/
package com.ning.http.client;
import java.net.InetAddress;
/**
* This interface hosts new low level callback methods on {@link AsyncHandler}.
* For now, those methods are in a dedicated interface in order not to break the existing API,
......@@ -19,7 +21,6 @@ package com.ning.http.client;
*
* More additional hooks might come, such as:
* <ul>
* <li>onConnected()</li>
* <li>onConnectionClosed()</li>
* <li>onBytesSent(long numberOfBytes)</li>
* <li>onBytesReceived(long numberOfBytes)</li>
......@@ -28,15 +29,48 @@ package com.ning.http.client;
public interface AsyncHandlerExtensions {
/**
* Notify the callback when a request is being written on the wire.
* Notify the callback when trying to open a new connection.
*/
void onOpenConnection();
/**
* Notify the callback when a new connection was successfully opened.
*/
void onConnectionOpen();
/**
* Notify the callback when trying to fetch a connection from the pool.
*/
void onPoolConnection();
/**
* Notify the callback when a new connection was successfully fetched from the pool.
*/
void onConnectionPooled();
/**
* Notify the callback when a request is about to be written on the wire.
* If the original request causes multiple requests to be sent, for example, because of authorization or retry,
* it will be notified multiple times.
* Currently only supported by the Netty provider.
*
* @param request the real request object (underlying provider model)
*/
void onRequestSent();
void onSendRequest(Object request);
/**
* Notify the callback every time a request is being retried.
*/
void onRetry();
/**
* Notify the callback after DNS resolution has completed.
*
* @param address the resolved address
*/
void onDnsResolved(InetAddress address);
/**
* Notify the callback when the SSL handshake performed to establish an HTTPS connection has been completed.
*/
void onSslHandshakeCompleted();
}
......@@ -17,10 +17,10 @@
package com.ning.http.client;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
......@@ -30,11 +30,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ning.http.client.Request.EntityWriter;
import com.ning.http.client.cookie.Cookie;
import com.ning.http.client.filter.FilterContext;
import com.ning.http.client.filter.FilterException;
import com.ning.http.client.filter.RequestFilter;
import com.ning.http.client.multipart.Part;
import com.ning.http.client.providers.jdk.JDKAsyncHttpProvider;
import com.ning.http.client.resumable.ResumableAsyncHandler;
......@@ -124,7 +124,7 @@ import com.ning.http.client.resumable.ResumableAsyncHandler;
* <p/>
* String bodyResponse = f.get();
* </pre></blockquote
* From any {@link HttpContent} sub classes, you can asynchronously process the response status,headers and body and decide when to
* From any content classes, you can asynchronously process the response status,headers and body and decide when to
* stop the processing the response by throwing a new {link ResponseComplete} at any moment.
* <p/>
* This class can also be used without the need of {@link AsyncHandler}</p>
......@@ -136,12 +136,12 @@ import com.ning.http.client.resumable.ResumableAsyncHandler;
* <p/>
* Finally, you can configure the AsyncHttpClient using an {@link AsyncHttpClientConfig} instance</p>
* <blockquote><pre>
* AsyncHttpClient c = new AsyncHttpClient(new AsyncHttpClientConfig.Builder().setRequestTimeoutInMs(...).build());
* AsyncHttpClient c = new AsyncHttpClient(new AsyncHttpClientConfig.Builder().setRequestTimeout(...).build());
* Future<Response> f = c.prepareGet(TARGET_URL).execute();
* Response r = f.get();
* </pre></blockquote>
* <p/>
* An instance of this class will cache every HTTP 1.1 connections and close them when the {@link AsyncHttpClientConfig#getIdleConnectionTimeoutInMs()}
* An instance of this class will cache every HTTP 1.1 connections and close them when the {@link AsyncHttpClientConfig#getReadTimeout()}
* expires. This object can hold many persistent connections to different host.
*/
public class AsyncHttpClient implements Closeable {
......@@ -213,19 +213,19 @@ public class AsyncHttpClient implements Closeable {
public class BoundRequestBuilder extends RequestBuilderBase<BoundRequestBuilder> {
private BoundRequestBuilder(String reqType, boolean useRawUrl) {
super(BoundRequestBuilder.class, reqType, useRawUrl);
private BoundRequestBuilder(String method, boolean isDisableUrlEncoding) {
super(BoundRequestBuilder.class, method, isDisableUrlEncoding);
}
private BoundRequestBuilder(Request prototype) {
super(BoundRequestBuilder.class, prototype);
}
public <T> ListenableFuture<T> execute(AsyncHandler<T> handler) throws IOException {
public <T> ListenableFuture<T> execute(AsyncHandler<T> handler) {
return AsyncHttpClient.this.executeRequest(build(), handler);
}
public ListenableFuture<Response> execute() throws IOException {
public ListenableFuture<Response> execute() {
return AsyncHttpClient.this.executeRequest(build(), new AsyncCompletionHandlerBase());
}
......@@ -249,13 +249,13 @@ public class AsyncHttpClient implements Closeable {
}
@Override
public BoundRequestBuilder addParameter(String key, String value) {
return super.addParameter(key, value);
public BoundRequestBuilder addFormParam(String key, String value) {
return super.addFormParam(key, value);
}
@Override
public BoundRequestBuilder addQueryParameter(String name, String value) {
return super.addQueryParameter(name, value);
public BoundRequestBuilder addQueryParam(String name, String value) {
return super.addQueryParam(name, value);
}
@Override
......@@ -268,16 +268,6 @@ public class AsyncHttpClient implements Closeable {
return super.setBody(data);
}
@Override
public BoundRequestBuilder setBody(EntityWriter dataWriter, long length) {
return super.setBody(dataWriter, length);
}
@Override
public BoundRequestBuilder setBody(EntityWriter dataWriter) {
return super.setBody(dataWriter);
}
@Override
public BoundRequestBuilder setBody(InputStream stream) {
return super.setBody(stream);
......@@ -304,13 +294,13 @@ public class AsyncHttpClient implements Closeable {
}
@Override
public BoundRequestBuilder setParameters(Map<String, Collection<String>> parameters) {
return super.setParameters(parameters);
public BoundRequestBuilder setFormParams(Map<String, List<String>> params) {
return super.setFormParams(params);
}
@Override
public BoundRequestBuilder setParameters(FluentStringsMap parameters) {
return super.setParameters(parameters);
public BoundRequestBuilder setFormParams(List<Param> params) {
return super.setFormParams(params);
}
@Override
......@@ -472,6 +462,26 @@ public class AsyncHttpClient implements Closeable {
return requestBuilder("DELETE", url);
}
/**
* Prepare an HTTP client PATCH request.
*
* @param url A well formed URL.
* @return {@link RequestBuilder}
*/
public BoundRequestBuilder preparePatch(String url) {
return requestBuilder("PATCH", url);
}
/**
* Prepare an HTTP client TRACE request.
*
* @param url A well formed URL.
* @return {@link RequestBuilder}
*/
public BoundRequestBuilder prepareTrace(String url) {
return requestBuilder("TRACE", url);
}
/**
* Construct a {@link RequestBuilder} using a {@link Request}
*
......@@ -489,27 +499,33 @@ public class AsyncHttpClient implements Closeable {
* @param handler an instance of {@link AsyncHandler}
* @param <T> Type of the value that will be returned by the associated {@link java.util.concurrent.Future}
* @return a {@link Future} of type T
* @throws IOException
*/
public <T> ListenableFuture<T> executeRequest(Request request, AsyncHandler<T> handler) throws IOException {
public <T> ListenableFuture<T> executeRequest(Request request, AsyncHandler<T> handler) {
if (config.getRequestFilters().isEmpty()) {
return httpProvider.execute(request, handler);
FilterContext fc = new FilterContext.FilterContextBuilder().asyncHandler(handler).request(request).build();
} else {
FilterContext<T> fc = new FilterContext.FilterContextBuilder<T>().asyncHandler(handler).request(request).build();
try {
fc = preProcessRequest(fc);
} catch (Exception e) {
handler.onThrowable(e);
return new ListenableFuture.CompletedFailure<T>("preProcessRequest failed", e);
}
return httpProvider.execute(fc.getRequest(), fc.getAsyncHandler());
}
}
/**
* Execute an HTTP request.
*
* @param request {@link Request}
* @return a {@link Future} of type Response
* @throws IOException
*/
public ListenableFuture<Response> executeRequest(Request request) throws IOException {
FilterContext fc = new FilterContext.FilterContextBuilder().asyncHandler(new AsyncCompletionHandlerBase()).request(request).build();
fc = preProcessRequest(fc);
return httpProvider.execute(fc.getRequest(), fc.getAsyncHandler());
public ListenableFuture<Response> executeRequest(Request request) {
return executeRequest(request, new AsyncCompletionHandlerBase());
}
/**
......@@ -518,18 +534,12 @@ public class AsyncHttpClient implements Closeable {
* @param fc {@link FilterContext}
* @return {@link FilterContext}
*/
private FilterContext preProcessRequest(FilterContext fc) throws IOException {
private <T> FilterContext<T> preProcessRequest(FilterContext<T> fc) throws FilterException {
for (RequestFilter asyncFilter : config.getRequestFilters()) {
try {
fc = asyncFilter.filter(fc);
if (fc == null) {
throw new NullPointerException("FilterContext is null");
}
} catch (FilterException e) {
IOException ex = new IOException();
ex.initCause(e);
throw ex;
}
}
Request request = fc.getRequest();
......@@ -542,7 +552,7 @@ public class AsyncHttpClient implements Closeable {
builder.setHeader("Range", "bytes=" + request.getRangeOffset() + "-");
request = builder.build();
}
fc = new FilterContext.FilterContextBuilder(fc).request(request).build();
fc = new FilterContext.FilterContextBuilder<T>(fc).request(request).build();
return fc;
}
......@@ -582,8 +592,8 @@ public class AsyncHttpClient implements Closeable {
}
}
protected BoundRequestBuilder requestBuilder(String reqType, String url) {
return new BoundRequestBuilder(reqType, config.isUseRawUrl()).setUrl(url).setSignatureCalculator(signatureCalculator);
protected BoundRequestBuilder requestBuilder(String method, String url) {
return new BoundRequestBuilder(method, config.isDisableUrlEncodingForBoundedRequests()).setUrl(url).setSignatureCalculator(signatureCalculator);
}
protected BoundRequestBuilder requestBuilder(Request prototype) {
......
......@@ -39,34 +39,34 @@ public class AsyncHttpClientConfigBean extends AsyncHttpClientConfig {
}
void configureFilters() {
requestFilters = new LinkedList<RequestFilter>();
responseFilters = new LinkedList<ResponseFilter>();
ioExceptionFilters = new LinkedList<IOExceptionFilter>();
requestFilters = new LinkedList<>();
responseFilters = new LinkedList<>();
ioExceptionFilters = new LinkedList<>();
}
void configureDefaults() {
maxTotalConnections = defaultMaxTotalConnections();
maxConnectionPerHost = defaultMaxConnectionPerHost();
connectionTimeOutInMs = defaultConnectionTimeOutInMs();
webSocketIdleTimeoutInMs = defaultWebSocketIdleTimeoutInMs();
idleConnectionInPoolTimeoutInMs = defaultIdleConnectionInPoolTimeoutInMs();
idleConnectionTimeoutInMs = defaultIdleConnectionTimeoutInMs();
requestTimeoutInMs = defaultRequestTimeoutInMs();
maxConnectionLifeTimeInMs = defaultMaxConnectionLifeTimeInMs();
redirectEnabled = defaultRedirectEnabled();
maxConnections = defaultMaxConnections();
maxConnectionsPerHost = defaultMaxConnectionsPerHost();
connectTimeout = defaultConnectTimeout();
webSocketTimeout = defaultWebSocketTimeout();
pooledConnectionIdleTimeout = defaultPooledConnectionIdleTimeout();
readTimeout = defaultReadTimeout();
requestTimeout = defaultRequestTimeout();
connectionTTL = defaultConnectionTTL();
followRedirect = defaultFollowRedirect();
maxRedirects = defaultMaxRedirects();
compressionEnabled = defaultCompressionEnabled();
compressionEnforced = defaultCompressionEnforced();
userAgent = defaultUserAgent();
allowPoolingConnection = defaultAllowPoolingConnection();
useRelativeURIsWithSSLProxies = defaultUseRelativeURIsWithSSLProxies();
requestCompressionLevel = defaultRequestCompressionLevel();
allowPoolingConnections = defaultAllowPoolingConnections();
useRelativeURIsWithConnectProxies = defaultUseRelativeURIsWithConnectProxies();
maxRequestRetry = defaultMaxRequestRetry();
ioThreadMultiplier = defaultIoThreadMultiplier();
allowSslConnectionPool = defaultAllowSslConnectionPool();
useRawUrl = defaultUseRawUrl();
removeQueryParamOnRedirect = defaultRemoveQueryParamOnRedirect();
allowPoolingSslConnections = defaultAllowPoolingSslConnections();
disableUrlEncodingForBoundRequests = defaultDisableUrlEncodingForBoundRequests();
strict302Handling = defaultStrict302Handling();
hostnameVerifier = defaultHostnameVerifier();
acceptAnyCertificate = defaultAcceptAnyCertificate();
sslSessionCacheSize = defaultSslSessionCacheSize();
sslSessionTimeout = defaultSslSessionTimeout();
if (defaultUseProxySelector()) {
proxyServerSelector = ProxyUtils.getJdkDefaultProxyServerSelector();
......@@ -86,22 +86,22 @@ public class AsyncHttpClientConfigBean extends AsyncHttpClientConfig {
}
public AsyncHttpClientConfigBean setMaxTotalConnections(int maxTotalConnections) {
this.maxTotalConnections = maxTotalConnections;
this.maxConnections = maxTotalConnections;
return this;
}
public AsyncHttpClientConfigBean setMaxConnectionPerHost(int maxConnectionPerHost) {
this.maxConnectionPerHost = maxConnectionPerHost;
this.maxConnectionsPerHost = maxConnectionPerHost;
return this;
}
public AsyncHttpClientConfigBean setConnectionTimeOutInMs(int connectionTimeOutInMs) {
this.connectionTimeOutInMs = connectionTimeOutInMs;
public AsyncHttpClientConfigBean setConnectionTimeOut(int connectionTimeOut) {
this.connectTimeout = connectionTimeOut;
return this;
}
public AsyncHttpClientConfigBean setIdleConnectionInPoolTimeoutInMs(int idleConnectionInPoolTimeoutInMs) {
this.idleConnectionInPoolTimeoutInMs = idleConnectionInPoolTimeoutInMs;
public AsyncHttpClientConfigBean setIdleConnectionInPoolTimeout(int idleConnectionInPoolTimeout) {
this.pooledConnectionIdleTimeout = idleConnectionInPoolTimeout;
return this;
}
......@@ -110,23 +110,23 @@ public class AsyncHttpClientConfigBean extends AsyncHttpClientConfig {
return this;
}
public AsyncHttpClientConfigBean setIdleConnectionTimeoutInMs(int idleConnectionTimeoutInMs) {
this.idleConnectionTimeoutInMs = idleConnectionTimeoutInMs;
public AsyncHttpClientConfigBean setReadTimeout(int readTimeout) {
this.readTimeout = readTimeout;
return this;
}
public AsyncHttpClientConfigBean setRequestTimeoutInMs(int requestTimeoutInMs) {
this.requestTimeoutInMs = requestTimeoutInMs;
public AsyncHttpClientConfigBean setRequestTimeout(int requestTimeout) {
this.requestTimeout = requestTimeout;
return this;
}
public AsyncHttpClientConfigBean setMaxConnectionLifeTimeInMs(int maxConnectionLifeTimeInMs) {
this.maxConnectionLifeTimeInMs = maxConnectionLifeTimeInMs;
public AsyncHttpClientConfigBean setMaxConnectionLifeTime(int maxConnectionLifeTime) {
this.connectionTTL = maxConnectionLifeTime;
return this;
}
public AsyncHttpClientConfigBean setRedirectEnabled(boolean redirectEnabled) {
this.redirectEnabled = redirectEnabled;
public AsyncHttpClientConfigBean setFollowRedirect(boolean followRedirect) {
this.followRedirect = followRedirect;
return this;
}
......@@ -135,8 +135,8 @@ public class AsyncHttpClientConfigBean extends AsyncHttpClientConfig {
return this;
}
public AsyncHttpClientConfigBean setCompressionEnabled(boolean compressionEnabled) {
this.compressionEnabled = compressionEnabled;
public AsyncHttpClientConfigBean setCompressionEnforced(boolean compressionEnforced) {
this.compressionEnforced = compressionEnforced;
return this;
}
......@@ -146,7 +146,7 @@ public class AsyncHttpClientConfigBean extends AsyncHttpClientConfig {
}
public AsyncHttpClientConfigBean setAllowPoolingConnection(boolean allowPoolingConnection) {
this.allowPoolingConnection = allowPoolingConnection;
this.allowPoolingConnections = allowPoolingConnection;
return this;
}
......@@ -173,21 +173,11 @@ public class AsyncHttpClientConfigBean extends AsyncHttpClientConfig {
return this;
}
public AsyncHttpClientConfigBean setSslEngineFactory(SSLEngineFactory sslEngineFactory) {
this.sslEngineFactory = sslEngineFactory;
return this;
}
public AsyncHttpClientConfigBean setProviderConfig(AsyncHttpProviderConfig<?, ?> providerConfig) {
this.providerConfig = providerConfig;
return this;
}
public AsyncHttpClientConfigBean setConnectionsPool(ConnectionsPool<?, ?> connectionsPool) {
this.connectionsPool = connectionsPool;
return this;
}
public AsyncHttpClientConfigBean setRealm(Realm realm) {
this.realm = realm;
return this;
......@@ -208,28 +198,18 @@ public class AsyncHttpClientConfigBean extends AsyncHttpClientConfig {
return this;
}
public AsyncHttpClientConfigBean setRequestCompressionLevel(int requestCompressionLevel) {
this.requestCompressionLevel = requestCompressionLevel;
return this;
}
public AsyncHttpClientConfigBean setMaxRequestRetry(int maxRequestRetry) {
this.maxRequestRetry = maxRequestRetry;
return this;
}
public AsyncHttpClientConfigBean setAllowSslConnectionPool(boolean allowSslConnectionPool) {
this.allowSslConnectionPool = allowSslConnectionPool;
this.allowPoolingSslConnections = allowSslConnectionPool;
return this;
}
public AsyncHttpClientConfigBean setUseRawUrl(boolean useRawUrl) {
this.useRawUrl = useRawUrl;
return this;
}
public AsyncHttpClientConfigBean setRemoveQueryParamOnRedirect(boolean removeQueryParamOnRedirect) {
this.removeQueryParamOnRedirect = removeQueryParamOnRedirect;
public AsyncHttpClientConfigBean setDisableUrlEncodingForBoundRequests(boolean disableUrlEncodingForBoundRequests) {
this.disableUrlEncodingForBoundRequests = disableUrlEncodingForBoundRequests;
return this;
}
......@@ -242,4 +222,19 @@ public class AsyncHttpClientConfigBean extends AsyncHttpClientConfig {
this.ioThreadMultiplier = ioThreadMultiplier;
return this;
}
public AsyncHttpClientConfigBean setAcceptAnyCertificate(boolean acceptAnyCertificate) {
this.acceptAnyCertificate = acceptAnyCertificate;
return this;
}
public AsyncHttpClientConfigBean setSslSessionCacheSize(Integer sslSessionCacheSize) {
this.sslSessionCacheSize = sslSessionCacheSize;
return this;
}
public AsyncHttpClientConfigBean setSslSessionTimeout(Integer sslSessionTimeout) {
this.sslSessionTimeout = sslSessionTimeout;
return this;
}
}
......@@ -12,10 +12,7 @@
*/
package com.ning.http.client;
import com.ning.http.util.AllowAllHostnameVerifier;
import static com.ning.http.util.MiscUtil.getBoolean;
import javax.net.ssl.HostnameVerifier;
import static com.ning.http.util.MiscUtils.getBoolean;
public final class AsyncHttpClientConfigDefaults {
......@@ -24,52 +21,52 @@ public final class AsyncHttpClientConfigDefaults {
public static final String ASYNC_CLIENT = AsyncHttpClientConfig.class.getName() + ".";
public static int defaultMaxTotalConnections() {
return Integer.getInteger(ASYNC_CLIENT + "maxTotalConnections", -1);
public static int defaultMaxConnections() {
return Integer.getInteger(ASYNC_CLIENT + "maxConnections", -1);
}
public static int defaultMaxConnectionPerHost() {
public static int defaultMaxConnectionsPerHost() {
return Integer.getInteger(ASYNC_CLIENT + "maxConnectionsPerHost", -1);
}
public static int defaultConnectionTimeOutInMs() {
return Integer.getInteger(ASYNC_CLIENT + "connectionTimeoutInMs", 60 * 1000);
public static int defaultConnectTimeout() {
return Integer.getInteger(ASYNC_CLIENT + "connectTimeout", 5 * 1000);
}
public static int defaultIdleConnectionInPoolTimeoutInMs() {
return Integer.getInteger(ASYNC_CLIENT + "idleConnectionInPoolTimeoutInMs", 60 * 1000);
public static int defaultPooledConnectionIdleTimeout() {
return Integer.getInteger(ASYNC_CLIENT + "pooledConnectionIdleTimeout", 60 * 1000);
}
public static int defaultIdleConnectionTimeoutInMs() {
return Integer.getInteger(ASYNC_CLIENT + "idleConnectionTimeoutInMs", 60 * 1000);
public static int defaultReadTimeout() {
return Integer.getInteger(ASYNC_CLIENT + "readTimeout", 60 * 1000);
}
public static int defaultRequestTimeoutInMs() {
return Integer.getInteger(ASYNC_CLIENT + "requestTimeoutInMs", 60 * 1000);
public static int defaultRequestTimeout() {
return Integer.getInteger(ASYNC_CLIENT + "requestTimeout", 60 * 1000);
}
public static int defaultWebSocketIdleTimeoutInMs() {
return Integer.getInteger(ASYNC_CLIENT + "webSocketTimoutInMS", 15 * 60 * 1000);
public static int defaultWebSocketTimeout() {
return Integer.getInteger(ASYNC_CLIENT + "webSocketTimeout", 15 * 60 * 1000);
}
public static int defaultMaxConnectionLifeTimeInMs() {
return Integer.getInteger(ASYNC_CLIENT + "maxConnectionLifeTimeInMs", -1);
public static int defaultConnectionTTL() {
return Integer.getInteger(ASYNC_CLIENT + "connectionTTL", -1);
}
public static boolean defaultRedirectEnabled() {
return Boolean.getBoolean(ASYNC_CLIENT + "redirectsEnabled");
public static boolean defaultFollowRedirect() {
return Boolean.getBoolean(ASYNC_CLIENT + "followRedirect");
}
public static int defaultMaxRedirects() {
return Integer.getInteger(ASYNC_CLIENT + "maxRedirects", 5);
}
public static boolean defaultCompressionEnabled() {
return Boolean.getBoolean(ASYNC_CLIENT + "compressionEnabled");
public static boolean defaultCompressionEnforced() {
return getBoolean(ASYNC_CLIENT + "compressionEnforced", false);
}
public static String defaultUserAgent() {
return System.getProperty(ASYNC_CLIENT + "userAgent", "NING/1.0");
return System.getProperty(ASYNC_CLIENT + "userAgent", "AHC/1.0");
}
public static int defaultIoThreadMultiplier() {
......@@ -88,36 +85,39 @@ public final class AsyncHttpClientConfigDefaults {
return Boolean.getBoolean(ASYNC_CLIENT + "strict302Handling");
}
public static boolean defaultAllowPoolingConnection() {
return getBoolean(ASYNC_CLIENT + "allowPoolingConnection", true);
}
public static boolean defaultUseRelativeURIsWithSSLProxies() {
return getBoolean(ASYNC_CLIENT + "useRelativeURIsWithSSLProxies", true);
public static boolean defaultAllowPoolingConnections() {
return getBoolean(ASYNC_CLIENT + "allowPoolingConnections", true);
}
// unused/broken, left there for compatibility, fixed in Netty 4
public static int defaultRequestCompressionLevel() {
return Integer.getInteger(ASYNC_CLIENT + "requestCompressionLevel", -1);
public static boolean defaultUseRelativeURIsWithConnectProxies() {
return getBoolean(ASYNC_CLIENT + "useRelativeURIsWithConnectProxies", true);
}
public static int defaultMaxRequestRetry() {
return Integer.getInteger(ASYNC_CLIENT + "maxRequestRetry", 5);
}
public static boolean defaultAllowSslConnectionPool() {
return getBoolean(ASYNC_CLIENT + "allowSslConnectionPool", true);
public static boolean defaultAllowPoolingSslConnections() {
return getBoolean(ASYNC_CLIENT + "allowPoolingSslConnections", true);
}
public static boolean defaultDisableUrlEncodingForBoundRequests() {
return Boolean.getBoolean(ASYNC_CLIENT + "disableUrlEncodingForBoundRequests");
}
public static boolean defaultAcceptAnyCertificate() {
return getBoolean(ASYNC_CLIENT + "acceptAnyCertificate", false);
}
public static boolean defaultUseRawUrl() {
return Boolean.getBoolean(ASYNC_CLIENT + "useRawUrl");
public static Integer defaultSslSessionCacheSize() {
return Integer.getInteger(ASYNC_CLIENT + "sslSessionCacheSize");
}
public static boolean defaultRemoveQueryParamOnRedirect() {
return getBoolean(ASYNC_CLIENT + "removeQueryParamOnRedirect", true);
public static Integer defaultSslSessionTimeout() {
return Integer.getInteger(ASYNC_CLIENT + "sslSessionTimeout");
}
public static HostnameVerifier defaultHostnameVerifier() {
return new AllowAllHostnameVerifier();
public static String[] defaultEnabledProtocols() {
return new String[] { "TLSv1.2", "TLSv1.1", "TLSv1" };
}
}
......@@ -15,9 +15,6 @@
*/
package com.ning.http.client;
import java.io.IOException;
import java.util.List;
/**
* Interface to be used when implementing custom asynchronous I/O HTTP client.
* By default, the {@link com.ning.http.client.providers.netty.NettyAsyncHttpProvider} is used.
......@@ -29,24 +26,11 @@ public interface AsyncHttpProvider {
*
* @param handler an instance of {@link AsyncHandler}
* @return a {@link ListenableFuture} of Type T.
* @throws IOException
*/
<T> ListenableFuture<T> execute(Request request, AsyncHandler<T> handler) throws IOException;
<T> ListenableFuture<T> execute(Request request, AsyncHandler<T> handler);
/**
* Close the current underlying TCP/HTTP connection.
*/
void close();
/**
* Prepare a {@link Response}
*
* @param status {@link HttpResponseStatus}
* @param headers {@link HttpResponseHeaders}
* @param bodyParts list of {@link HttpResponseBodyPart}
* @return a {@link Response}
*/
Response prepareResponse(HttpResponseStatus status,
HttpResponseHeaders headers,
List<HttpResponseBodyPart> bodyParts);
}
......@@ -29,7 +29,7 @@ public interface AsyncHttpProviderConfig<U, V> {
* @param value the value of the property
* @return this instance of AsyncHttpProviderConfig
*/
AsyncHttpProviderConfig addProperty(U name, V value);
AsyncHttpProviderConfig<U, V> addProperty(U name, V value);
/**
* Return the value associated with the property's name
......
......@@ -13,13 +13,14 @@
package com.ning.http.client;
import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* A request body.
*/
public interface Body {
public interface Body extends Closeable {
/**
* Gets the length of the body.
......@@ -36,11 +37,4 @@ public interface Body {
* @throws IOException If the chunk could not be read.
*/
long read(ByteBuffer buffer) throws IOException;
/**
* Releases any resources associated with this body.
*
* @throws IOException
*/
void close() throws IOException;
}
......@@ -13,13 +13,14 @@
package com.ning.http.client;
import java.io.Closeable;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* A simple API to be used with the {@link SimpleAsyncHttpClient} class in order to process response's bytes.
*/
public interface BodyConsumer {
public interface BodyConsumer extends Closeable {
/**
* Consume the received bytes.
......@@ -28,11 +29,4 @@ public interface BodyConsumer {
* @throws IOException
*/
void consume(ByteBuffer byteBuffer) throws IOException;
/**
* Invoked when all the response bytes has been processed.
*
* @throws IOException
*/
void close() throws IOException;
}
/*
* Copyright 2010 Ning, Inc.
*
* Ning licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
package com.ning.http.client;
public class ByteArrayPart implements Part {
private final String name;
private final String fileName;
private final byte[] data;
private final String mimeType;
private final String charSet;
public ByteArrayPart(String name, String fileName, byte[] data, String mimeType, String charSet) {
this.name = name;
this.fileName = fileName;
this.data = data;
this.mimeType = mimeType;
this.charSet = charSet;
}
/**
* {@inheritDoc}
*/
/* @Override */
public String getName() {
return name;
}
public String getFileName() {
return fileName;
}
public byte[] getData() {
return data;
}
public String getMimeType() {
return mimeType;
}
public String getCharSet() {
return charSet;
}
}
/*
* Copyright (c) 2014 AsyncHttpClient Project. All rights reserved.
*
* This program is licensed to you under the Apache License Version 2.0,
* and you may not use this file except in compliance with the Apache License Version 2.0.
* You may obtain a copy of the Apache License Version 2.0 at http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the Apache License Version 2.0 is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the Apache License Version 2.0 for the specific language governing permissions and limitations there under.
*/
package com.ning.http.client;
import com.ning.http.client.uri.Uri;
import com.ning.http.util.AsyncHttpProviderUtils;
public interface ConnectionPoolPartitioning {
public class ProxyPartitionKey {
private final String proxyUrl;
private final String targetHostBaseUrl;
public ProxyPartitionKey(String proxyUrl, String targetHostBaseUrl) {
this.proxyUrl = proxyUrl;
this.targetHostBaseUrl = targetHostBaseUrl;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((proxyUrl == null) ? 0 : proxyUrl.hashCode());
result = prime * result + ((targetHostBaseUrl == null) ? 0 : targetHostBaseUrl.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof ProxyPartitionKey))
return false;
ProxyPartitionKey other = (ProxyPartitionKey) obj;
if (proxyUrl == null) {
if (other.proxyUrl != null)
return false;
} else if (!proxyUrl.equals(other.proxyUrl))
return false;
if (targetHostBaseUrl == null) {
if (other.targetHostBaseUrl != null)
return false;
} else if (!targetHostBaseUrl.equals(other.targetHostBaseUrl))
return false;
return true;
}
@Override
public String toString() {
return new StringBuilder()//
.append("ProxyPartitionKey(proxyUrl=").append(proxyUrl)//
.append(", targetHostBaseUrl=").append(targetHostBaseUrl)//
.toString();
}
}
Object getPartitionKey(Uri uri, ProxyServer proxyServer);
public enum PerHostConnectionPoolPartitioning implements ConnectionPoolPartitioning {
INSTANCE;
public Object getPartitionKey(Uri uri, ProxyServer proxyServer) {
String targetHostBaseUrl = AsyncHttpProviderUtils.getBaseUrl(uri);
return proxyServer != null ? new ProxyPartitionKey(proxyServer.getUrl(), targetHostBaseUrl) : targetHostBaseUrl;
}
}
}
/*
* Copyright 2010 Ning, Inc.
*
* Ning licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.ning.http.client;
import java.net.URI;
import com.ning.http.util.AsyncHttpProviderUtils;
public enum DefaultConnectionPoolStrategy implements ConnectionPoolKeyStrategy {
INSTANCE;
public String getKey(URI uri) {
return AsyncHttpProviderUtils.getBaseUrl(uri);
}
}
\ No newline at end of file
/*
* Copyright 2010 Ning, Inc.
*
* Ning licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
*/
package com.ning.http.client;
import java.io.File;
/**
* A file multipart part.
*/
public class FilePart implements Part {
private final String name;
private final File file;
private final String mimeType;
private final String charSet;
public FilePart(String name, File file, String mimeType, String charSet) {
this.name = name;
this.file = file;
this.mimeType = mimeType;
this.charSet = charSet;
}
/**
* {@inheritDoc}
*/
public String getName() {
return name;
}
public File getFile() {
return file;
}
public String getMimeType() {
return mimeType;
}
public String getCharSet() {
return charSet;
}
}
\ No newline at end of file
......@@ -16,7 +16,7 @@
*/
package com.ning.http.client;
import static com.ning.http.util.MiscUtil.isNonEmpty;
import static com.ning.http.util.MiscUtils.isNonEmpty;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -38,8 +38,8 @@ import java.util.Set;
* original case in the appropriate methods (e.g. {@link FluentCaseInsensitiveStringsMap#keySet()}).
*/
public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>>, Iterable<Map.Entry<String, List<String>>> {
private final Map<String, List<String>> values = new LinkedHashMap<String, List<String>>();
private final Map<String, String> keyLookup = new LinkedHashMap<String, String>();
private final Map<String, List<String>> values = new LinkedHashMap<>();
private final Map<String, String> keyLookup = new LinkedHashMap<>();
public FluentCaseInsensitiveStringsMap() {
}
......@@ -68,7 +68,7 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
List<String> curValues = null;
if (realKey == null) {
keyLookup.put(lcKey, key);
curValues = new ArrayList<String>();
curValues = new ArrayList<>();
values.put(key, curValues);
} else {
curValues = values.get(realKey);
......@@ -104,7 +104,7 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
}
if (result == null) {
// lazy initialization
result = new ArrayList<String>();
result = new ArrayList<>();
}
result.add(value);
}
......@@ -137,7 +137,7 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
}
if (curValues == null) {
curValues = new ArrayList<String>();
curValues = new ArrayList<>();
this.values.put(realKey, curValues);
}
curValues.addAll(nonNullValues);
......@@ -183,8 +183,8 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
* @param values The new values
* @return This object
*/
public FluentCaseInsensitiveStringsMap replace(final String key, final String... values) {
return replace(key, Arrays.asList(values));
public FluentCaseInsensitiveStringsMap replaceWith(final String key, final String... values) {
return replaceWith(key, Arrays.asList(values));
}
/**
......@@ -194,7 +194,7 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
* @param values The new values
* @return This object
*/
public FluentCaseInsensitiveStringsMap replace(final String key, final Collection<String> values) {
public FluentCaseInsensitiveStringsMap replaceWith(final String key, final Collection<String> values) {
if (key != null) {
List<String> nonNullValues = fetchValues(values);
String lcKkey = key.toLowerCase(Locale.ENGLISH);
......@@ -226,7 +226,7 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
public FluentCaseInsensitiveStringsMap replaceAll(FluentCaseInsensitiveStringsMap src) {
if (src != null) {
for (Map.Entry<String, List<String>> header : src) {
replace(header.getKey(), header.getValue());
replaceWith(header.getKey(), header.getValue());
}
}
return this;
......@@ -242,16 +242,13 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
public FluentCaseInsensitiveStringsMap replaceAll(Map<? extends String, ? extends Collection<String>> src) {
if (src != null) {
for (Map.Entry<? extends String, ? extends Collection<String>> header : src.entrySet()) {
replace(header.getKey(), header.getValue());
replaceWith(header.getKey(), header.getValue());
}
}
return this;
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public List<String> put(String key, List<String> value) {
if (key == null) {
throw new NullPointerException("Null keys are not allowed");
......@@ -259,14 +256,11 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
List<String> oldValue = get(key);
replace(key, value);
replaceWith(key, value);
return oldValue;
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public void putAll(Map<? extends String, ? extends List<String>> values) {
replaceAll(values);
}
......@@ -319,10 +313,7 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
return this;
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public List<String> remove(Object key) {
if (key == null) {
return null;
......@@ -334,67 +325,43 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
}
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public void clear() {
keyLookup.clear();
values.clear();
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public Iterator<Map.Entry<String, List<String>>> iterator() {
return Collections.unmodifiableSet(values.entrySet()).iterator();
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public Set<String> keySet() {
return new LinkedHashSet<String>(keyLookup.values());
return new LinkedHashSet<>(keyLookup.values());
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public Set<Entry<String, List<String>>> entrySet() {
return values.entrySet();
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public int size() {
return values.size();
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public boolean isEmpty() {
return values.isEmpty();
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public boolean containsKey(Object key) {
return key == null ? false : keyLookup.containsKey(key.toString().toLowerCase(Locale.ENGLISH));
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public boolean containsValue(Object value) {
return values.containsValue(value);
}
......@@ -409,10 +376,8 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
public String getFirstValue(String key) {
List<String> values = get(key);
if (values == null) {
if (values.isEmpty()) {
return null;
} else if (values.isEmpty()) {
return "";
} else {
return values.get(0);
}
......@@ -427,7 +392,7 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
public String getJoinedValue(String key, String delimiter) {
List<String> values = get(key);
if (values == null) {
if (values.isEmpty()) {
return null;
} else if (values.size() == 1) {
return values.get(0);
......@@ -444,29 +409,18 @@ public class FluentCaseInsensitiveStringsMap implements Map<String, List<String>
}
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public List<String> get(Object key) {
if (key == null) {
return null;
}
if (key == null)
return Collections.emptyList();
String lcKey = key.toString().toLowerCase(Locale.ENGLISH);
String realKey = keyLookup.get(lcKey);
if (realKey == null) {
return null;
} else {
return values.get(realKey);
}
return realKey != null ? values.get(realKey) : Collections.<String> emptyList();
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public Collection<List<String>> values() {
return values.values();
}
......
......@@ -16,7 +16,7 @@
*/
package com.ning.http.client;
import static com.ning.http.util.MiscUtil.isNonEmpty;
import static com.ning.http.util.MiscUtils.isNonEmpty;
import java.util.ArrayList;
import java.util.Arrays;
......@@ -33,7 +33,7 @@ import java.util.Set;
* return this instance.
*/
public class FluentStringsMap implements Map<String, List<String>>, Iterable<Map.Entry<String, List<String>>> {
private final Map<String, List<String>> values = new LinkedHashMap<String, List<String>>();
private final Map<String, List<String>> values = new LinkedHashMap<>();
public FluentStringsMap() {
}
......@@ -59,7 +59,7 @@ public class FluentStringsMap implements Map<String, List<String>>, Iterable<Map
List<String> curValues = values.get(key);
if (curValues == null) {
curValues = new ArrayList<String>(1);
curValues = new ArrayList<>(1);
values.put(key, curValues);
}
curValues.add(value);
......@@ -93,7 +93,7 @@ public class FluentStringsMap implements Map<String, List<String>>, Iterable<Map
List<String> curValues = this.values.get(key);
if (curValues == null) {
this.values.put(key, new ArrayList<String>(values));
this.values.put(key, new ArrayList<>(values));
} else {
curValues.addAll(values);
}
......@@ -138,8 +138,8 @@ public class FluentStringsMap implements Map<String, List<String>>, Iterable<Map
* @param values The new values
* @return This object
*/
public FluentStringsMap replace(final String key, final String... values) {
return replace(key, Arrays.asList(values));
public FluentStringsMap replaceWith(final String key, final String... values) {
return replaceWith(key, Arrays.asList(values));
}
/**
......@@ -149,12 +149,12 @@ public class FluentStringsMap implements Map<String, List<String>>, Iterable<Map
* @param values The new values
* @return This object
*/
public FluentStringsMap replace(final String key, final Collection<String> values) {
public FluentStringsMap replaceWith(final String key, final Collection<String> values) {
if (key != null) {
if (values == null) {
this.values.remove(key);
} else {
this.values.put(key, new ArrayList<String>(values));
this.values.put(key, new ArrayList<>(values));
}
}
return this;
......@@ -170,7 +170,7 @@ public class FluentStringsMap implements Map<String, List<String>>, Iterable<Map
public FluentStringsMap replaceAll(FluentStringsMap src) {
if (src != null) {
for (Map.Entry<String, List<String>> header : src) {
replace(header.getKey(), header.getValue());
replaceWith(header.getKey(), header.getValue());
}
}
return this;
......@@ -186,16 +186,13 @@ public class FluentStringsMap implements Map<String, List<String>>, Iterable<Map
public FluentStringsMap replaceAll(Map<? extends String, ? extends Collection<String>> src) {
if (src != null) {
for (Map.Entry<? extends String, ? extends Collection<String>> header : src.entrySet()) {
replace(header.getKey(), header.getValue());
replaceWith(header.getKey(), header.getValue());
}
}
return this;
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public List<String> put(String key, List<String> value) {
if (key == null) {
throw new NullPointerException("Null keys are not allowed");
......@@ -203,14 +200,11 @@ public class FluentStringsMap implements Map<String, List<String>>, Iterable<Map
List<String> oldValue = get(key);
replace(key, value);
replaceWith(key, value);
return oldValue;
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public void putAll(Map<? extends String, ? extends List<String>> values) {
replaceAll(values);
}
......@@ -256,10 +250,7 @@ public class FluentStringsMap implements Map<String, List<String>>, Iterable<Map
return this;
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public List<String> remove(Object key) {
if (key == null) {
return null;
......@@ -271,66 +262,42 @@ public class FluentStringsMap implements Map<String, List<String>>, Iterable<Map
}
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public void clear() {
values.clear();
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public Iterator<Map.Entry<String, List<String>>> iterator() {
return Collections.unmodifiableSet(values.entrySet()).iterator();
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public Set<String> keySet() {
return Collections.unmodifiableSet(values.keySet());
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public Set<Entry<String, List<String>>> entrySet() {
return values.entrySet();
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public int size() {
return values.size();
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public boolean isEmpty() {
return values.isEmpty();
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public boolean containsKey(Object key) {
return key == null ? false : values.containsKey(key.toString());
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public boolean containsValue(Object value) {
return values.containsValue(value);
}
......@@ -380,10 +347,7 @@ public class FluentStringsMap implements Map<String, List<String>>, Iterable<Map
}
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public List<String> get(Object key) {
if (key == null) {
return null;
......@@ -392,14 +356,25 @@ public class FluentStringsMap implements Map<String, List<String>>, Iterable<Map
return values.get(key.toString());
}
/**
* {@inheritDoc}
*/
/* @Override */
@Override
public Collection<List<String>> values() {
return values.values();
}
public List<Param> toParams() {
if (values.isEmpty())
return Collections.emptyList();
else {
List<Param> params = new ArrayList<>(values.size());
for (Map.Entry<String, List<String>> entry : values.entrySet()) {
String name = entry.getKey();
for (String value: entry.getValue())
params.add(new Param(name, value));
}
return params;
}
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
......
/*
* Copyright 2010 Ning, Inc.
*
* Ning licenses this file to you under the Apache License, version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package com.ning.http.client;
import java.net.URI;
/**
* Base class for callback class used by {@link com.ning.http.client.AsyncHandler}
*/
public class HttpContent {
protected final AsyncHttpProvider provider;
protected final URI uri;
protected HttpContent(URI url, AsyncHttpProvider provider) {
this.provider = provider;
this.uri = url;
}
/**
* Return the current {@link AsyncHttpProvider}
*
* @return the current {@link AsyncHttpProvider}
*/
public final AsyncHttpProvider provider() {
return provider;
}
/**
* Return the request {@link URI}
*
* @return the request {@link URI}
*/
public final URI getUrl() {
return uri;
}
}