convenience API methods, checkstyle and findbug fixes

This commit is contained in:
Jörg Prante 2017-05-12 01:06:09 +02:00
parent 8f1a7211e6
commit 741228dd76
16 changed files with 164 additions and 96 deletions

View file

@ -56,10 +56,10 @@ page at http://checkstyle.sourceforge.net/config.html -->
<!-- Checks for out of order import statements. -->
<property name="severity" value="warning"/>
<property name="groups" value="com,io,junit,net,org,java,javax"/>
<property name="groups" value="com,io,junit,net,org,javax,java"/>
<!-- This ensures that static imports go last. -->
<property name="option" value="under"/>
<property name="tokens" value="STATIC_IMPORT, IMPORT"/>
<property name="tokens" value="IMPORT, STATIC_IMPORT"/>
</module>
<!--

View file

@ -41,10 +41,6 @@ import io.netty.handler.codec.http2.HttpConversionUtil;
import java.util.logging.Level;
import java.util.logging.Logger;
import static io.netty.handler.codec.http2.Http2Error.INTERNAL_ERROR;
import static io.netty.handler.codec.http2.Http2Error.PROTOCOL_ERROR;
import static io.netty.handler.codec.http2.Http2Exception.connectionError;
/**
* A HTTP/2 event adapter for a client.
* This event adapter expects {@link Http2Settings} are sent from the server before the
@ -80,7 +76,7 @@ public class Http2EventHandler extends Http2EventAdapter {
/**
* Handles an inbound {@code SETTINGS} frame.
* After frame is received, the reuqets is sent.
* After frame is received, the request is sent.
*
* @param ctx the context from the handler where the frame was read.
* @param settings the settings received from the remote endpoint.
@ -214,12 +210,13 @@ public class Http2EventHandler extends Http2EventAdapter {
Http2Stream stream = connection.stream(streamId);
FullHttpMessage msg = getMessage(stream);
if (msg == null) {
throw connectionError(PROTOCOL_ERROR, "data frame received for unknown stream id %d", streamId);
throw Http2Exception.connectionError(Http2Error.PROTOCOL_ERROR,
"data frame received for unknown stream id %d", streamId);
}
ByteBuf content = msg.content();
final int dataReadableBytes = data.readableBytes();
if (content.readableBytes() > maxContentLength - dataReadableBytes) {
throw connectionError(INTERNAL_ERROR,
throw Http2Exception.connectionError(Http2Error.INTERNAL_ERROR,
"content length exceeded maximum of %d for stream id %d", maxContentLength, streamId);
}
content.writeBytes(data, data.readerIndex(), dataReadableBytes);
@ -349,7 +346,7 @@ public class Http2EventHandler extends Http2EventAdapter {
}
}
/**
* The stream is out of scope for the HTTP message flow and will no longer be tracked
* The stream is out of scope for the HTTP message flow and will no longer be tracked.
* @param stream The stream to remove associated state with
* @param release {@code true} to call release on the value if it is present. {@code false} to not call release.
*/
@ -361,7 +358,7 @@ public class Http2EventHandler extends Http2EventAdapter {
}
/**
* Set final headers and fire a channel read event
* Set final headers and fire a channel read event.
*
* @param ctx The context to fire the event on
* @param msg The message to send
@ -390,8 +387,7 @@ public class Http2EventHandler extends Http2EventAdapter {
return msg;
}
private void endHeader(ChannelHandlerContext ctx, Http2Stream stream, FullHttpMessage msg,
boolean endOfStream) {
private void endHeader(ChannelHandlerContext ctx, Http2Stream stream, FullHttpMessage msg, boolean endOfStream) {
if (endOfStream) {
fireChannelRead(ctx, msg, getMessage(stream) != msg, stream);
} else {

View file

@ -35,12 +35,13 @@ import io.netty.handler.codec.http.HttpResponse;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.cookie.ClientCookieEncoder;
import io.netty.handler.codec.http.cookie.Cookie;
import io.netty.handler.ssl.OpenSsl;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.FutureListener;
import org.xbib.netty.http.client.listener.CookieListener;
import org.xbib.netty.http.client.listener.ExceptionListener;
import org.xbib.netty.http.client.listener.HttpPushListener;
import org.xbib.netty.http.client.listener.HttpHeadersListener;
import org.xbib.netty.http.client.listener.HttpPushListener;
import org.xbib.netty.http.client.listener.HttpResponseListener;
import org.xbib.netty.http.client.util.InetAddressKey;
import org.xbib.netty.http.client.util.NetworkUtils;
@ -66,6 +67,8 @@ public final class HttpClient implements Closeable {
private static final AtomicInteger streamId = new AtomicInteger(3);
private static final HttpClient INSTANCE = HttpClient.builder().build();
private final ByteBufAllocator byteBufAllocator;
private final EventLoopGroup eventLoopGroup;
@ -83,11 +86,16 @@ public final class HttpClient implements Closeable {
this.byteBufAllocator = byteBufAllocator;
this.eventLoopGroup = eventLoopGroup;
this.poolMap = new HttpClientChannelPoolMap(this, httpClientChannelContext, bootstrap, maxConnections);
logger.log(Level.FINE, () -> "OpenSSL ALPN support: " + OpenSsl.isAlpnSupported());
NetworkUtils.extendSystemProperties();
logger.log(Level.FINE, () -> "local host name = " + NetworkUtils.getLocalHostName("localhost"));
logger.log(Level.FINE, NetworkUtils::displayNetworkInterfaces);
}
public static HttpClient getInstance() {
return INSTANCE;
}
/**
* Create a builder to configure connecting.
*
@ -106,73 +114,105 @@ public final class HttpClient implements Closeable {
*
* @return a request builder
*/
public HttpClientRequestBuilder prepareGet() {
public HttpRequestBuilder prepareGet() {
return prepareRequest(HttpMethod.GET);
}
public HttpRequestBuilder prepareGet(String url) {
return prepareRequest(HttpMethod.GET).setURL(url);
}
/**
* Prepare a HTTP HEAD request.
*
* @return a request builder
*/
public HttpClientRequestBuilder prepareHead() {
public HttpRequestBuilder prepareHead() {
return prepareRequest(HttpMethod.HEAD);
}
public HttpRequestBuilder prepareHead(String url) {
return prepareRequest(HttpMethod.HEAD).setURL(url);
}
/**
* Prepare a HTTP PUT request.
*
* @return a request builder
*/
public HttpClientRequestBuilder preparePut() {
public HttpRequestBuilder preparePut() {
return prepareRequest(HttpMethod.PUT);
}
public HttpRequestBuilder preparePut(String url) {
return prepareRequest(HttpMethod.PUT).setURL(url);
}
/**
* Prepare a HTTP POST request.
*
* @return a request builder
*/
public HttpClientRequestBuilder preparePost() {
public HttpRequestBuilder preparePost() {
return prepareRequest(HttpMethod.POST);
}
public HttpRequestBuilder preparePost(String url) {
return prepareRequest(HttpMethod.POST).setURL(url);
}
/**
* Prepare a HTTP DELETE request.
*
* @return a request builder
*/
public HttpClientRequestBuilder prepareDelete() {
public HttpRequestBuilder prepareDelete() {
return prepareRequest(HttpMethod.DELETE);
}
public HttpRequestBuilder prepareDelete(String url) {
return prepareRequest(HttpMethod.DELETE).setURL(url);
}
/**
* Prepare a HTTP OPTIONS request.
*
* @return a request builder
*/
public HttpClientRequestBuilder prepareOptions() {
public HttpRequestBuilder prepareOptions() {
return prepareRequest(HttpMethod.OPTIONS);
}
public HttpRequestBuilder prepareOptions(String url) {
return prepareRequest(HttpMethod.OPTIONS).setURL(url);
}
/**
* Prepare a HTTP PATCH request.
*
* @return a request builder
*/
public HttpClientRequestBuilder preparePatch() {
public HttpRequestBuilder preparePatch() {
return prepareRequest(HttpMethod.PATCH);
}
public HttpRequestBuilder preparePatch(String url) {
return prepareRequest(HttpMethod.PATCH).setURL(url);
}
/**
* Prepare a HTTP TRACE request.
*
* @return a request builder
*/
public HttpClientRequestBuilder prepareTrace() {
public HttpRequestBuilder prepareTrace() {
return prepareRequest(HttpMethod.TRACE);
}
public HttpRequestBuilder prepareTrace(String url) {
return prepareRequest(HttpMethod.TRACE).setURL(url);
}
public HttpClientChannelPoolMap poolMap() {
return poolMap;
}
@ -258,7 +298,8 @@ public final class HttpClient implements Closeable {
} else if (httpRequest.protocolVersion().majorVersion() == 2) {
logger.log(Level.FINE, () -> "waiting for HTTP/2 settings");
settingsPromise.await(httpRequestContext.getTimeout(), TimeUnit.MILLISECONDS);
logger.log(Level.FINE, () -> "waiting for HTTP/2 responses = " + httpRequestContext.getStreamIdPromiseMap().size());
logger.log(Level.FINE, () -> "waiting for HTTP/2 responses = " +
httpRequestContext.getStreamIdPromiseMap().size());
int timeout = httpRequestContext.getTimeout();
for (Map.Entry<Integer, Map.Entry<ChannelFuture, ChannelPromise>> entry :
httpRequestContext.getStreamIdPromiseMap().entrySet()) {
@ -267,12 +308,13 @@ public final class HttpClient implements Closeable {
logger.log(Level.FINE, "waiting for channel, stream ID = " + entry.getKey());
if (!channelFuture.awaitUninterruptibly(timeout, TimeUnit.MILLISECONDS)) {
IllegalStateException illegalStateException =
new IllegalStateException("time out while waiting to write for stream id " + entry.getKey());
new IllegalStateException("time out while waiting to write for stream id " +
entry.getKey());
if (exceptionListener != null) {
exceptionListener.onException(illegalStateException);
httpRequestContext.fail(illegalStateException.getMessage());
final ChannelPool channelPool =
channelFuture.channel().attr(HttpClientChannelContext.CHANNEL_POOL_ATTRIBUTE_KEY).get();
final ChannelPool channelPool = channelFuture.channel()
.attr(HttpClientChannelContext.CHANNEL_POOL_ATTRIBUTE_KEY).get();
channelPool.release(channelFuture.channel());
}
throw illegalStateException;
@ -285,13 +327,14 @@ public final class HttpClient implements Closeable {
logger.log(Level.FINE, "waiting for promise of stream ID = " + entry.getKey());
if (!promise.awaitUninterruptibly(timeout, TimeUnit.MILLISECONDS)) {
IllegalStateException illegalStateException =
new IllegalStateException("time out while waiting for response on stream id " + entry.getKey());
new IllegalStateException("time out while waiting for response on stream id " +
entry.getKey());
if (exceptionListener != null) {
exceptionListener.onException(illegalStateException);
httpRequestContext.fail(illegalStateException.getMessage());
if (channelFuture != null) {
final ChannelPool channelPool =
channelFuture.channel().attr(HttpClientChannelContext.CHANNEL_POOL_ATTRIBUTE_KEY).get();
final ChannelPool channelPool = channelFuture.channel()
.attr(HttpClientChannelContext.CHANNEL_POOL_ATTRIBUTE_KEY).get();
channelPool.release(channelFuture.channel());
}
}
@ -303,8 +346,8 @@ public final class HttpClient implements Closeable {
exceptionListener.onException(runtimeException);
httpRequestContext.fail(runtimeException.getMessage());
if (channelFuture != null) {
final ChannelPool channelPool =
channelFuture.channel().attr(HttpClientChannelContext.CHANNEL_POOL_ATTRIBUTE_KEY).get();
final ChannelPool channelPool = channelFuture.channel()
.attr(HttpClientChannelContext.CHANNEL_POOL_ATTRIBUTE_KEY).get();
channelPool.release(channelFuture.channel());
}
}

View file

@ -30,9 +30,9 @@ import io.netty.handler.ssl.CipherSuiteFilter;
import io.netty.handler.ssl.SslProvider;
import org.xbib.netty.http.client.util.ClientAuthMode;
import javax.net.ssl.TrustManagerFactory;
import java.io.InputStream;
import java.net.InetSocketAddress;
import javax.net.ssl.TrustManagerFactory;
/**
*

View file

@ -24,13 +24,13 @@ import io.netty.handler.ssl.SslProvider;
import io.netty.util.AttributeKey;
import org.xbib.netty.http.client.listener.CookieListener;
import org.xbib.netty.http.client.listener.ExceptionListener;
import org.xbib.netty.http.client.listener.HttpPushListener;
import org.xbib.netty.http.client.listener.HttpHeadersListener;
import org.xbib.netty.http.client.listener.HttpPushListener;
import org.xbib.netty.http.client.listener.HttpResponseListener;
import org.xbib.netty.http.client.util.ClientAuthMode;
import java.io.InputStream;
import javax.net.ssl.TrustManagerFactory;
import java.io.InputStream;
/**
*/

View file

@ -21,8 +21,8 @@ import io.netty.handler.ssl.OpenSsl;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import org.xbib.netty.http.client.util.InetAddressKey;
import org.xbib.netty.http.client.util.ClientAuthMode;
import org.xbib.netty.http.client.util.InetAddressKey;
import javax.net.ssl.TrustManagerFactory;

View file

@ -50,15 +50,15 @@ import io.netty.handler.timeout.ReadTimeoutHandler;
import org.xbib.netty.http.client.listener.ExceptionListener;
import org.xbib.netty.http.client.util.InetAddressKey;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.net.ssl.SNIHostName;
import javax.net.ssl.SNIServerName;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLParameters;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Netty HTTP client channel initializer.
@ -259,7 +259,7 @@ class HttpClientChannelInitializer extends ChannelInitializer<SocketChannel> {
}
@Sharable
private class UpgradeRequestHandler extends ChannelInboundHandlerAdapter {
private static class UpgradeRequestHandler extends ChannelInboundHandlerAdapter {
/**
* Send an upgrade request if channel becomes active.
@ -299,7 +299,7 @@ class HttpClientChannelInitializer extends ChannelInitializer<SocketChannel> {
* A Netty handler that logs user events and find expetced ones.
*/
@Sharable
private class UserEventLogger extends ChannelInboundHandlerAdapter {
private static class UserEventLogger extends ChannelInboundHandlerAdapter {
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
@ -319,7 +319,7 @@ class HttpClientChannelInitializer extends ChannelInitializer<SocketChannel> {
* A Netty handler that logs the I/O traffic of a connection.
*/
@Sharable
private final class TrafficLoggingHandler extends LoggingHandler {
private static class TrafficLoggingHandler extends LoggingHandler {
TrafficLoggingHandler() {
super("client", LogLevel.TRACE);

View file

@ -2,6 +2,7 @@ package org.xbib.netty.http.client;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.UnpooledByteBufAllocator;
import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.DefaultHttpRequest;
@ -19,8 +20,8 @@ import io.netty.util.AsciiString;
import io.netty.util.CharsetUtil;
import org.xbib.netty.http.client.listener.CookieListener;
import org.xbib.netty.http.client.listener.ExceptionListener;
import org.xbib.netty.http.client.listener.HttpPushListener;
import org.xbib.netty.http.client.listener.HttpHeadersListener;
import org.xbib.netty.http.client.listener.HttpPushListener;
import org.xbib.netty.http.client.listener.HttpResponseListener;
import java.io.IOException;
@ -50,6 +51,8 @@ public class HttpClientRequestBuilder implements HttpRequestBuilder, HttpRequest
private static final Logger logger = Logger.getLogger(HttpClientRequestBuilder.class.getName());
private static final HttpVersion HTTP_2_0 = HttpVersion.valueOf("HTTP/2.0");
private final HttpClient httpClient;
private final ByteBufAllocator byteBufAllocator;
@ -96,6 +99,11 @@ public class HttpClientRequestBuilder implements HttpRequestBuilder, HttpRequest
private HttpPushListener httpPushListener;
HttpClientRequestBuilder(HttpMethod httpMethod,
ByteBufAllocator byteBufAllocator, int streamId) {
this(null, httpMethod, byteBufAllocator, streamId);
}
/**
* Construct HTTP client request builder.
*
@ -114,6 +122,28 @@ public class HttpClientRequestBuilder implements HttpRequestBuilder, HttpRequest
this.cookies = new HashSet<>();
}
public static HttpRequestBuilder builder(HttpMethod httpMethod) {
return new HttpClientRequestBuilder(httpMethod, UnpooledByteBufAllocator.DEFAULT, 3);
}
@Override
public HttpRequestBuilder setHttp1() {
this.httpVersion = HttpVersion.HTTP_1_1;
return this;
}
@Override
public HttpRequestBuilder setHttp2() {
this.httpVersion = HTTP_2_0;
return this;
}
@Override
public HttpRequestBuilder setVersion(String httpVersion) {
this.httpVersion = HttpVersion.valueOf(httpVersion);
return this;
}
@Override
public HttpRequestBuilder setTimeout(int timeout) {
this.timeout = timeout;
@ -171,12 +201,6 @@ public class HttpClientRequestBuilder implements HttpRequestBuilder, HttpRequest
return this;
}
@Override
public HttpRequestBuilder setVersion(String httpVersion) {
this.httpVersion = HttpVersion.valueOf(httpVersion);
return this;
}
@Override
public HttpRequestBuilder acceptGzip(boolean gzip) {
this.gzip = gzip;
@ -314,6 +338,14 @@ public class HttpClientRequestBuilder implements HttpRequestBuilder, HttpRequest
@Override
public HttpRequestContext execute() {
return execute(httpClient);
}
@Override
public HttpRequestContext execute(HttpClient httpClient) {
if (httpClient == null) {
return null;
}
if (httpRequest == null) {
httpRequest = build();
}
@ -378,8 +410,7 @@ public class HttpClientRequestBuilder implements HttpRequestBuilder, HttpRequest
}
private void content(byte[] buf, AsciiString contentType) throws IOException {
ByteBuf buffer = byteBufAllocator.buffer(buf.length).writeBytes(buf);
content(buffer, contentType);
content(byteBufAllocator.buffer(buf.length).writeBytes(buf), contentType);
}
private void content(ByteBuf body, AsciiString contentType) throws IOException {

View file

@ -21,8 +21,8 @@ import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.cookie.Cookie;
import org.xbib.netty.http.client.listener.CookieListener;
import org.xbib.netty.http.client.listener.ExceptionListener;
import org.xbib.netty.http.client.listener.HttpPushListener;
import org.xbib.netty.http.client.listener.HttpHeadersListener;
import org.xbib.netty.http.client.listener.HttpPushListener;
import org.xbib.netty.http.client.listener.HttpResponseListener;
import java.io.IOException;
@ -33,7 +33,9 @@ import java.util.function.Function;
*/
public interface HttpRequestBuilder {
HttpRequestBuilder setTimeout(int timeout);
HttpRequestBuilder setHttp1();
HttpRequestBuilder setHttp2();
HttpRequestBuilder setVersion(String httpVersion);
@ -81,9 +83,13 @@ public interface HttpRequestBuilder {
HttpRequestBuilder onPushReceived(HttpPushListener httpPushListener);
HttpRequestBuilder setTimeout(int timeout);
HttpRequest build();
HttpRequestContext execute();
HttpRequestContext execute(HttpClient httpClient);
<T> CompletableFuture<T> execute(Function<FullHttpResponse, T> supplier);
}

View file

@ -24,8 +24,8 @@ import io.netty.handler.codec.http2.Http2Headers;
import io.netty.util.internal.PlatformDependent;
import org.xbib.netty.http.client.listener.CookieListener;
import org.xbib.netty.http.client.listener.ExceptionListener;
import org.xbib.netty.http.client.listener.HttpPushListener;
import org.xbib.netty.http.client.listener.HttpHeadersListener;
import org.xbib.netty.http.client.listener.HttpPushListener;
import org.xbib.netty.http.client.listener.HttpResponseListener;
import org.xbib.netty.http.client.util.LimitedHashSet;
@ -91,6 +91,8 @@ public final class HttpRequestContext implements HttpResponseListener, HttpReque
private Map<Integer, FullHttpResponse> httpResponses;
private boolean hastimeout;
private Long stopTime;
HttpRequestContext(URI uri, HttpRequest httpRequest, AtomicInteger streamId,
@ -233,11 +235,7 @@ public final class HttpRequestContext implements HttpResponseListener, HttpReque
return false;
}
boolean secure = "https".equals(uri.getScheme());
boolean secureMatch = (secure && cookie.isSecure()) || (!secure && !cookie.isSecure());
if (!secureMatch) {
return false;
}
return true;
return (secure && cookie.isSecure()) || (!secure && !cookie.isSecure());
}
public int getTimeout() {
@ -293,11 +291,15 @@ public final class HttpRequestContext implements HttpResponseListener, HttpReque
}
public HttpRequestContext waitFor(long value, TimeUnit timeUnit) throws InterruptedException {
latch.await(value, timeUnit);
this.hastimeout = latch.await(value, timeUnit);
stopTime = System.currentTimeMillis();
return this;
}
public boolean isTimeout() {
return hastimeout;
}
public void success(String reason) {
logger.log(Level.FINE, () -> "success because of " + reason);
if (succeeded.compareAndSet(false, true)) {

View file

@ -21,8 +21,6 @@ import io.netty.handler.codec.http.HttpVersion;
*/
public interface HttpRequestDefaults {
int DEFAULT_TIMEOUT_MILLIS = 5000;
HttpVersion DEFAULT_HTTP_VERSION = HttpVersion.HTTP_1_1;
String DEFAULT_USER_AGENT = HttpClientUserAgent.getUserAgent();
@ -31,5 +29,7 @@ public interface HttpRequestDefaults {
boolean DEFAULT_FOLLOW_REDIRECT = true;
int DEFAULT_TIMEOUT_MILLIS = 5000;
int DEFAULT_MAX_REDIRECT = 10;
}

View file

@ -19,7 +19,7 @@ import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http2.Http2Headers;
/**
* This listener can forward HTTP push
* This listener can forward HTTP push.
*
*/
@FunctionalInterface

View file

@ -66,7 +66,7 @@ public class InetAddressKey {
host.equals(((InetAddressKey) object).host) &&
port == ((InetAddressKey) object).port &&
version.equals(((InetAddressKey) object).version) &&
secure == ((InetAddressKey) object).secure;
secure.equals(((InetAddressKey) object).secure);
}
@Override

View file

@ -20,6 +20,7 @@ import java.util.LinkedHashSet;
/**
* A {@link java.util.Set} with limited size. If the size is exceeded, an exception is thrown.
* @param <E> the element type
*/
public final class LimitedHashSet<E> extends LinkedHashSet<E> {

View file

@ -206,11 +206,14 @@ public class NetworkUtils {
public static boolean matchesNetwork(NetworkClass given, NetworkClass expected) {
switch (expected) {
case ANY:
return EnumSet.of(NetworkClass.LOOPBACK, NetworkClass.LOCAL, NetworkClass.PUBLIC, NetworkClass.ANY).contains(given);
return EnumSet.of(NetworkClass.LOOPBACK, NetworkClass.LOCAL, NetworkClass.PUBLIC, NetworkClass.ANY)
.contains(given);
case PUBLIC:
return EnumSet.of(NetworkClass.LOOPBACK, NetworkClass.LOCAL, NetworkClass.PUBLIC).contains(given);
return EnumSet.of(NetworkClass.LOOPBACK, NetworkClass.LOCAL, NetworkClass.PUBLIC)
.contains(given);
case LOCAL:
return EnumSet.of(NetworkClass.LOOPBACK, NetworkClass.LOCAL).contains(given);
return EnumSet.of(NetworkClass.LOOPBACK, NetworkClass.LOCAL)
.contains(given);
case LOOPBACK:
return NetworkClass.LOOPBACK == given;
}
@ -509,8 +512,12 @@ public class NetworkUtils {
.append(" prefixlen:").append(interfaceAddress.getNetworkPrefixLength());
} else {
int netmask = 0xFFFFFFFF << (32 - interfaceAddress.getNetworkPrefixLength());
byte[] b = new byte[] { (byte)(netmask >>> 24), (byte)(netmask >>> 16 & 0xFF),
(byte)(netmask >>> 8 & 0xFF), (byte)(netmask & 0xFF) };
byte[] b = new byte[] {
(byte) (netmask >>> 24),
(byte) (netmask >>> 16 & 0xFF),
(byte) (netmask >>> 8 & 0xFF),
(byte) (netmask & 0xFF)
};
sb.append("inet ").append(format(address));
try {
sb.append(" netmask:").append(format(InetAddress.getByAddress(b)));

View file

@ -34,39 +34,21 @@ public class AkamaiTest {
@Test
public void testAkamaiHttps() throws Exception {
// here we see server PUSH_PROMISE as response to headers, a go-away frame is written.
/*
----------------INBOUND--------------------
[id: 0x27d23874, L:/192.168.178.23:52376 - R:http2.akamai.com/104.94.191.203:443]
PUSH_PROMISE: streamId=3, promisedStreamId=2, headers=DefaultHttp2Headers[:method: GET,
:path: /resources/push.css, :authority: http2.akamai.com, :scheme: https, host: http2.akamai.com,
user-agent: XbibHttpClient/unknown (Java/Azul Systems, Inc./1.8.0_112) (Netty/4.1.9.Final),
accept-encoding: gzip], padding=0
------------------------------------
2017-05-01 18:53:46.076 AM FEINSTEN [org.xbib.netty.http.client.HttpClientChannelInitializer]
io.netty.handler.codec.http2.Http2FrameLogger log
----------------OUTBOUND--------------------
[id: 0x27d23874, L:/192.168.178.23:52376 - R:http2.akamai.com/104.94.191.203:443]
GO_AWAY: lastStreamId=2, errorCode=1, length=75, bytes=556e7265636f676e697a656420485454...
*/
HttpClient httpClient = HttpClient.builder()
.build();
httpClient.prepareGet()
.setVersion("HTTP/2.0")
.setURL("https://http2.akamai.com/demo/h2_demo_frame.html")
HttpClient httpClient = HttpClient.getInstance();
httpClient.prepareGet("https://http2.akamai.com/demo/h2_demo_frame.html")
.setHttp2()
.onException(e -> logger.log(Level.SEVERE, e.getMessage(), e))
.onResponse(fullHttpResponse -> {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
logger.log(Level.INFO, "status = " + fullHttpResponse.status() + " response body = " + response);
logger.log(Level.INFO, "status = " + fullHttpResponse.status()
+ " response body = " + response);
})
.onPushReceived((headers, fullHttpResponse) -> {
logger.log(Level.INFO, "received push promise: request headers = " + headers
.onPushReceived((requestHeaders, fullHttpResponse) -> {
String response = fullHttpResponse.content().toString(StandardCharsets.UTF_8);
logger.log(Level.INFO, "received push promise: request headers = " + requestHeaders
+ " status = " + fullHttpResponse.status()
+ " response headers = " + fullHttpResponse.headers().entries()
+ " response body = " + response
);
})
.execute()