add our HttpResponse in the client API, REST client module, fix dependencies with compile/compileTest

This commit is contained in:
Jörg Prante 2019-08-07 18:50:42 +02:00
parent 7848b063e7
commit 28cdfcfb57
45 changed files with 366 additions and 282 deletions

View file

@ -1,6 +1,6 @@
group = org.xbib group = org.xbib
name = netty-http name = netty-http
version = 4.1.38.0 version = 4.1.38.1
# main packages # main packages
netty.version = 4.1.38.Final netty.version = 4.1.38.Final

View file

@ -0,0 +1,3 @@
dependencies {
compile project(':netty-http-client')
}

View file

@ -1,12 +1,12 @@
package org.xbib.netty.http.client.rest; package org.xbib.netty.http.client.rest;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpMethod;
import org.xbib.net.URL; import org.xbib.net.URL;
import org.xbib.netty.http.client.Client; import org.xbib.netty.http.client.Client;
import org.xbib.netty.http.common.HttpAddress; import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.client.Request; import org.xbib.netty.http.client.Request;
import org.xbib.netty.http.common.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.Charset; import java.nio.charset.Charset;
@ -16,16 +16,16 @@ public class RestClient {
private static final Client client = new Client(); private static final Client client = new Client();
private FullHttpResponse response; private HttpResponse response;
private RestClient() { private RestClient() {
} }
public void setResponse(FullHttpResponse response) { public void setResponse(HttpResponse response) {
this.response = response.copy(); this.response = response;
} }
public FullHttpResponse getResponse() { public HttpResponse getResponse() {
return response; return response;
} }
@ -34,14 +34,8 @@ public class RestClient {
} }
public String asString(Charset charset) { public String asString(Charset charset) {
ByteBuf byteBuf = response != null ? response.content() : null; ByteBuf byteBuf = response != null ? response.getBody() : null;
try { return byteBuf != null && byteBuf.isReadable() ? byteBuf.toString(charset) : null;
return byteBuf != null && byteBuf.isReadable() ? response.content().toString(charset) : null;
} finally {
if (byteBuf != null) {
byteBuf.release();
}
}
} }
public void close() throws IOException { public void close() throws IOException {

View file

@ -1,7 +1,6 @@
package org.xbib.netty.http.client.test.rest; package org.xbib.netty.http.client.rest;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.netty.http.client.rest.RestClient;
import java.io.IOException; import java.io.IOException;
import java.util.logging.Logger; import java.util.logging.Logger;

View file

@ -1,12 +1,10 @@
dependencies { dependencies {
implementation project(":netty-http-common") compile project(":netty-http-common")
implementation "io.netty:netty-handler-proxy:${project.property('netty.version')}" compile "io.netty:netty-handler-proxy:${project.property('netty.version')}"
implementation "io.netty:netty-transport-native-epoll:${project.property('netty.version')}" compile "io.netty:netty-transport-native-epoll:${project.property('netty.version')}"
implementation "io.netty:netty-codec-http2:${project.property('netty.version')}" testCompile "io.netty:netty-tcnative-boringssl-static:${project.property('tcnative.version')}"
implementation "org.xbib:net-url:${project.property('xbib-net-url.version')}" testCompile "org.bouncycastle:bcpkix-jdk15on:${project.property('bouncycastle.version')}"
testImplementation "io.netty:netty-tcnative-boringssl-static:${project.property('tcnative.version')}" testCompile "org.conscrypt:conscrypt-openjdk-uber:${project.property('conscrypt.version')}"
testImplementation "org.bouncycastle:bcpkix-jdk15on:${project.property('bouncycastle.version')}" testCompile "com.fasterxml.jackson.core:jackson-databind:${project.property('jackson.version')}"
testImplementation "org.conscrypt:conscrypt-openjdk-uber:${project.property('conscrypt.version')}"
testImplementation "com.fasterxml.jackson.core:jackson-databind:${project.property('jackson.version')}"
} }

View file

@ -13,7 +13,6 @@ import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.pool.ChannelPoolHandler; import io.netty.channel.pool.ChannelPoolHandler;
import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http2.Http2Settings; import io.netty.handler.codec.http2.Http2Settings;
import io.netty.handler.proxy.HttpProxyHandler; import io.netty.handler.proxy.HttpProxyHandler;
@ -33,6 +32,7 @@ import org.xbib.netty.http.client.transport.Http2Transport;
import org.xbib.netty.http.client.transport.HttpTransport; import org.xbib.netty.http.client.transport.HttpTransport;
import org.xbib.netty.http.client.transport.Transport; import org.xbib.netty.http.client.transport.Transport;
import org.xbib.netty.http.common.HttpAddress; import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.netty.http.common.NetworkUtils; import org.xbib.netty.http.common.NetworkUtils;
import org.xbib.netty.http.common.security.SecurityUtil; import org.xbib.netty.http.common.security.SecurityUtil;
@ -261,7 +261,7 @@ public final class Client {
} }
public <T> CompletableFuture<T> execute(Request request, public <T> CompletableFuture<T> execute(Request request,
Function<FullHttpResponse, T> supplier) throws IOException { Function<HttpResponse, T> supplier) throws IOException {
return newTransport(HttpAddress.of(request.url(), request.httpVersion())) return newTransport(HttpAddress.of(request.url(), request.httpVersion()))
.execute(request, supplier); .execute(request, supplier);
} }

View file

@ -25,6 +25,7 @@ import org.xbib.netty.http.client.listener.StatusListener;
import org.xbib.netty.http.client.retry.BackOff; import org.xbib.netty.http.client.retry.BackOff;
import org.xbib.netty.http.common.HttpAddress; import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.common.HttpParameters; import org.xbib.netty.http.common.HttpParameters;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.netty.http.common.cookie.Cookie; import org.xbib.netty.http.common.cookie.Cookie;
import java.nio.charset.MalformedInputException; import java.nio.charset.MalformedInputException;
@ -73,7 +74,7 @@ public class Request {
private CompletableFuture<?> completableFuture; private CompletableFuture<?> completableFuture;
private ResponseListener responseListener; private ResponseListener<HttpResponse> responseListener;
private CookieListener cookieListener; private CookieListener cookieListener;
@ -208,12 +209,12 @@ public class Request {
return statusListener; return statusListener;
} }
public Request setResponseListener(ResponseListener responseListener) { public Request setResponseListener(ResponseListener<HttpResponse> responseListener) {
this.responseListener = responseListener; this.responseListener = responseListener;
return this; return this;
} }
public ResponseListener getResponseListener() { public ResponseListener<HttpResponse> getResponseListener() {
return responseListener; return responseListener;
} }

View file

@ -5,6 +5,7 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse;
import org.xbib.netty.http.client.transport.Transport; import org.xbib.netty.http.client.transport.Transport;
import org.xbib.netty.http.common.DefaultHttpResponse;
@ChannelHandler.Sharable @ChannelHandler.Sharable
public class HttpResponseHandler extends SimpleChannelInboundHandler<FullHttpResponse> { public class HttpResponseHandler extends SimpleChannelInboundHandler<FullHttpResponse> {
@ -12,7 +13,8 @@ public class HttpResponseHandler extends SimpleChannelInboundHandler<FullHttpRes
@Override @Override
public void channelRead0(ChannelHandlerContext ctx, FullHttpResponse httpResponse) throws Exception { public void channelRead0(ChannelHandlerContext ctx, FullHttpResponse httpResponse) throws Exception {
Transport transport = ctx.channel().attr(Transport.TRANSPORT_ATTRIBUTE_KEY).get(); Transport transport = ctx.channel().attr(Transport.TRANSPORT_ATTRIBUTE_KEY).get();
transport.responseReceived(ctx.channel(),null, httpResponse); transport.responseReceived(ctx.channel(),null,
new DefaultHttpResponse(transport.getHttpAddress(), httpResponse.retain()));
} }
@Override @Override

View file

@ -6,6 +6,7 @@ import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http2.HttpConversionUtil; import io.netty.handler.codec.http2.HttpConversionUtil;
import org.xbib.netty.http.client.transport.Transport; import org.xbib.netty.http.client.transport.Transport;
import org.xbib.netty.http.common.DefaultHttpResponse;
@ChannelHandler.Sharable @ChannelHandler.Sharable
public class Http2ResponseHandler extends SimpleChannelInboundHandler<FullHttpResponse> { public class Http2ResponseHandler extends SimpleChannelInboundHandler<FullHttpResponse> {
@ -14,7 +15,8 @@ public class Http2ResponseHandler extends SimpleChannelInboundHandler<FullHttpRe
protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse httpResponse) throws Exception { protected void channelRead0(ChannelHandlerContext ctx, FullHttpResponse httpResponse) throws Exception {
Transport transport = ctx.channel().attr(Transport.TRANSPORT_ATTRIBUTE_KEY).get(); Transport transport = ctx.channel().attr(Transport.TRANSPORT_ATTRIBUTE_KEY).get();
Integer streamId = httpResponse.headers().getInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text()); Integer streamId = httpResponse.headers().getInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text());
transport.responseReceived(ctx.channel(), streamId, httpResponse); transport.responseReceived(ctx.channel(), streamId,
new DefaultHttpResponse(transport.getHttpAddress(), httpResponse.retain()));
} }
@Override @Override

View file

@ -1,9 +1,9 @@
package org.xbib.netty.http.client.listener; package org.xbib.netty.http.client.listener;
import io.netty.handler.codec.http.FullHttpResponse; import org.xbib.netty.http.common.HttpResponse;
@FunctionalInterface @FunctionalInterface
public interface ResponseListener { public interface ResponseListener<R extends HttpResponse> {
void onResponse(FullHttpResponse fullHttpResponse); void onResponse(R response);
} }

View file

@ -1,9 +1,10 @@
package org.xbib.netty.http.client.listener; package org.xbib.netty.http.client.listener;
import io.netty.handler.codec.http.HttpResponseStatus;
import org.xbib.netty.http.common.HttpStatus;
@FunctionalInterface @FunctionalInterface
public interface StatusListener { public interface StatusListener {
void onStatus(HttpResponseStatus httpResponseStatus); void onStatus(HttpStatus httpStatus);
} }

View file

@ -1,7 +1,6 @@
package org.xbib.netty.http.client.transport; package org.xbib.netty.http.client.transport;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.ssl.SslHandler; import io.netty.handler.ssl.SslHandler;
@ -12,6 +11,7 @@ import org.xbib.netty.http.client.Client;
import org.xbib.netty.http.common.HttpAddress; import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.client.Request; import org.xbib.netty.http.client.Request;
import org.xbib.netty.http.client.retry.BackOff; import org.xbib.netty.http.client.retry.BackOff;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.netty.http.common.cookie.Cookie; import org.xbib.netty.http.common.cookie.Cookie;
import org.xbib.netty.http.common.cookie.CookieBox; import org.xbib.netty.http.common.cookie.CookieBox;
@ -65,6 +65,11 @@ abstract class BaseTransport implements Transport {
this.requests = new ConcurrentSkipListMap<>(); this.requests = new ConcurrentSkipListMap<>();
} }
@Override
public HttpAddress getHttpAddress() {
return httpAddress;
}
/** /**
* Experimental method for executing in a wrapping completable future. * Experimental method for executing in a wrapping completable future.
* @param request request * @param request request
@ -74,7 +79,7 @@ abstract class BaseTransport implements Transport {
*/ */
@Override @Override
public <T> CompletableFuture<T> execute(Request request, public <T> CompletableFuture<T> execute(Request request,
Function<FullHttpResponse, T> supplier) throws IOException { Function<HttpResponse, T> supplier) throws IOException {
Objects.requireNonNull(supplier); Objects.requireNonNull(supplier);
final CompletableFuture<T> completableFuture = new CompletableFuture<>(); final CompletableFuture<T> completableFuture = new CompletableFuture<>();
request.setResponseListener(response -> { request.setResponseListener(response -> {
@ -237,7 +242,7 @@ abstract class BaseTransport implements Transport {
return channel; return channel;
} }
protected Request continuation(Request request, FullHttpResponse httpResponse) throws URLSyntaxException { protected Request continuation(Request request, HttpResponse httpResponse) throws URLSyntaxException {
if (httpResponse == null) { if (httpResponse == null) {
return null; return null;
} }
@ -247,7 +252,7 @@ abstract class BaseTransport implements Transport {
} }
try { try {
if (request.canRedirect()) { if (request.canRedirect()) {
int status = httpResponse.status().code(); int status = httpResponse.getStatus().getCode();
switch (status) { switch (status) {
case 300: case 300:
case 301: case 301:
@ -256,12 +261,12 @@ abstract class BaseTransport implements Transport {
case 305: case 305:
case 307: case 307:
case 308: case 308:
String location = httpResponse.headers().get(HttpHeaderNames.LOCATION); String location = httpResponse.getHeaders().getHeader(HttpHeaderNames.LOCATION);
location = new PercentDecoder(StandardCharsets.UTF_8.newDecoder()).decode(location); location = new PercentDecoder(StandardCharsets.UTF_8.newDecoder()).decode(location);
if (location != null) { if (location != null) {
logger.log(Level.FINE, "found redirect location: " + location); logger.log(Level.FINE, "found redirect location: " + location);
URL redirUrl = URL.base(request.url()).resolve(location); URL redirUrl = URL.base(request.url()).resolve(location);
HttpMethod method = httpResponse.status().code() == 303 ? HttpMethod.GET : request.httpMethod(); HttpMethod method = httpResponse.getStatus().getCode() == 303 ? HttpMethod.GET : request.httpMethod();
Request.Builder newHttpRequestBuilder = Request.builder(method) Request.Builder newHttpRequestBuilder = Request.builder(method)
.url(redirUrl) .url(redirUrl)
.setVersion(request.httpVersion()) .setVersion(request.httpVersion())
@ -297,7 +302,7 @@ abstract class BaseTransport implements Transport {
return null; return null;
} }
protected Request retry(Request request, FullHttpResponse httpResponse) { protected Request retry(Request request, HttpResponse httpResponse) {
if (httpResponse == null) { if (httpResponse == null) {
return null; return null;
} }
@ -308,7 +313,7 @@ abstract class BaseTransport implements Transport {
if (request.isBackOff()) { if (request.isBackOff()) {
BackOff backOff = request.getBackOff() != null ? request.getBackOff() : BackOff backOff = request.getBackOff() != null ? request.getBackOff() :
client.getClientConfig().getBackOff(); client.getClientConfig().getBackOff();
int status = httpResponse.status().code(); int status = httpResponse.getStatus ().getCode();
switch (status) { switch (status) {
case 403: case 403:
case 404: case 404:

View file

@ -3,7 +3,6 @@ package org.xbib.netty.http.client.transport;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http2.DefaultHttp2DataFrame; import io.netty.handler.codec.http2.DefaultHttp2DataFrame;
@ -26,6 +25,7 @@ import org.xbib.netty.http.client.listener.StatusListener;
import org.xbib.netty.http.common.HttpAddress; import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.client.Request; import org.xbib.netty.http.client.Request;
import org.xbib.netty.http.client.listener.ResponseListener; import org.xbib.netty.http.client.listener.ResponseListener;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.netty.http.common.cookie.Cookie; import org.xbib.netty.http.common.cookie.Cookie;
import java.io.IOException; import java.io.IOException;
@ -134,13 +134,13 @@ public class Http2Transport extends BaseTransport {
} }
@Override @Override
public void responseReceived(Channel channel, Integer streamId, FullHttpResponse fullHttpResponse) { public void responseReceived(Channel channel, Integer streamId, HttpResponse httpResponse) {
if (throwable != null) { if (throwable != null) {
logger.log(Level.WARNING, "throwable not null for response " + fullHttpResponse, throwable); logger.log(Level.WARNING, "throwable not null for response " + httpResponse, throwable);
return; return;
} }
if (streamId == null) { if (streamId == null) {
logger.log(Level.WARNING, "stream ID is null for response " + fullHttpResponse); logger.log(Level.WARNING, "stream ID is null for response " + httpResponse);
return; return;
} }
// format of childchan channel ID is <parent channel ID> "/" <substream ID> // format of childchan channel ID is <parent channel ID> "/" <substream ID>
@ -160,9 +160,9 @@ public class Http2Transport extends BaseTransport {
} else { } else {
StatusListener statusListener = request.getStatusListener(); StatusListener statusListener = request.getStatusListener();
if (statusListener != null) { if (statusListener != null) {
statusListener.onStatus(fullHttpResponse.status()); statusListener.onStatus(httpResponse.getStatus());
} }
for (String cookieString : fullHttpResponse.headers().getAll(HttpHeaderNames.SET_COOKIE)) { for (String cookieString : httpResponse.getHeaders().getAllHeaders(HttpHeaderNames.SET_COOKIE)) {
Cookie cookie = ClientCookieDecoder.STRICT.decode(cookieString); Cookie cookie = ClientCookieDecoder.STRICT.decode(cookieString);
addCookie(cookie); addCookie(cookie);
CookieListener cookieListener = request.getCookieListener(); CookieListener cookieListener = request.getCookieListener();
@ -170,17 +170,17 @@ public class Http2Transport extends BaseTransport {
cookieListener.onCookie(cookie); cookieListener.onCookie(cookie);
} }
} }
ResponseListener responseListener = request.getResponseListener(); ResponseListener<HttpResponse> responseListener = request.getResponseListener();
if (responseListener != null) { if (responseListener != null) {
responseListener.onResponse(fullHttpResponse); responseListener.onResponse(httpResponse);
} }
try { try {
Request retryRequest = retry(request, fullHttpResponse); Request retryRequest = retry(request, httpResponse);
if (retryRequest != null) { if (retryRequest != null) {
// retry transport, wait for completion // retry transport, wait for completion
client.retry(this, retryRequest); client.retry(this, retryRequest);
} else { } else {
Request continueRequest = continuation(request, fullHttpResponse); Request continueRequest = continuation(request, httpResponse);
if (continueRequest != null) { if (continueRequest != null) {
// continue with new transport, synchronous call here, wait for completion // continue with new transport, synchronous call here, wait for completion
client.continuation(this, continueRequest); client.continuation(this, continueRequest);

View file

@ -3,7 +3,6 @@ package org.xbib.netty.http.client.transport;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.handler.codec.http.DefaultFullHttpRequest; import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http2.Http2Headers; import io.netty.handler.codec.http2.Http2Headers;
import io.netty.handler.codec.http2.Http2Settings; import io.netty.handler.codec.http2.Http2Settings;
@ -17,6 +16,7 @@ import org.xbib.netty.http.client.listener.StatusListener;
import org.xbib.netty.http.common.HttpAddress; import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.client.Request; import org.xbib.netty.http.client.Request;
import org.xbib.netty.http.client.listener.ResponseListener; import org.xbib.netty.http.client.listener.ResponseListener;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.netty.http.common.cookie.Cookie; import org.xbib.netty.http.common.cookie.Cookie;
import java.io.IOException; import java.io.IOException;
@ -75,9 +75,9 @@ public class HttpTransport extends BaseTransport {
} }
@Override @Override
public void responseReceived(Channel channel, Integer streamId, FullHttpResponse fullHttpResponse) { public void responseReceived(Channel channel, Integer streamId, HttpResponse httpResponse) {
if (throwable != null) { if (throwable != null) {
logger.log(Level.WARNING, "throwable not null for response " + fullHttpResponse, throwable); logger.log(Level.WARNING, "throwable not null for response " + httpResponse, throwable);
return; return;
} }
if (requests.isEmpty()) { if (requests.isEmpty()) {
@ -89,9 +89,9 @@ public class HttpTransport extends BaseTransport {
if (request != null) { if (request != null) {
StatusListener statusListener = request.getStatusListener(); StatusListener statusListener = request.getStatusListener();
if (statusListener != null) { if (statusListener != null) {
statusListener.onStatus(fullHttpResponse.status()); statusListener.onStatus(httpResponse.getStatus());
} }
for (String cookieString : fullHttpResponse.headers().getAll(HttpHeaderNames.SET_COOKIE)) { for (String cookieString : httpResponse.getHeaders().getAllHeaders(HttpHeaderNames.SET_COOKIE)) {
Cookie cookie = ClientCookieDecoder.STRICT.decode(cookieString); Cookie cookie = ClientCookieDecoder.STRICT.decode(cookieString);
addCookie(cookie); addCookie(cookie);
CookieListener cookieListener = request.getCookieListener(); CookieListener cookieListener = request.getCookieListener();
@ -99,18 +99,18 @@ public class HttpTransport extends BaseTransport {
cookieListener.onCookie(cookie); cookieListener.onCookie(cookie);
} }
} }
ResponseListener responseListener = request.getResponseListener(); ResponseListener<HttpResponse> responseListener = request.getResponseListener();
if (responseListener != null) { if (responseListener != null) {
responseListener.onResponse(fullHttpResponse); responseListener.onResponse(httpResponse);
} }
} }
try { try {
Request retryRequest = retry(request, fullHttpResponse); Request retryRequest = retry(request, httpResponse);
if (retryRequest != null) { if (retryRequest != null) {
// retry transport, wait for completion // retry transport, wait for completion
client.retry(this, retryRequest); client.retry(this, retryRequest);
} else { } else {
Request continueRequest = continuation(request, fullHttpResponse); Request continueRequest = continuation(request, httpResponse);
if (continueRequest != null) { if (continueRequest != null) {
// continue with new transport, synchronous call here, wait for completion // continue with new transport, synchronous call here, wait for completion
client.continuation(this, continueRequest); client.continuation(this, continueRequest);

View file

@ -1,11 +1,12 @@
package org.xbib.netty.http.client.transport; package org.xbib.netty.http.client.transport;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http2.Http2Headers; import io.netty.handler.codec.http2.Http2Headers;
import io.netty.handler.codec.http2.Http2Settings; import io.netty.handler.codec.http2.Http2Settings;
import io.netty.util.AttributeKey; import io.netty.util.AttributeKey;
import org.xbib.netty.http.client.Request; import org.xbib.netty.http.client.Request;
import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.netty.http.common.cookie.CookieBox; import org.xbib.netty.http.common.cookie.CookieBox;
import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSession;
@ -18,15 +19,17 @@ public interface Transport {
AttributeKey<Transport> TRANSPORT_ATTRIBUTE_KEY = AttributeKey.valueOf("transport"); AttributeKey<Transport> TRANSPORT_ATTRIBUTE_KEY = AttributeKey.valueOf("transport");
HttpAddress getHttpAddress();
Transport execute(Request request) throws IOException; Transport execute(Request request) throws IOException;
<T> CompletableFuture<T> execute(Request request, Function<FullHttpResponse, T> supplier) throws IOException; <T> CompletableFuture<T> execute(Request request, Function<HttpResponse, T> supplier) throws IOException;
void waitForSettings(); void waitForSettings();
void settingsReceived(Http2Settings http2Settings) throws IOException; void settingsReceived(Http2Settings http2Settings) throws IOException;
void responseReceived(Channel channel, Integer streamId, FullHttpResponse fullHttpResponse) throws IOException; void responseReceived(Channel channel, Integer streamId, HttpResponse fullHttpResponse) throws IOException;
void pushPromiseReceived(Channel channel, Integer streamId, Integer promisedStreamId, Http2Headers headers); void pushPromiseReceived(Channel channel, Integer streamId, Integer promisedStreamId, Http2Headers headers);

View file

@ -1,9 +1,9 @@
package org.xbib.netty.http.client.test; package org.xbib.netty.http.client.test;
import io.netty.handler.codec.http.FullHttpResponse;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.netty.http.client.Client; import org.xbib.netty.http.client.Client;
import org.xbib.netty.http.client.Request; import org.xbib.netty.http.client.Request;
import org.xbib.netty.http.common.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -23,12 +23,12 @@ class CompletableFutureTest {
void testComposeCompletableFutures() throws IOException { void testComposeCompletableFutures() throws IOException {
Client client = Client.builder().build(); Client client = Client.builder().build();
try { try {
final Function<FullHttpResponse, String> httpResponseStringFunction = response -> final Function<HttpResponse, String> stringFunction = response ->
response.content().toString(StandardCharsets.UTF_8); response.getBodyAsString(StandardCharsets.UTF_8);
Request request = Request.get() Request request = Request.get()
.url("http://repo.maven.apache.org/maven2/org/xbib/netty-http-client/maven-metadata.xml.sha1") .url("http://repo.maven.apache.org/maven2/org/xbib/netty-http-client/maven-metadata.xml.sha1")
.build(); .build();
CompletableFuture<String> completableFuture = client.execute(request, httpResponseStringFunction) CompletableFuture<String> completableFuture = client.execute(request, stringFunction)
.exceptionally(Throwable::getMessage) .exceptionally(Throwable::getMessage)
.thenCompose(content -> { .thenCompose(content -> {
logger.log(Level.INFO, content); logger.log(Level.INFO, content);
@ -37,7 +37,7 @@ class CompletableFutureTest {
return client.execute(Request.post() return client.execute(Request.post()
.url("http://google.com/") .url("http://google.com/")
.addParameter("query", content) .addParameter("query", content)
.build(), httpResponseStringFunction); .build(), stringFunction);
} catch (IOException e) { } catch (IOException e) {
logger.log(Level.WARNING, e.getMessage(), e); logger.log(Level.WARNING, e.getMessage(), e);
return null; return null;

View file

@ -28,10 +28,9 @@ class ConscryptTest {
.url("https://google.com") .url("https://google.com")
.setVersion("HTTP/1.1") .setVersion("HTTP/1.1")
.build() .build()
.setResponseListener(fullHttpResponse -> { .setResponseListener(resp -> {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8); logger.log(Level.INFO, "status = " + resp.getStatus()
logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + resp.getBodyAsString(StandardCharsets.UTF_8));
+ " response body = " + response);
}); });
client.execute(request).get(); client.execute(request).get();
} finally { } finally {

View file

@ -36,9 +36,9 @@ class CookieSetterHttpBinTest {
.url("http://httpbin.org/cookies/set?name=value") .url("http://httpbin.org/cookies/set?name=value")
.build() .build()
.setCookieListener(cookie -> logger.log(Level.INFO, "this is the cookie: " + cookie.toString())) .setCookieListener(cookie -> logger.log(Level.INFO, "this is the cookie: " + cookie.toString()))
.setResponseListener(fullHttpResponse -> { .setResponseListener(resp -> {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8); logger.log(Level.INFO, "status = " + resp.getStatus() +
logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + response); " response body = " + resp.getBodyAsString(StandardCharsets.UTF_8));
}); });
client.execute(request).get(); client.execute(request).get();
} finally { } finally {

View file

@ -22,10 +22,10 @@ class Http1Test {
.build(); .build();
try { try {
Request request = Request.get().url("http://xbib.org").build() Request request = Request.get().url("http://xbib.org").build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO,
msg.headers().entries() + "got response: " + resp.getHeaders() +
msg.content().toString(StandardCharsets.UTF_8) + resp.getBodyAsString(StandardCharsets.UTF_8) +
" status=" + msg.status().code())); " status=" + resp.getStatus()));
client.execute(request).get(); client.execute(request).get();
} finally { } finally {
client.shutdownGracefully(); client.shutdownGracefully();
@ -38,13 +38,13 @@ class Http1Test {
.build(); .build();
try { try {
Request request1 = Request.get().url("http://xbib.org").build() Request request1 = Request.get().url("http://xbib.org").build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO, "got response: " +
msg.content().toString(StandardCharsets.UTF_8))); resp.getBodyAsString(StandardCharsets.UTF_8)));
client.execute(request1).get(); client.execute(request1).get();
Request request2 = Request.get().url("http://google.com").setVersion("HTTP/1.1").build() Request request2 = Request.get().url("http://google.com").setVersion("HTTP/1.1").build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO, "got response: " +
msg.content().toString(StandardCharsets.UTF_8))); resp.getBodyAsString(StandardCharsets.UTF_8)));
client.execute(request2).get(); client.execute(request2).get();
} finally { } finally {
client.shutdownGracefully(); client.shutdownGracefully();
@ -59,17 +59,13 @@ class Http1Test {
Request request1 = Request.builder(HttpMethod.GET) Request request1 = Request.builder(HttpMethod.GET)
.url("http://xbib.org").setVersion("HTTP/1.1") .url("http://xbib.org").setVersion("HTTP/1.1")
.build() .build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO, "got response: " +
msg.headers().entries() + resp.getHeaders() + " status=" +resp.getStatus()));
//msg.content().toString(StandardCharsets.UTF_8) +
" status=" + msg.status().code()));
Request request2 = Request.builder(HttpMethod.GET) Request request2 = Request.builder(HttpMethod.GET)
.url("http://xbib.org").setVersion("HTTP/1.1") .url("http://xbib.org").setVersion("HTTP/1.1")
.build() .build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO, "got response: " +
msg.headers().entries() + resp.getHeaders() + " status=" +resp.getStatus()));
//msg.content().toString(StandardCharsets.UTF_8) +
" status=" + msg.status().code()));
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
client.execute(request1); client.execute(request1);

View file

@ -22,10 +22,9 @@ class SecureHttpTest {
.build(); .build();
try { try {
Request request = Request.get().url("https://www.google.com/").build() Request request = Request.get().url("https://www.google.com/").build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO, "got response: " +
msg.headers().entries() + resp.getHeaders() + resp.getBodyAsString(StandardCharsets.UTF_8) +
msg.content().toString(StandardCharsets.UTF_8) + " status=" + resp.getStatus()));
" status=" + msg.status().code()));
client.execute(request).get(); client.execute(request).get();
} finally { } finally {
client.shutdownGracefully(); client.shutdownGracefully();
@ -38,13 +37,13 @@ class SecureHttpTest {
.build(); .build();
try { try {
Request request1 = Request.get().url("https://google.com").build() Request request1 = Request.get().url("https://google.com").build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO, "got response: " +
msg.content().toString(StandardCharsets.UTF_8))); resp.getBodyAsString(StandardCharsets.UTF_8)));
client.execute(request1).get(); client.execute(request1).get();
Request request2 = Request.get().url("https://google.com").setVersion("HTTP/2.0").build() Request request2 = Request.get().url("https://google.com").setVersion("HTTP/2.0").build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO, "got response: " +
msg.content().toString(StandardCharsets.UTF_8))); resp.getBodyAsString(StandardCharsets.UTF_8)));
client.execute(request2).get(); client.execute(request2).get();
} finally { } finally {
client.shutdownGracefully(); client.shutdownGracefully();
@ -59,15 +58,15 @@ class SecureHttpTest {
Request request1 = Request.builder(HttpMethod.GET) Request request1 = Request.builder(HttpMethod.GET)
.url("https://google.com").setVersion("HTTP/1.1") .url("https://google.com").setVersion("HTTP/1.1")
.build() .build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO, "got response: " +
msg.headers().entries() + resp.getHeaders() +
" status=" + msg.status().code())); " status=" + resp.getStatus()));
Request request2 = Request.builder(HttpMethod.GET) Request request2 = Request.builder(HttpMethod.GET)
.url("https://google.com").setVersion("HTTP/1.1") .url("https://google.com").setVersion("HTTP/1.1")
.build() .build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO, "got response: " +
msg.headers().entries() + resp.getHeaders() +
" status=" + msg.status().code())); " status=" + resp.getStatus()));
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
client.execute(request1); client.execute(request1);

View file

@ -1,10 +1,10 @@
package org.xbib.netty.http.client.test; package org.xbib.netty.http.client.test;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.proxy.HttpProxyHandler; import io.netty.handler.proxy.HttpProxyHandler;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.netty.http.client.Client; import org.xbib.netty.http.client.Client;
import org.xbib.netty.http.client.Request; import org.xbib.netty.http.client.Request;
import org.xbib.netty.http.common.HttpResponse;
import java.io.IOException; import java.io.IOException;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@ -24,9 +24,9 @@ class XbibTest {
try { try {
Request request = Request.get().url("http://xbib.org") Request request = Request.get().url("http://xbib.org")
.build() .build()
.setResponseListener(fullHttpResponse -> { .setResponseListener(resp -> {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8); logger.log(Level.INFO, "status = " + resp.getStatus() +
logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + response); " response = " + resp.getBodyAsString(StandardCharsets.UTF_8));
}); });
client.execute(request); client.execute(request);
} finally { } finally {
@ -40,18 +40,18 @@ class XbibTest {
.setTcpNodelay(true) .setTcpNodelay(true)
.build(); .build();
try { try {
final Function<FullHttpResponse, String> httpResponseStringFunction = final Function<HttpResponse, String> stringFunction =
response -> response.content().toString(StandardCharsets.UTF_8); response -> response.getBodyAsString(StandardCharsets.UTF_8);
Request request = Request.get().url("http://xbib.org") Request request = Request.get().url("http://xbib.org")
.build(); .build();
final CompletableFuture<String> completableFuture = httpClient.execute(request, httpResponseStringFunction) final CompletableFuture<String> completableFuture = httpClient.execute(request, stringFunction)
.exceptionally(Throwable::getMessage) .exceptionally(Throwable::getMessage)
.thenCompose(content -> { .thenCompose(content -> {
try { try {
return httpClient.execute(Request.post() return httpClient.execute(Request.post()
.url("http://google.de") .url("http://google.de")
.addParameter("query", content.substring(0, 15)) .addParameter("query", content.substring(0, 15))
.build(), httpResponseStringFunction); .build(), stringFunction);
} catch (IOException e) { } catch (IOException e) {
logger.log(Level.WARNING, e.getMessage(), e); logger.log(Level.WARNING, e.getMessage(), e);
return null; return null;
@ -75,10 +75,8 @@ class XbibTest {
httpClient.execute(Request.get() httpClient.execute(Request.get()
.url("http://xbib.org") .url("http://xbib.org")
.build() .build()
.setResponseListener(fullHttpResponse -> { .setResponseListener(resp -> logger.log(Level.INFO, "status = " + resp.getStatus() +
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8); " response body = " + resp.getBodyAsString(StandardCharsets.UTF_8))))
logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + response);
}))
.get(); .get();
} finally { } finally {
httpClient.shutdownGracefully(); httpClient.shutdownGracefully();
@ -94,10 +92,10 @@ class XbibTest {
.url("http://xbib.org") .url("http://xbib.org")
.setTimeoutInMillis(10) .setTimeoutInMillis(10)
.build() .build()
.setResponseListener(fullHttpResponse -> { .setResponseListener(resp ->
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8); logger.log(Level.INFO, "status = " + resp.getStatus() +
logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + response); " response body = " + resp.getBodyAsString(StandardCharsets.UTF_8))
})) ))
.get(); .get();
} finally { } finally {
httpClient.shutdownGracefully(); httpClient.shutdownGracefully();
@ -112,9 +110,9 @@ class XbibTest {
.setVersion("HTTP/1.1") .setVersion("HTTP/1.1")
.url("http://xbib.org") .url("http://xbib.org")
.build() .build()
.setResponseListener(fullHttpResponse -> { .setResponseListener(resp -> {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8); logger.log(Level.INFO, "status = " + resp.getStatus() +
logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + response); " response body = " + resp.getBodyAsString(StandardCharsets.UTF_8));
})) }))
.get(); .get();
@ -122,9 +120,9 @@ class XbibTest {
.setVersion("HTTP/1.1") .setVersion("HTTP/1.1")
.url("http://xbib.org") .url("http://xbib.org")
.build() .build()
.setResponseListener(fullHttpResponse -> { .setResponseListener(resp -> {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8); logger.log(Level.INFO, "status = " + resp.getStatus() +
logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + response); " response body = " + resp.getBodyAsString(StandardCharsets.UTF_8));
})) }))
.get(); .get();
} finally { } finally {

View file

@ -39,10 +39,9 @@ public class AkamaiTest {
//.url("https://http2.akamai.com/") //.url("https://http2.akamai.com/")
.setVersion("HTTP/2.0") .setVersion("HTTP/2.0")
.build() .build()
.setResponseListener(msg -> { .setResponseListener(resp -> {
String response = msg.content().toString(StandardCharsets.UTF_8); logger.log(Level.INFO, "status = " + resp.getStatus().getCode() +
logger.log(Level.INFO, "status = " + msg.status() + resp.getHeaders() + " " + resp.getBodyAsString(StandardCharsets.UTF_8));
msg.headers().entries() + " " + response);
}); });
client.execute(request).get(); client.execute(request).get();
} finally { } finally {

View file

@ -26,10 +26,8 @@ class Http2PushTest {
Request request = Request.builder(HttpMethod.GET) Request request = Request.builder(HttpMethod.GET)
.url(url).setVersion("HTTP/2.0") .url(url).setVersion("HTTP/2.0")
.build() .build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO,
msg.headers().entries() + "got response: " + resp.getHeaders() + " status=" + resp.getStatus()));
//msg.content().toString(StandardCharsets.UTF_8) +
" status=" + msg.status().code()));
client.execute(request).get(); client.execute(request).get();
} finally { } finally {

View file

@ -35,9 +35,8 @@ class PooledClientTest {
.setPoolNodeConnectionLimit(threads) .setPoolNodeConnectionLimit(threads)
.build(); .build();
AtomicInteger count = new AtomicInteger(); AtomicInteger count = new AtomicInteger();
ResponseListener responseListener = fullHttpResponse -> { ResponseListener responseListener = resp -> {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8); String response = resp.getBodyAsString(StandardCharsets.UTF_8);
//logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + response);
count.getAndIncrement(); count.getAndIncrement();
}; };
try { try {
@ -49,7 +48,6 @@ class PooledClientTest {
for (int i = 0; i < loop; i++) { for (int i = 0; i < loop; i++) {
Request request = Request.get().setVersion(httpAddress.getVersion()) Request request = Request.get().setVersion(httpAddress.getVersion())
.url(url.toString()) .url(url.toString())
//.setTimeoutInMillis(25000L)
.build() .build()
.setResponseListener(responseListener); .setResponseListener(responseListener);
client.newTransport().execute(request).get(); client.newTransport().execute(request).get();

View file

@ -36,18 +36,14 @@ class WebtideTest {
Request request1 = Request.builder(HttpMethod.GET) Request request1 = Request.builder(HttpMethod.GET)
.url("https://webtide.com").setVersion("HTTP/2.0") .url("https://webtide.com").setVersion("HTTP/2.0")
.build() .build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO, "got response: " +
msg.headers().entries() + resp.getHeaders() + " status=" + resp.getStatus()));
//msg.content().toString(StandardCharsets.UTF_8) +
" status=" + msg.status().code()));
Request request2 = Request.builder(HttpMethod.GET) Request request2 = Request.builder(HttpMethod.GET)
.url("https://webtide.com/why-choose-jetty/").setVersion("HTTP/2.0") .url("https://webtide.com/why-choose-jetty/").setVersion("HTTP/2.0")
.build() .build()
.setResponseListener(msg -> logger.log(Level.INFO, "got response: " + .setResponseListener(resp -> logger.log(Level.INFO, "got response: " +
msg.headers().entries() + resp.getHeaders() + " status=" +resp.getStatus()));
//msg.content().toString(StandardCharsets.UTF_8) +
" status=" + msg.status().code()));
client.execute(request1).execute(request2); client.execute(request1).execute(request2);
} finally { } finally {

View file

@ -0,0 +1,34 @@
package org.xbib.netty.http.common;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public class DefaultHttpHeaders implements HttpHeaders {
private final io.netty.handler.codec.http.HttpHeaders httpHeaders;
public DefaultHttpHeaders(io.netty.handler.codec.http.HttpHeaders headers) {
this.httpHeaders = headers;
}
@Override
public String getHeader(CharSequence header) {
return httpHeaders.get(header);
}
@Override
public List<String> getAllHeaders(CharSequence header) {
return httpHeaders.getAll(header);
}
@Override
public Iterator<Map.Entry<CharSequence, CharSequence>> iterator() {
return httpHeaders.iteratorCharSequence();
}
@Override
public String toString() {
return httpHeaders.entries().toString();
}
}

View file

@ -0,0 +1,56 @@
package org.xbib.netty.http.common;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.handler.codec.http.FullHttpResponse;
import java.io.InputStream;
import java.nio.charset.Charset;
public class DefaultHttpResponse implements HttpResponse {
private final HttpAddress httpAddress;
private final FullHttpResponse fullHttpResponse;
private final HttpStatus httpStatus;
private final HttpHeaders httpHeaders;
public DefaultHttpResponse(HttpAddress httpAddress, FullHttpResponse fullHttpResponse) {
this.httpAddress = httpAddress;
this.fullHttpResponse = fullHttpResponse;
this.httpStatus = new HttpStatus(fullHttpResponse.status());
this.httpHeaders = new DefaultHttpHeaders(fullHttpResponse.headers());
}
@Override
public HttpAddress getAddress() {
return httpAddress;
}
@Override
public HttpStatus getStatus() {
return httpStatus;
}
@Override
public HttpHeaders getHeaders() {
return httpHeaders;
}
@Override
public ByteBuf getBody() {
return fullHttpResponse.content().asReadOnly();
}
@Override
public InputStream getBodyAsStream() {
return new ByteBufInputStream(getBody());
}
@Override
public String getBodyAsString(Charset charset) {
return getBody().toString(charset);
}
}

View file

@ -0,0 +1,14 @@
package org.xbib.netty.http.common;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
public interface HttpHeaders {
String getHeader(CharSequence header);
List<String> getAllHeaders(CharSequence header);
Iterator<Map.Entry<CharSequence, CharSequence>> iterator();
}

View file

@ -1,6 +1,5 @@
package org.xbib.netty.http.common; package org.xbib.netty.http.common;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Map; import java.util.Map;
@ -21,7 +20,7 @@ public interface HttpRequest {
Map<String, String> getHeaders(); Map<String, String> getHeaders();
InputStream getContent() throws IOException; InputStream getContent();
String getContentType(); String getContentType();

View file

@ -1,13 +1,21 @@
package org.xbib.netty.http.common; package org.xbib.netty.http.common;
import java.io.IOException; import io.netty.buffer.ByteBuf;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.Charset;
public interface HttpResponse { public interface HttpResponse {
int getStatusCode() throws IOException; HttpAddress getAddress();
String getReason() throws Exception; HttpStatus getStatus();
InputStream getContent() throws IOException; HttpHeaders getHeaders();
ByteBuf getBody();
InputStream getBodyAsStream();
String getBodyAsString(Charset charset);
} }

View file

@ -0,0 +1,30 @@
package org.xbib.netty.http.common;
import io.netty.handler.codec.http.HttpResponseStatus;
public class HttpStatus {
private final HttpResponseStatus httpResponseStatus;
public HttpStatus(HttpResponseStatus httpResponseStatus) {
this.httpResponseStatus = httpResponseStatus;
}
public int getCode() {
return httpResponseStatus.code();
}
public String getMessage() {
return httpResponseStatus.codeAsText().toString();
}
public String getReasonPhrase() {
return httpResponseStatus.reasonPhrase();
}
@Override
public String toString() {
return httpResponseStatus.toString();
}
}

View file

@ -1,7 +1,7 @@
dependencies { dependencies {
compile project(':netty-http-server') compile project(':netty-http-server')
implementation "org.reactivestreams:reactive-streams:${project.property('reactivestreams.version')}" compile "org.reactivestreams:reactive-streams:${project.property('reactivestreams.version')}"
testImplementation("org.reactivestreams:reactive-streams-tck:${project.property('reactivestreams.version')}") { testCompile("org.reactivestreams:reactive-streams-tck:${project.property('reactivestreams.version')}") {
exclude module: 'testng' exclude module: 'testng'
} }
} }

View file

@ -1,6 +1,4 @@
dependencies { dependencies {
implementation project(":netty-http-server") compile project(":netty-http-server")
implementation "io.netty:netty-codec-http2:${project.property('netty.version')}" compile "org.xbib:guice:${project.property('xbib-guice.version')}"
implementation "org.xbib:net-url:${project.property('xbib-net-url.version')}"
implementation "org.xbib:guice:${project.property('xbib-guice.version')}"
} }

View file

@ -1,9 +1,7 @@
dependencies { dependencies {
compile project(":netty-http-common") compile project(":netty-http-common")
compile "io.netty:netty-handler:${project.property('netty.version')}"
compile "io.netty:netty-transport-native-epoll:${project.property('netty.version')}" compile "io.netty:netty-transport-native-epoll:${project.property('netty.version')}"
compile "io.netty:netty-tcnative-boringssl-static:${project.property('tcnative.version')}" compile "io.netty:netty-tcnative-boringssl-static:${project.property('tcnative.version')}"
compile "io.netty:netty-codec-http2:${project.property('netty.version')}"
compile "org.bouncycastle:bcpkix-jdk15on:${project.property('bouncycastle.version')}" compile "org.bouncycastle:bcpkix-jdk15on:${project.property('bouncycastle.version')}"
testImplementation project(":netty-http-client") testCompile project(":netty-http-client")
} }

View file

@ -43,9 +43,9 @@ class ClassloaderServiceTest {
Request request = Request.get().setVersion(HttpVersion.HTTP_1_1) Request request = Request.get().setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base().resolve("/classloader/test.txt")) .url(server.getServerConfig().getAddress().base().resolve("/classloader/test.txt"))
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
if (r.status().equals(HttpResponseStatus.OK)) { if (resp.getStatus().getCode() == HttpResponseStatus.OK.code()) {
assertEquals("Hello Jörg", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg", resp.getBodyAsString(StandardCharsets.UTF_8));
count.incrementAndGet(); count.incrementAndGet();
} }
}); });

View file

@ -9,10 +9,10 @@ import org.xbib.netty.http.client.Request;
import org.xbib.netty.http.client.listener.ResponseListener; import org.xbib.netty.http.client.listener.ResponseListener;
import org.xbib.netty.http.client.transport.Transport; import org.xbib.netty.http.client.transport.Transport;
import org.xbib.netty.http.common.HttpAddress; import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.netty.http.server.Server; import org.xbib.netty.http.server.Server;
import org.xbib.netty.http.server.Domain; import org.xbib.netty.http.server.Domain;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -41,10 +41,8 @@ class CleartextHttp1Test {
Client client = Client.builder() Client client = Client.builder()
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
final ResponseListener responseListener = fullHttpResponse -> { final ResponseListener<HttpResponse> responseListener = resp -> {
if (fullHttpResponse.status().equals(HttpResponseStatus.OK)) { if (resp.getStatus().getCode() == HttpResponseStatus.OK.code()) {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
//logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + response);
counter.incrementAndGet(); counter.incrementAndGet();
} }
}; };
@ -79,10 +77,8 @@ class CleartextHttp1Test {
.setPoolNodeConnectionLimit(2) .setPoolNodeConnectionLimit(2)
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
final ResponseListener responseListener = fullHttpResponse -> { final ResponseListener<HttpResponse> responseListener = resp -> {
if (fullHttpResponse.status().equals(HttpResponseStatus.OK)) { if (resp.getStatus().getCode() == HttpResponseStatus.OK.code()) {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
//logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + response);
counter.incrementAndGet(); counter.incrementAndGet();
} }
}; };
@ -126,11 +122,8 @@ class CleartextHttp1Test {
.setPoolNodeConnectionLimit(threads) .setPoolNodeConnectionLimit(threads)
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
final ResponseListener responseListener = fullHttpResponse -> { final ResponseListener<HttpResponse> responseListener = resp -> {
if (fullHttpResponse.status().equals(HttpResponseStatus.OK)) { if (resp.getStatus().getCode() == HttpResponseStatus.OK.code()) {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
//logger.log(Level.INFO, "status = " + fullHttpResponse.status() +
// " response=" + response + " payload=" + payload);
counter.incrementAndGet(); counter.incrementAndGet();
} }
}; };

View file

@ -8,6 +8,7 @@ import org.xbib.netty.http.client.Request;
import org.xbib.netty.http.client.listener.ResponseListener; import org.xbib.netty.http.client.listener.ResponseListener;
import org.xbib.netty.http.client.transport.Transport; import org.xbib.netty.http.client.transport.Transport;
import org.xbib.netty.http.common.HttpAddress; import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.netty.http.server.Server; import org.xbib.netty.http.server.Server;
import org.xbib.netty.http.server.ServerResponse; import org.xbib.netty.http.server.ServerResponse;
import org.xbib.netty.http.server.Domain; import org.xbib.netty.http.server.Domain;
@ -43,10 +44,9 @@ class CleartextHttp2Test {
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
// a single instance of HTTP/2 response listener, always receives responses out-of-order // a single instance of HTTP/2 response listener, always receives responses out-of-order
ResponseListener responseListener = fullHttpResponse -> { ResponseListener<HttpResponse> responseListener = resp -> {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8); logger.log(Level.INFO, "response listener: headers = " + resp.getHeaders() +
logger.log(Level.INFO, "response listener: headers = " + fullHttpResponse.headers().entries() + " response body = " + resp.getBodyAsString(StandardCharsets.UTF_8));
" response body = " + response);
counter.incrementAndGet(); counter.incrementAndGet();
}; };
try { try {
@ -87,17 +87,12 @@ class CleartextHttp2Test {
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
// a single instance of HTTP/2 response listener, always receives responses out-of-order // a single instance of HTTP/2 response listener, always receives responses out-of-order
final ResponseListener responseListener = fullHttpResponse -> { final ResponseListener<HttpResponse> responseListener = resp -> counter.incrementAndGet();
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
//logger.log(Level.INFO, "response listener: headers = " + fullHttpResponse.headers().entries() +
// " response body = " + response);
counter.incrementAndGet();
};
try { try {
// single transport, single thread // single transport, single thread
Transport transport = client.newTransport(); Transport transport = client.newTransport();
for (int i = 0; i < loop; i++) { for (int i = 0; i < loop; i++) {
String payload = Integer.toString(0) + "/" + Integer.toString(i); String payload = 0 + "/" + i;
Request request = Request.get().setVersion("HTTP/2.0") Request request = Request.get().setVersion("HTTP/2.0")
.url(server.getServerConfig().getAddress().base()) .url(server.getServerConfig().getAddress().base())
.content(payload, "text/plain") .content(payload, "text/plain")
@ -136,12 +131,7 @@ class CleartextHttp2Test {
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
// a HTTP/2 listener always receives responses out-of-order // a HTTP/2 listener always receives responses out-of-order
final ResponseListener responseListener = fullHttpResponse -> { final ResponseListener<HttpResponse> responseListener = resp -> counter.incrementAndGet();
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
//logger.log(Level.INFO, "response listener: headers = " + fullHttpResponse.headers().entries() +
// " response body = " + response);
counter.incrementAndGet();
};
try { try {
// note: for HTTP/2 only, we can use a single shared transport // note: for HTTP/2 only, we can use a single shared transport
final Transport transport = client.newTransport(); final Transport transport = client.newTransport();
@ -214,12 +204,7 @@ class CleartextHttp2Test {
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
// a single instance of HTTP/2 response listener, always receives responses out-of-order // a single instance of HTTP/2 response listener, always receives responses out-of-order
final ResponseListener responseListener = fullHttpResponse -> { final ResponseListener<HttpResponse> responseListener = resp -> counter.incrementAndGet();
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
//logger.log(Level.INFO, "response listener: headers = " + fullHttpResponse.headers().entries() +
// " response body = " + response);
counter.incrementAndGet();
};
try { try {
// note: for HTTP/2 only, we can use a single shared transport // note: for HTTP/2 only, we can use a single shared transport
final Transport transport = client.newTransport(); final Transport transport = client.newTransport();

View file

@ -59,8 +59,8 @@ class EndpointTest {
Request request = Request.get().setVersion(HttpVersion.HTTP_1_1) Request request = Request.get().setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base().resolve("/test.txt")) .url(server.getServerConfig().getAddress().base().resolve("/test.txt"))
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
assertEquals("Hello Jörg", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg", resp.getBodyAsString(StandardCharsets.UTF_8));
success.set(true); success.set(true);
}); });
client.execute(request).get(); client.execute(request).get();
@ -99,8 +99,8 @@ class EndpointTest {
Request request = Request.get().setVersion(HttpVersion.HTTP_1_1) Request request = Request.get().setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base().resolve("/test.txt")) .url(server.getServerConfig().getAddress().base().resolve("/test.txt"))
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
assertEquals("Hello Jörg", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg", resp.getBodyAsString(StandardCharsets.UTF_8));
success.set(true); success.set(true);
}); });
client.execute(request).get(); client.execute(request).get();
@ -146,24 +146,24 @@ class EndpointTest {
Request request = Request.get().setVersion(HttpVersion.HTTP_1_1) Request request = Request.get().setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base().resolve("/static/test.txt")) .url(server.getServerConfig().getAddress().base().resolve("/static/test.txt"))
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
assertEquals("Hello Jörg", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg", resp.getBodyAsString(StandardCharsets.UTF_8));
success.set(true); success.set(true);
}); });
client.execute(request).get(); client.execute(request).get();
Request request1 = Request.get().setVersion(HttpVersion.HTTP_1_1) Request request1 = Request.get().setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base().resolve("/static1/test1.txt")) .url(server.getServerConfig().getAddress().base().resolve("/static1/test1.txt"))
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
assertEquals("Hello Jörg 1", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg 1",resp.getBodyAsString(StandardCharsets.UTF_8));
success1.set(true); success1.set(true);
}); });
client.execute(request1).get(); client.execute(request1).get();
Request request2 = Request.get().setVersion(HttpVersion.HTTP_1_1) Request request2 = Request.get().setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base().resolve("/static2/test2.txt")) .url(server.getServerConfig().getAddress().base().resolve("/static2/test2.txt"))
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
assertEquals("Hello Jörg 2", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg 2", resp.getBodyAsString(StandardCharsets.UTF_8));
success2.set(true); success2.set(true);
}); });
client.execute(request2).get(); client.execute(request2).get();
@ -214,12 +214,12 @@ class EndpointTest {
.url(server.getServerConfig().getAddress().base().resolve("/static/test.txt")) .url(server.getServerConfig().getAddress().base().resolve("/static/test.txt"))
.addParameter("a", "b") .addParameter("a", "b")
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
if (r.status().equals(HttpResponseStatus.OK)) { if (resp.getStatus().getCode() == HttpResponseStatus.OK.code()) {
assertEquals("Hello Jörg", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg", resp.getBodyAsString(StandardCharsets.UTF_8));
success.set(true); success.set(true);
} else { } else {
logger.log(Level.WARNING, r.toString()); logger.log(Level.WARNING, resp.getStatus().getReasonPhrase());
} }
}); });
client.execute(request).get(); client.execute(request).get();
@ -227,12 +227,12 @@ class EndpointTest {
.url(server.getServerConfig().getAddress().base() .url(server.getServerConfig().getAddress().base()
.resolve("/static1/test1.txt").newBuilder().fragment("frag").build()) .resolve("/static1/test1.txt").newBuilder().fragment("frag").build())
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
if (r.status().equals(HttpResponseStatus.OK)) { if (resp.getStatus().getCode() == HttpResponseStatus.OK.code()) {
assertEquals("Hello Jörg 1", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg 1", resp.getBodyAsString(StandardCharsets.UTF_8));
success1.set(true); success1.set(true);
} else { } else {
logger.log(Level.WARNING, r.toString()); logger.log(Level.WARNING, resp.getStatus().getReasonPhrase());
} }
}); });
client.execute(request1).get(); client.execute(request1).get();
@ -240,12 +240,12 @@ class EndpointTest {
.url(server.getServerConfig().getAddress().base().resolve("/static2/test2.txt")) .url(server.getServerConfig().getAddress().base().resolve("/static2/test2.txt"))
.content("{\"a\":\"b\"}","application/json") .content("{\"a\":\"b\"}","application/json")
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
if (r.status().equals(HttpResponseStatus.OK)) { if (resp.getStatus().getCode() == HttpResponseStatus.OK.code()) {
assertEquals("Hello Jörg 2", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg 2",resp.getBodyAsString(StandardCharsets.UTF_8));
success2.set(true); success2.set(true);
} else { } else {
logger.log(Level.WARNING, r.toString()); logger.log(Level.WARNING, resp.getStatus().getReasonPhrase());
} }
}); });
client.execute(request2).get(); client.execute(request2).get();
@ -288,11 +288,11 @@ class EndpointTest {
Request request = Request.get().setVersion(HttpVersion.HTTP_1_1) Request request = Request.get().setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base().resolve("/static/" + i + "/test.txt")) .url(server.getServerConfig().getAddress().base().resolve("/static/" + i + "/test.txt"))
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
if (r.status().equals(HttpResponseStatus.OK)) { if (resp.getStatus().getCode() == HttpResponseStatus.OK.code()) {
count.incrementAndGet(); count.incrementAndGet();
} else { } else {
logger.log(Level.WARNING, r.status().reasonPhrase()); logger.log(Level.WARNING, resp.getStatus().getReasonPhrase());
} }
}); });
client.execute(request).get(); client.execute(request).get();

View file

@ -44,8 +44,8 @@ class FileServiceTest {
Request request = Request.get().setVersion(HttpVersion.HTTP_1_1) Request request = Request.get().setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base().resolve("/static/test.txt")) .url(server.getServerConfig().getAddress().base().resolve("/static/test.txt"))
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
assertEquals("Hello Jörg", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg", resp.getBodyAsString(StandardCharsets.UTF_8));
success.set(true); success.set(true);
}); });
logger.log(Level.INFO, request.toString()); logger.log(Level.INFO, request.toString());
@ -79,8 +79,8 @@ class FileServiceTest {
.setVersion(HttpVersion.valueOf("HTTP/2.0")) .setVersion(HttpVersion.valueOf("HTTP/2.0"))
.url(server.getServerConfig().getAddress().base().resolve("/static/test.txt")) .url(server.getServerConfig().getAddress().base().resolve("/static/test.txt"))
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
assertEquals("Hello Jörg", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg", resp.getBodyAsString(StandardCharsets.UTF_8));
success.set(true); success.set(true);
}); });
logger.log(Level.INFO, request.toString()); logger.log(Level.INFO, request.toString());

View file

@ -45,8 +45,8 @@ class PostTest {
.addParameter("a", "b") .addParameter("a", "b")
.addFormParameter("name", "Jörg") .addFormParameter("name", "Jörg")
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
if (r.status().equals(HttpResponseStatus.OK)) { if (resp.getStatus().getCode() == HttpResponseStatus.OK.code()) {
success.set(true); success.set(true);
} }
}); });
@ -83,8 +83,8 @@ class PostTest {
.addParameter("a", "b") .addParameter("a", "b")
.addFormParameter("name", "Jörg") .addFormParameter("name", "Jörg")
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
if (r.status().equals(HttpResponseStatus.OK)) { if (resp.getStatus().getCode() == HttpResponseStatus.OK.code()) {
success.set(true); success.set(true);
} }
}); });

View file

@ -53,8 +53,8 @@ class SecureFileServiceTest {
.setVersion(HttpVersion.HTTP_1_1) .setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base().resolve("/static/test.txt")) .url(server.getServerConfig().getAddress().base().resolve("/static/test.txt"))
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
assertEquals("Hello Jörg", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg", resp.getBodyAsString(StandardCharsets.UTF_8));
success.set(true); success.set(true);
}); });
logger.log(Level.INFO, request.toString()); logger.log(Level.INFO, request.toString());
@ -94,8 +94,8 @@ class SecureFileServiceTest {
.setVersion(HttpVersion.valueOf("HTTP/2.0")) .setVersion(HttpVersion.valueOf("HTTP/2.0"))
.url(server.getServerConfig().getAddress().base().resolve("/static/test.txt")) .url(server.getServerConfig().getAddress().base().resolve("/static/test.txt"))
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
assertEquals("Hello Jörg", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg", resp.getBodyAsString(StandardCharsets.UTF_8));
success.set(true); success.set(true);
}); });
logger.log(Level.INFO, request.toString()); logger.log(Level.INFO, request.toString());
@ -136,8 +136,8 @@ class SecureFileServiceTest {
.setVersion(HttpVersion.HTTP_1_1) .setVersion(HttpVersion.HTTP_1_1)
.url(server.getServerConfig().getAddress().base().resolve("/static/test.txt")) .url(server.getServerConfig().getAddress().base().resolve("/static/test.txt"))
.build() .build()
.setResponseListener(r -> { .setResponseListener(resp -> {
assertEquals("Hello Jörg", r.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello Jörg", resp.getBodyAsString(StandardCharsets.UTF_8));
success.set(true); success.set(true);
}); });
logger.log(Level.INFO, request.toString()); logger.log(Level.INFO, request.toString());

View file

@ -9,11 +9,11 @@ import org.xbib.netty.http.client.Request;
import org.xbib.netty.http.client.listener.ResponseListener; import org.xbib.netty.http.client.listener.ResponseListener;
import org.xbib.netty.http.client.transport.Transport; import org.xbib.netty.http.client.transport.Transport;
import org.xbib.netty.http.common.HttpAddress; import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.netty.http.server.Server; import org.xbib.netty.http.server.Server;
import org.xbib.netty.http.server.Domain; import org.xbib.netty.http.server.Domain;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -43,11 +43,7 @@ class SecureHttp1Test {
.trustInsecure() .trustInsecure()
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
final ResponseListener responseListener = fullHttpResponse -> { final ResponseListener<HttpResponse> responseListener = resp -> counter.getAndIncrement();
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
//logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + response);
counter.getAndIncrement();
};
try { try {
server.accept(); server.accept();
Request request = Request.get().setVersion(HttpVersion.HTTP_1_1) Request request = Request.get().setVersion(HttpVersion.HTTP_1_1)
@ -81,11 +77,7 @@ class SecureHttp1Test {
.setPoolNodeConnectionLimit(2) .setPoolNodeConnectionLimit(2)
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
final ResponseListener responseListener = fullHttpResponse -> { final ResponseListener<HttpResponse> responseListener = resp -> counter.incrementAndGet();
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
//logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + response);
counter.incrementAndGet();
};
try { try {
for (int i = 0; i < loop; i++) { for (int i = 0; i < loop; i++) {
Request request = Request.get().setVersion(HttpVersion.HTTP_1_1) Request request = Request.get().setVersion(HttpVersion.HTTP_1_1)
@ -129,12 +121,7 @@ class SecureHttp1Test {
.setPoolNodeConnectionLimit(threads) .setPoolNodeConnectionLimit(threads)
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
final ResponseListener responseListener = fullHttpResponse -> { final ResponseListener<HttpResponse> responseListener = resp -> counter.incrementAndGet();
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
//logger.log(Level.INFO, "response listener: headers = " + fullHttpResponse.headers().entries() +
// " response body = " + response);
counter.incrementAndGet();
};
try { try {
ExecutorService executorService = Executors.newFixedThreadPool(threads); ExecutorService executorService = Executors.newFixedThreadPool(threads);
for (int n = 0; n < threads; n++) { for (int n = 0; n < threads; n++) {

View file

@ -8,6 +8,7 @@ import org.xbib.netty.http.client.Request;
import org.xbib.netty.http.client.listener.ResponseListener; import org.xbib.netty.http.client.listener.ResponseListener;
import org.xbib.netty.http.client.transport.Transport; import org.xbib.netty.http.client.transport.Transport;
import org.xbib.netty.http.common.HttpAddress; import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.netty.http.server.Server; import org.xbib.netty.http.server.Server;
import org.xbib.netty.http.server.Domain; import org.xbib.netty.http.server.Domain;
@ -44,10 +45,9 @@ class SecureHttp2Test {
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
// a single instance of HTTP/2 response listener, always receives responses out-of-order // a single instance of HTTP/2 response listener, always receives responses out-of-order
final ResponseListener responseListener = fullHttpResponse -> { final ResponseListener<HttpResponse> responseListener = resp -> {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8); logger.log(Level.INFO, "response listener: headers = " + resp.getHeaders() +
logger.log(Level.INFO, "response listener: headers = " + fullHttpResponse.headers().entries() + " response body = " + resp.getBodyAsString(StandardCharsets.UTF_8));
" response body = " + response);
counter.incrementAndGet(); counter.incrementAndGet();
}; };
try { try {
@ -89,17 +89,12 @@ class SecureHttp2Test {
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
// a single instance of HTTP/2 response listener, always receives responses out-of-order // a single instance of HTTP/2 response listener, always receives responses out-of-order
final ResponseListener responseListener = fullHttpResponse -> { final ResponseListener<HttpResponse> responseListener = resp -> counter.incrementAndGet();
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
//logger.log(Level.INFO, "response listener: headers = " + fullHttpResponse.headers().entries() +
// " response body = " + response);
counter.incrementAndGet();
};
try { try {
// single transport, single thread // single transport, single thread
Transport transport = client.newTransport(); Transport transport = client.newTransport();
for (int i = 0; i < loop; i++) { for (int i = 0; i < loop; i++) {
String payload = Integer.toString(0) + "/" + Integer.toString(i); String payload = 0 + "/" + i;
Request request = Request.get().setVersion("HTTP/2.0") Request request = Request.get().setVersion("HTTP/2.0")
.url(server.getServerConfig().getAddress().base()) .url(server.getServerConfig().getAddress().base())
.content(payload, "text/plain") .content(payload, "text/plain")
@ -141,12 +136,7 @@ class SecureHttp2Test {
.build(); .build();
AtomicInteger counter = new AtomicInteger(); AtomicInteger counter = new AtomicInteger();
// a HTTP/2 listener always receives responses out-of-order // a HTTP/2 listener always receives responses out-of-order
final ResponseListener responseListener = fullHttpResponse -> { final ResponseListener<HttpResponse> responseListener = resp -> counter.incrementAndGet();
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
//logger.log(Level.INFO, "response listener: headers = " + fullHttpResponse.headers().entries() +
// " response body = " + response);
counter.incrementAndGet();
};
try { try {
// note: for HTTP/2 only, we can use a single shared transport // note: for HTTP/2 only, we can use a single shared transport
final Transport transport = client.newTransport(); final Transport transport = client.newTransport();

View file

@ -47,9 +47,9 @@ class StreamTest {
.url(server.getServerConfig().getAddress().base().resolve("/")) .url(server.getServerConfig().getAddress().base().resolve("/"))
.content("my body parameter", "text/plain") .content("my body parameter", "text/plain")
.build() .build()
.setResponseListener(response -> { .setResponseListener(resp -> {
if (response.status().equals(HttpResponseStatus.OK)) { if (resp.getStatus().getCode() == HttpResponseStatus.OK.code()) {
assertEquals("Hello World", response.content().toString(StandardCharsets.UTF_8)); assertEquals("Hello World", resp.getBodyAsString(StandardCharsets.UTF_8));
count.incrementAndGet(); count.incrementAndGet();
} }
}); });

View file

@ -1,5 +1,6 @@
include 'netty-http-common' include 'netty-http-common'
include 'netty-http-client' include 'netty-http-client'
include 'netty-http-client-rest'
include 'netty-http-server' include 'netty-http-server'
include 'netty-http-server-reactive' include 'netty-http-server-reactive'
include 'netty-http-server-rest' include 'netty-http-server-rest'