Skip to content
Snippets Groups Projects
Commit 6707fb04 authored by Emmanuel Bourg's avatar Emmanuel Bourg
Browse files

New upstream version 2.5.1

parent 4ed3005a
No related branches found
No related tags found
No related merge requests found
Showing
with 162 additions and 68 deletions
......@@ -2,7 +2,7 @@
<parent>
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client-project</artifactId>
<version>2.5.0</version>
<version>2.5.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>async-http-client</artifactId>
......
......@@ -12,12 +12,6 @@
*/
package org.asynchttpclient.handler;
import io.netty.handler.codec.http.HttpHeaders;
import org.asynchttpclient.AsyncHandler;
import org.asynchttpclient.HttpResponseBodyPart;
import org.asynchttpclient.HttpResponseStatus;
import org.asynchttpclient.Response;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
......@@ -27,6 +21,13 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.Semaphore;
import io.netty.handler.codec.http.HttpHeaders;
import org.asynchttpclient.AsyncHandler;
import org.asynchttpclient.HttpResponseBodyPart;
import org.asynchttpclient.HttpResponseStatus;
import org.asynchttpclient.Response;
/**
* An AsyncHandler that returns Response (without body, so status code and
* headers only) as fast as possible for inspection, but leaves you the option
......@@ -139,6 +140,11 @@ public class BodyDeferringAsyncHandler implements AsyncHandler<Response> {
return State.CONTINUE;
}
@Override
public void onRetry() {
throw new UnsupportedOperationException(this.getClass().getSimpleName() + " cannot retry a request.");
}
@Override
public State onBodyPartReceived(HttpResponseBodyPart bodyPart) throws Exception {
// body arrived, flush headers
......
......@@ -34,6 +34,7 @@ public class Uri {
private final int port;
private final String query;
private final String path;
private final String fragment;
private String url;
private boolean secured;
private boolean webSocket;
......@@ -43,7 +44,8 @@ public class Uri {
String host,
int port,
String path,
String query) {
String query,
String fragment) {
this.scheme = assertNotEmpty(scheme, "scheme");
this.userInfo = userInfo;
......@@ -51,6 +53,7 @@ public class Uri {
this.port = port;
this.path = path;
this.query = query;
this.fragment = fragment;
this.secured = HTTPS.equals(scheme) || WSS.equals(scheme);
this.webSocket = WS.equals(scheme) || WSS.equalsIgnoreCase(scheme);
}
......@@ -75,7 +78,8 @@ public class Uri {
parser.host,
parser.port,
parser.path,
parser.query);
parser.query,
parser.fragment);
}
public String getQuery() {
......@@ -102,6 +106,10 @@ public class Uri {
return host;
}
public String getFragment() {
return fragment;
}
public boolean isSecured() {
return secured;
}
......@@ -168,6 +176,10 @@ public class Uri {
return sb.toString();
}
public String toFullUrl() {
return fragment == null ? toUrl() : toUrl() + "#" + fragment;
}
public String getBaseUrl() {
return scheme + "://" + host + ":" + getExplicitPort();
}
......@@ -198,7 +210,8 @@ public class Uri {
host,
port,
path,
query);
query,
fragment);
}
public Uri withNewQuery(String newQuery) {
......@@ -207,7 +220,8 @@ public class Uri {
host,
port,
path,
newQuery);
newQuery,
fragment);
}
@Override
......@@ -220,6 +234,7 @@ public class Uri {
result = prime * result + ((query == null) ? 0 : query.hashCode());
result = prime * result + ((scheme == null) ? 0 : scheme.hashCode());
result = prime * result + ((userInfo == null) ? 0 : userInfo.hashCode());
result = prime * result + ((fragment == null) ? 0 : fragment.hashCode());
return result;
}
......@@ -259,6 +274,11 @@ public class Uri {
return false;
} else if (!userInfo.equals(other.userInfo))
return false;
if (fragment == null) {
if (other.fragment != null)
return false;
} else if (!fragment.equals(other.fragment))
return false;
return true;
}
......
......@@ -21,6 +21,7 @@ final class UriParser {
public String host;
public int port = -1;
public String query;
public String fragment;
private String authority;
public String path;
public String userInfo;
......@@ -116,6 +117,9 @@ final class UriParser {
int charpPosition = findWithinCurrentRange('#');
if (charpPosition >= 0) {
end = charpPosition;
if (charpPosition + 1 < originalUrl.length()) {
fragment = originalUrl.substring(charpPosition + 1);
}
}
}
......@@ -123,6 +127,7 @@ final class UriParser {
// see RFC2396 5.2.2: query and fragment inheritance
if (isRelative && currentIndex == end) {
query = context.getQuery();
fragment = context.getFragment();
}
}
......
......@@ -133,7 +133,8 @@ public enum UriEncoder {
uri.getHost(),
uri.getPort(),
newPath,
newQuery);
newQuery,
uri.getFragment());
}
protected abstract String encodePath(String path);
......
......@@ -12,17 +12,17 @@
*/
package org.asynchttpclient.handler;
import org.apache.commons.io.IOUtils;
import org.asynchttpclient.*;
import org.asynchttpclient.exception.RemotelyClosedException;
import org.asynchttpclient.handler.BodyDeferringAsyncHandler.BodyDeferringInputStream;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.testng.annotations.Test;
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
import static io.netty.handler.codec.http.HttpHeaderValues.APPLICATION_OCTET_STREAM;
import static org.apache.commons.io.IOUtils.copy;
import static org.asynchttpclient.Dsl.asyncHttpClient;
import static org.asynchttpclient.Dsl.config;
import static org.asynchttpclient.test.TestUtils.findFreePort;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertTrue;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PipedInputStream;
......@@ -30,14 +30,22 @@ import java.io.PipedOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH;
import static io.netty.handler.codec.http.HttpHeaderValues.APPLICATION_OCTET_STREAM;
import static org.apache.commons.io.IOUtils.copy;
import static org.asynchttpclient.Dsl.asyncHttpClient;
import static org.asynchttpclient.Dsl.config;
import static org.asynchttpclient.test.TestUtils.findFreePort;
import static org.testng.Assert.*;
import org.apache.commons.io.IOUtils;
import org.asynchttpclient.AbstractBasicTest;
import org.asynchttpclient.AsyncHttpClient;
import org.asynchttpclient.AsyncHttpClientConfig;
import org.asynchttpclient.BoundRequestBuilder;
import org.asynchttpclient.ListenableFuture;
import org.asynchttpclient.Response;
import org.asynchttpclient.exception.RemotelyClosedException;
import org.asynchttpclient.handler.BodyDeferringAsyncHandler.BodyDeferringInputStream;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.testng.annotations.Test;
public class BodyDeferringAsyncHandlerTest extends AbstractBasicTest {
......@@ -169,6 +177,37 @@ public class BodyDeferringAsyncHandlerTest extends AbstractBasicTest {
}
}
@Test(expectedExceptions = UnsupportedOperationException.class)
public void deferredInputStreamTrickWithCloseConnectionAndRetry() throws Throwable {
try (AsyncHttpClient client = asyncHttpClient(config().setMaxRequestRetry(1).setRequestTimeout(10000).build())) {
BoundRequestBuilder r = client.prepareGet(getTargetUrl()).addHeader("X-CLOSE-CONNECTION", Boolean.TRUE.toString());
PipedOutputStream pos = new PipedOutputStream();
PipedInputStream pis = new PipedInputStream(pos);
BodyDeferringAsyncHandler bdah = new BodyDeferringAsyncHandler(pos);
Future<Response> f = r.execute(bdah);
BodyDeferringInputStream is = new BodyDeferringInputStream(f, bdah, pis);
Response resp = is.getAsapResponse();
assertNotNull(resp);
assertEquals(resp.getStatusCode(), HttpServletResponse.SC_OK);
assertEquals(resp.getHeader(CONTENT_LENGTH), String.valueOf(CONTENT_LENGTH_VALUE));
// "consume" the body, but our code needs input stream
CountingOutputStream cos = new CountingOutputStream();
try {
try {
copy(is, cos);
} finally {
is.close();
cos.close();
}
} catch (IOException e) {
throw e.getCause();
}
}
}
@Test(expectedExceptions = IOException.class)
public void testConnectionRefused() throws IOException, InterruptedException {
int newPortWithoutAnyoneListening = findFreePort();
......@@ -214,6 +253,7 @@ public class BodyDeferringAsyncHandlerTest extends AbstractBasicTest {
httpResponse.flushBuffer();
final boolean wantConnectionClose = httpRequest.getHeader("X-CLOSE-CONNECTION") != null;
final boolean wantFailure = httpRequest.getHeader("X-FAIL-TRANSFER") != null;
final boolean wantSlow = httpRequest.getHeader("X-SLOW") != null;
......@@ -229,12 +269,17 @@ public class BodyDeferringAsyncHandlerTest extends AbstractBasicTest {
}
}
if (wantFailure && i > CONTENT_LENGTH_VALUE / 2) {
// kaboom
// yes, response is committed, but Jetty does aborts and
// drops connection
httpResponse.sendError(500);
break;
if (i > CONTENT_LENGTH_VALUE / 2) {
if (wantFailure) {
// kaboom
// yes, response is committed, but Jetty does aborts and
// drops connection
httpResponse.sendError(500);
break;
} else if (wantConnectionClose) {
// kaboom^2
httpResponse.getOutputStream().close();
}
}
}
......
......@@ -62,61 +62,61 @@ public class UriParserTest {
@Test
public void testResolveAbsoluteUriAgainstContext() {
Uri context = new Uri("https", null, "example.com", 80, "/path", "");
Uri context = new Uri("https", null, "example.com", 80, "/path", "", null);
validateAgainstRelativeURI(context, "https://example.com:80/path", "http://example.com/path");
}
@Test
public void testRootRelativePath() {
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2");
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2", null);
validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "/relativeUrl");
}
@Test
public void testCurrentDirRelativePath() {
Uri context = new Uri("https", null, "example.com", 80, "/foo/bar", "q=2");
Uri context = new Uri("https", null, "example.com", 80, "/foo/bar", "q=2", null);
validateAgainstRelativeURI(context, "https://example.com:80/foo/bar?q=2", "relativeUrl");
}
@Test
public void testFragmentOnly() {
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2");
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2", null);
validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "#test");
}
@Test
public void testRelativeUrlWithQuery() {
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2");
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2", null);
validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "/relativePath?q=3");
}
@Test
public void testRelativeUrlWithQueryOnly() {
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2");
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2", null);
validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "?q=3");
}
@Test
public void testRelativeURLWithDots() {
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2");
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2", null);
validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "./relative/./url");
}
@Test
public void testRelativeURLWithTwoEmbeddedDots() {
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2");
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2", null);
validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "./relative/../url");
}
@Test
public void testRelativeURLWithTwoTrailingDots() {
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2");
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2", null);
validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "./relative/url/..");
}
@Test
public void testRelativeURLWithOneTrailingDot() {
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2");
Uri context = new Uri("https", null, "example.com", 80, "/path", "q=2", null);
validateAgainstRelativeURI(context, "https://example.com:80/path?q=2", "./relative/url/.");
}
}
......@@ -133,7 +133,7 @@ public class UriTest {
@Test
public void testToUrlWithUserInfoPortPathAndQuery() {
Uri uri = new Uri("http", "user", "example.com", 44, "/path/path2", "query=4");
Uri uri = new Uri("http", "user", "example.com", 44, "/path/path2", "query=4", null);
assertEquals(uri.toUrl(), "http://user@example.com:44/path/path2?query=4", "toUrl returned incorrect url");
}
......@@ -167,7 +167,7 @@ public class UriTest {
@Test
public void testWithNewScheme() {
Uri uri = new Uri("http", "user", "example.com", 44, "/path/path2", "query=4");
Uri uri = new Uri("http", "user", "example.com", 44, "/path/path2", "query=4", null);
Uri newUri = uri.withNewScheme("https");
assertEquals(newUri.getScheme(), "https");
assertEquals(newUri.toUrl(), "https://user@example.com:44/path/path2?query=4", "toUrl returned incorrect url");
......@@ -175,7 +175,7 @@ public class UriTest {
@Test
public void testWithNewQuery() {
Uri uri = new Uri("http", "user", "example.com", 44, "/path/path2", "query=4");
Uri uri = new Uri("http", "user", "example.com", 44, "/path/path2", "query=4", null);
Uri newUri = uri.withNewQuery("query2=10&query3=20");
assertEquals(newUri.getQuery(), "query2=10&query3=20");
assertEquals(newUri.toUrl(), "http://user@example.com:44/path/path2?query2=10&query3=20", "toUrl returned incorrect url");
......@@ -183,14 +183,14 @@ public class UriTest {
@Test
public void testToRelativeUrl() {
Uri uri = new Uri("http", "user", "example.com", 44, "/path/path2", "query=4");
Uri uri = new Uri("http", "user", "example.com", 44, "/path/path2", "query=4", null);
String relativeUrl = uri.toRelativeUrl();
assertEquals(relativeUrl, "/path/path2?query=4", "toRelativeUrl returned incorrect url");
}
@Test
public void testToRelativeUrlWithEmptyPath() {
Uri uri = new Uri("http", "user", "example.com", 44, null, "query=4");
Uri uri = new Uri("http", "user", "example.com", 44, null, "query=4", null);
String relativeUrl = uri.toRelativeUrl();
assertEquals(relativeUrl, "/?query=4", "toRelativeUrl returned incorrect url");
}
......@@ -232,10 +232,27 @@ public class UriTest {
public void testEquals() {
String url = "http://user@hello.com:8080/level1/level2/level3?q=1";
Uri createdUri = Uri.create(url);
Uri constructedUri = new Uri("http", "user", "hello.com", 8080, "/level1/level2/level3", "q=1");
Uri constructedUri = new Uri("http", "user", "hello.com", 8080, "/level1/level2/level3", "q=1", null);
assertTrue(createdUri.equals(constructedUri), "The equals method returned false for two equal urls");
}
@Test
void testFragment() {
String url = "http://user@hello.com:8080/level1/level2/level3?q=1";
String fragment = "foo";
String urlWithFragment = url + "#" + fragment;
Uri uri = Uri.create(urlWithFragment);
assertEquals(fragment, uri.getFragment(), "Fragment should be extracted");
assertEquals(uri.toUrl(), url, "toUrl should return without fragment");
assertEquals(uri.toFullUrl(), urlWithFragment, "toFullUrl should return with fragment");
}
@Test
void testRelativeFragment() {
Uri uri = Uri.create(Uri.create("http://user@hello.com:8080"), "/level1/level2/level3?q=1#foo");
assertEquals("foo", uri.getFragment(), "fragment should be kept when computing a relative url");
}
@Test
public void testIsWebsocket() {
String url = "http://user@hello.com:8080/level1/level2/level3?q=1";
......
......@@ -2,7 +2,7 @@
<parent>
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client-project</artifactId>
<version>2.5.0</version>
<version>2.5.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>async-http-client-example</artifactId>
......
......@@ -2,7 +2,7 @@
<parent>
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client-extras-parent</artifactId>
<version>2.5.0</version>
<version>2.5.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>async-http-client-extras-guava</artifactId>
......
......@@ -18,7 +18,7 @@
<parent>
<artifactId>async-http-client-extras-parent</artifactId>
<groupId>org.asynchttpclient</groupId>
<version>2.5.0</version>
<version>2.5.1</version>
</parent>
<artifactId>async-http-client-extras-jdeferred</artifactId>
<name>Asynchronous Http Client JDeferred Extras</name>
......
......@@ -2,7 +2,7 @@
<parent>
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client-project</artifactId>
<version>2.5.0</version>
<version>2.5.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>async-http-client-extras-parent</artifactId>
......
......@@ -2,7 +2,7 @@
<parent>
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client-extras-parent</artifactId>
<version>2.5.0</version>
<version>2.5.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>async-http-client-extras-registry</artifactId>
......
......@@ -4,7 +4,7 @@
<parent>
<artifactId>async-http-client-extras-parent</artifactId>
<groupId>org.asynchttpclient</groupId>
<version>2.5.0</version>
<version>2.5.1</version>
</parent>
<artifactId>async-http-client-extras-retrofit2</artifactId>
......
......@@ -3,7 +3,7 @@
<parent>
<artifactId>async-http-client-extras-parent</artifactId>
<groupId>org.asynchttpclient</groupId>
<version>2.5.0</version>
<version>2.5.1</version>
</parent>
<artifactId>async-http-client-extras-rxjava</artifactId>
<name>Asynchronous Http Client RxJava Extras</name>
......
......@@ -3,7 +3,7 @@
<parent>
<artifactId>async-http-client-extras-parent</artifactId>
<groupId>org.asynchttpclient</groupId>
<version>2.5.0</version>
<version>2.5.1</version>
</parent>
<artifactId>async-http-client-extras-rxjava2</artifactId>
<name>Asynchronous Http Client RxJava2 Extras</name>
......
......@@ -3,7 +3,7 @@
<parent>
<artifactId>async-http-client-extras-parent</artifactId>
<groupId>org.asynchttpclient</groupId>
<version>2.5.0</version>
<version>2.5.1</version>
</parent>
<artifactId>async-http-client-extras-simple</artifactId>
<name>Asynchronous Http Simple Client</name>
......
......@@ -4,7 +4,7 @@
<parent>
<artifactId>async-http-client-extras-parent</artifactId>
<groupId>org.asynchttpclient</groupId>
<version>2.5.0</version>
<version>2.5.1</version>
</parent>
<artifactId>async-http-client-extras-typesafe-config</artifactId>
......
......@@ -2,7 +2,7 @@
<parent>
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client-project</artifactId>
<version>2.5.0</version>
<version>2.5.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>async-http-client-netty-utils</artifactId>
......
......@@ -9,7 +9,7 @@
<groupId>org.asynchttpclient</groupId>
<artifactId>async-http-client-project</artifactId>
<name>Asynchronous Http Client Project</name>
<version>2.5.0</version>
<version>2.5.1</version>
<packaging>pom</packaging>
<description>
The Async Http Client (AHC) library's purpose is to allow Java
......@@ -402,21 +402,21 @@
<surefire.redirectTestOutputToFile>true</surefire.redirectTestOutputToFile>
<source.property>1.8</source.property>
<target.property>1.8</target.property>
<netty.version>4.1.25.Final</netty.version>
<netty.version>4.1.26.Final</netty.version>
<slf4j.version>1.7.25</slf4j.version>
<reactive-streams.version>1.0.2</reactive-streams.version>
<activation.version>1.2.0</activation.version>
<netty-reactive-streams.version>2.0.0</netty-reactive-streams.version>
<rxjava.version>1.3.8</rxjava.version>
<rxjava2.version>2.1.14</rxjava2.version>
<rxjava2.version>2.1.16</rxjava2.version>
<logback.version>1.2.3</logback.version>
<testng.version>6.13.1</testng.version>
<jetty.version>9.4.8.v20171121</jetty.version>
<tomcat.version>9.0.7</tomcat.version>
<jetty.version>9.4.11.v20180605</jetty.version>
<tomcat.version>9.0.10</tomcat.version>
<commons-io.version>2.6</commons-io.version>
<commons-fileupload.version>1.3.3</commons-fileupload.version>
<privilegedaccessor.version>1.2.2</privilegedaccessor.version>
<mockito.version>2.18.3</mockito.version>
<mockito.version>2.19.0</mockito.version>
<hamcrest.version>2.0.0.0</hamcrest.version>
</properties>
</project>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment