Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Very early changes for SPDY/3 support with the Grizzly provider. More…

… changes pending.
  • Loading branch information...
commit 1379ba5bdec90ed3d71f3f7233325418d5943246 1 parent 63d6cac
Ryan Lubke authored
View
31 api/src/main/java/com/ning/http/client/AsyncHttpClientConfig.java
@@ -110,6 +110,7 @@
protected boolean strict302Handling;
protected int maxConnectionLifeTimeInMs;
protected boolean useRelativeURIsWithSSLProxies;
+ protected boolean spdyEnabled;
protected AsyncHttpClientConfig() {
}
@@ -145,7 +146,8 @@ private AsyncHttpClientConfig(int maxTotalConnections,
HostnameVerifier hostnameVerifier,
int ioThreadMultiplier,
boolean strict302Handling,
- boolean useRelativeURIsWithSSLProxies) {
+ boolean useRelativeURIsWithSSLProxies,
+ boolean spdyEnabled) {
this.maxTotalConnections = maxTotalConnections;
this.maxConnectionPerHost = maxConnectionPerHost;
@@ -185,6 +187,7 @@ private AsyncHttpClientConfig(int maxTotalConnections,
}
this.proxyServer = proxyServer;
this.useRawUrl = useRawUrl;
+ this.spdyEnabled = spdyEnabled;
}
/**
@@ -456,6 +459,13 @@ public boolean isUseRawUrl() {
}
/**
+ * @return whether or not SPDY is enabled.
+ */
+ public boolean isSpdyEnabled() {
+ return spdyEnabled;
+ }
+
+ /**
* Return true if the query parameters will be stripped from the request when a redirect is requested.
*
* @return true if the query parameters will be stripped from the request when a redirect is requested.
@@ -575,6 +585,7 @@ public Thread newThread(Runnable r) {
private HostnameVerifier hostnameVerifier = new AllowAllHostnameVerifier();
private int ioThreadMultiplier = 2;
private boolean strict302Handling;
+ private boolean spdyEnabled;
public Builder() {
}
@@ -1032,6 +1043,21 @@ public Builder setUseRelativeURIsWithSSLProxies(boolean useRelativeURIsWithSSLPr
}
/**
+ * Enables SPDY support. Note that doing so, will currently disable WebSocket support
+ * for this client instance. If not explicitly enabled, spdy will not be used.
+ *
+ * @param spdyEnabled configures spdy support.
+ *
+ * @return this
+ *
+ * @since 2.0
+ */
+ public Builder setSpdyEnabled(boolean spdyEnabled) {
+ this.spdyEnabled = spdyEnabled;
+ return this;
+ }
+
+ /**
* Create a config builder with values taken from the given prototype configuration.
*
* @param prototype the configuration to use as a prototype.
@@ -1124,7 +1150,8 @@ public AsyncHttpClientConfig build() {
hostnameVerifier,
ioThreadMultiplier,
strict302Handling,
- useRelativeURIsWithSSLProxies);
+ useRelativeURIsWithSSLProxies,
+ spdyEnabled);
}
}
}
View
20 providers/grizzly/pom.xml
@@ -13,18 +13,26 @@
The Async Http Client Grizzly Provider.
</description>
+ <properties>
+ <grizzly.version>2.3.3-SNAPSHOT</grizzly.version>
+ <grizzly.npn.version>1.0</grizzly.npn.version>
+ </properties>
+
<dependencies>
<dependency>
<groupId>org.glassfish.grizzly</groupId>
<artifactId>grizzly-websockets</artifactId>
- <version>2.3.2</version>
+ <version>${grizzly.version}</version>
</dependency>
<dependency>
- <groupId>com.ning</groupId>
- <artifactId>async-http-client-api</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- <classifier>tests</classifier>
+ <groupId>org.glassfish.grizzly</groupId>
+ <artifactId>grizzly-spdy</artifactId>
+ <version>${grizzly.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.glassfish.grizzly</groupId>
+ <artifactId>grizzly-npn-api</artifactId>
+ <version>${grizzly.npn.version}</version>
</dependency>
</dependencies>
View
372 providers/grizzly/src/main/java/com/ning/http/client/providers/grizzly/GrizzlyAsyncHttpProvider.java
@@ -15,6 +15,7 @@
import com.ning.org.jboss.netty.handler.codec.http.CookieDecoder;
import com.ning.http.client.AsyncHandler;
+import com.ning.http.client.AsyncHttpClient;
import com.ning.http.client.AsyncHttpClientConfig;
import com.ning.http.client.AsyncHttpProvider;
import com.ning.http.client.AsyncHttpProviderConfig;
@@ -84,6 +85,10 @@
import org.glassfish.grizzly.http.Method;
import org.glassfish.grizzly.http.Protocol;
import org.glassfish.grizzly.impl.FutureImpl;
+import org.glassfish.grizzly.spdy.NextProtoNegSupport;
+import org.glassfish.grizzly.spdy.SpdyFramingFilter;
+import org.glassfish.grizzly.spdy.SpdyHandlerFilter;
+import org.glassfish.grizzly.spdy.SpdyMode;
import org.glassfish.grizzly.utils.Charsets;
import org.glassfish.grizzly.http.util.CookieSerializerUtils;
import org.glassfish.grizzly.http.util.DataChunk;
@@ -142,10 +147,9 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
-import static com.ning.http.util.MiscUtil.isNonEmpty;
-import static com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProviderConfig.Property.BUFFER_WEBSOCKET_FRAGMENTS;
+import static com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProviderConfig.Property;
import static com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProviderConfig.Property.MAX_HTTP_PACKET_HEADER_SIZE;
-import static com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProviderConfig.Property.TRANSPORT_CUSTOMIZER;
+import static com.ning.http.util.MiscUtil.isNonEmpty;
/**
* A Grizzly 2.0-based implementation of {@link AsyncHttpProvider}.
@@ -379,32 +383,73 @@ public void onTimeout(Connection connection) {
fcb.add(filter);
GrizzlyAsyncHttpProviderConfig providerConfig =
(GrizzlyAsyncHttpProviderConfig) clientConfig.getAsyncHttpProviderConfig();
- final AsyncHttpClientEventFilter eventFilter;
- if (providerConfig != null) {
- eventFilter = new AsyncHttpClientEventFilter(this, (Integer) providerConfig.getProperty(MAX_HTTP_PACKET_HEADER_SIZE));
+
+ boolean npnEnabled = NextProtoNegSupport.isEnabled();
+ boolean spdyEnabled = clientConfig.isSpdyEnabled();
+
+ if (spdyEnabled) {
+ // if NPN isn't available, check to see if it has been explicitly
+ // disabled. If it has, we assume the user knows what they are doing
+ // and we enable SPDY without NPN - this effectively disables standard
+ // HTTP/1.1 support.
+ if (!npnEnabled && providerConfig != null) {
+ if ((Boolean) providerConfig.getProperty(Property.NPN_ENABLED)) {
+ // NPN hasn't been disabled, so it's most likely a configuration proble.
+ // Log a warning and disable spdy support.
+ LOGGER.warn("Next Protocol Negotiation support is not available. SPDY support has been disabled.");
+ spdyEnabled = false;
+ }
+ }
+ }
+
+ if (!spdyEnabled) {
+ final AsyncHttpClientEventFilter eventFilter;
+ final EventHandler handler = new EventHandler(this);
+ if (providerConfig != null) {
+ eventFilter =
+ new AsyncHttpClientEventFilter(handler,
+ (Integer) providerConfig
+ .getProperty(
+ MAX_HTTP_PACKET_HEADER_SIZE));
+ } else {
+ eventFilter = new AsyncHttpClientEventFilter(handler);
+ }
+ handler.cleanup = eventFilter;
+ ContentEncoding[] encodings = eventFilter.getContentEncodings();
+ if (encodings.length > 0) {
+ for (ContentEncoding encoding : encodings) {
+ eventFilter.removeContentEncoding(encoding);
+ }
+ }
+ if (clientConfig.isCompressionEnabled()) {
+ eventFilter.addContentEncoding(
+ new GZipContentEncoding(512,
+ 512,
+ new ClientEncodingFilter()));
+ }
+ fcb.add(eventFilter);
+ final AsyncHttpClientFilter clientFilter =
+ new AsyncHttpClientFilter(clientConfig);
+ fcb.add(clientFilter);
+ fcb.add(new WebSocketClientFilter());
} else {
- eventFilter = new AsyncHttpClientEventFilter(this);
- }
- final AsyncHttpClientFilter clientFilter =
- new AsyncHttpClientFilter(clientConfig);
- ContentEncoding[] encodings = eventFilter.getContentEncodings();
- if (encodings.length > 0) {
- for (ContentEncoding encoding : encodings) {
- eventFilter.removeContentEncoding(encoding);
+ fcb.add(new SpdyFramingFilter());
+ fcb.add(new AsyncSpdyClientEventFilter(new EventHandler(this),
+ ((npnEnabled) ? SpdyMode.NPN : SpdyMode.PLAIN),
+ clientConfig.executorService()));
+ final AsyncHttpClientFilter clientFilter =
+ new AsyncHttpClientFilter(clientConfig);
+ fcb.add(clientFilter);
+ if (npnEnabled) {
+ int idx = fcb.indexOfType(SSLFilter.class);
+ SSLFilter f = (SSLFilter) fcb.get(idx);
+ NextProtoNegSupport.getInstance().configure(f);
}
}
- if (clientConfig.isCompressionEnabled()) {
- eventFilter.addContentEncoding(
- new GZipContentEncoding(512,
- 512,
- new ClientEncodingFilter()));
- }
- fcb.add(eventFilter);
- fcb.add(clientFilter);
-
+
if (providerConfig != null) {
final TransportCustomizer customizer = (TransportCustomizer)
- providerConfig.getProperty(TRANSPORT_CUSTOMIZER);
+ providerConfig.getProperty(Property.TRANSPORT_CUSTOMIZER);
if (customizer != null) {
customizer.customize(clientTransport, fcb);
} else {
@@ -413,7 +458,7 @@ public void onTimeout(Connection connection) {
} else {
doDefaultTransportConfig();
}
- fcb.add(new WebSocketClientFilter());
+
clientTransport.getAsyncQueueIO().getWriter().setMaxPendingBytesPerConnection(-1);
clientTransport.setProcessor(fcb.build());
@@ -560,7 +605,8 @@ boolean sendRequest(final FilterChainContext ctx,
context.bodyHandler = handler;
isWriteComplete = handler.doHandle(ctx, request, requestPacket);
} else {
- ctx.write(requestPacket, ctx.getTransportContext().getCompletionHandler());
+ HttpContent content = HttpContent.builder(requestPacket).last(true).build();
+ ctx.write(content, ctx.getTransportContext().getCompletionHandler());
}
LOGGER.debug("REQUEST: {}", requestPacket);
@@ -699,6 +745,7 @@ void tunnelEstablished(final Connection c) {
// ---------------------------------------------------------- Nested Classes
+
private static final class ContinueEvent implements FilterChainEvent {
private final HttpTransactionContext context;
@@ -1064,29 +1111,152 @@ private void addQueryString(final Request request,
} // END AsyncHttpClientFiler
- private static final class AsyncHttpClientEventFilter extends HttpClientFilter {
+ private interface Cleanup {
- private final Map<Integer,StatusHandler> HANDLER_MAP = new HashMap<Integer,StatusHandler>();
+ void cleanup(final FilterChainContext ctx);
+ }
- private final GrizzlyAsyncHttpProvider provider;
+
+ private static final class AsyncHttpClientEventFilter extends HttpClientFilter implements Cleanup {
+ private final EventHandler eventHandler;
+
// -------------------------------------------------------- Constructors
- AsyncHttpClientEventFilter(final GrizzlyAsyncHttpProvider provider) {
- this(provider, DEFAULT_MAX_HTTP_PACKET_HEADER_SIZE);
+ AsyncHttpClientEventFilter(final EventHandler eventHandler) {
+ this(eventHandler, DEFAULT_MAX_HTTP_PACKET_HEADER_SIZE);
}
- AsyncHttpClientEventFilter(final GrizzlyAsyncHttpProvider provider,
+ AsyncHttpClientEventFilter(final EventHandler eventHandler,
final int maxHeaderSize) {
super(maxHeaderSize);
- this.provider = provider;
+ this.eventHandler = eventHandler;
+ }
+
+
+ @Override
+ public void exceptionOccurred(FilterChainContext ctx, Throwable error) {
+ eventHandler.exceptionOccurred(ctx, error);
+ }
+
+ @Override
+ protected void onHttpContentParsed(HttpContent content, FilterChainContext ctx) {
+ eventHandler.onHttpContentParsed(content, ctx);
+ }
+
+ @Override
+ protected void onHttpHeadersEncoded(HttpHeader httpHeader, FilterChainContext ctx) {
+ eventHandler.onHttpHeadersEncoded(httpHeader, ctx);
+ }
+
+ @Override
+ protected void onHttpContentEncoded(HttpContent content, FilterChainContext ctx) {
+ eventHandler.onHttpContentEncoded(content, ctx);
+ }
+
+ @Override
+ protected void onInitialLineParsed(HttpHeader httpHeader, FilterChainContext ctx) {
+ eventHandler.onInitialLineParsed(httpHeader, ctx);
+ }
+
+ @Override
+ protected void onHttpHeaderError(HttpHeader httpHeader, FilterChainContext ctx, Throwable t) throws IOException {
+ eventHandler.onHttpHeaderError(httpHeader, ctx, t);
+ }
+
+ @Override
+ protected void onHttpHeadersParsed(HttpHeader httpHeader, FilterChainContext ctx) {
+ eventHandler.onHttpHeadersParsed(httpHeader, ctx);
+ }
+
+ @Override
+ protected boolean onHttpPacketParsed(HttpHeader httpHeader, FilterChainContext ctx) {
+ return eventHandler.onHttpPacketParsed(httpHeader, ctx);
+ }
+
+ @Override
+ public void cleanup(final FilterChainContext ctx) {
+ clearResponse(ctx.getConnection());
+ }
+ } // END AsyncHttpClientEventFilter
+
+
+ private static final class AsyncSpdyClientEventFilter extends SpdyHandlerFilter implements Cleanup {
+
+
+ private final EventHandler eventHandler;
+
+ // -------------------------------------------------------- Constructors
+
+
+ AsyncSpdyClientEventFilter(final EventHandler eventHandler,
+ SpdyMode mode,
+ ExecutorService threadPool) {
+ super(mode, threadPool);
+ this.eventHandler = eventHandler;
+ }
+
+ @Override
+ public void exceptionOccurred(FilterChainContext ctx, Throwable error) {
+ eventHandler.exceptionOccurred(ctx, error);
+ }
+
+ @Override
+ protected void onHttpContentParsed(HttpContent content, FilterChainContext ctx) {
+ eventHandler.onHttpContentParsed(content, ctx);
+ }
+
+ @Override
+ protected void onHttpHeadersEncoded(HttpHeader httpHeader, FilterChainContext ctx) {
+ eventHandler.onHttpHeadersEncoded(httpHeader, ctx);
+ }
+
+ @Override
+ protected void onHttpContentEncoded(HttpContent content, FilterChainContext ctx) {
+ eventHandler.onHttpContentEncoded(content, ctx);
+ }
+
+ @Override
+ protected void onInitialLineParsed(HttpHeader httpHeader, FilterChainContext ctx) {
+ eventHandler.onInitialLineParsed(httpHeader, ctx);
+ }
+
+ @Override
+ protected void onHttpHeaderError(HttpHeader httpHeader, FilterChainContext ctx, Throwable t) throws IOException {
+ eventHandler.onHttpHeaderError(httpHeader, ctx, t);
+ }
+
+ @Override
+ protected void onHttpHeadersParsed(HttpHeader httpHeader, FilterChainContext ctx) {
+ eventHandler.onHttpHeadersParsed(httpHeader, ctx);
+ }
+
+ @Override
+ protected boolean onHttpPacketParsed(HttpHeader httpHeader, FilterChainContext ctx) {
+ return eventHandler.onHttpPacketParsed(httpHeader, ctx);
+ }
+
+ @Override
+ public void cleanup(FilterChainContext ctx) {
+
+ }
+
+ } // END AsyncSpdyClientEventFilter
+
+
+ private static final class EventHandler {
+
+ private static final Map<Integer, StatusHandler> HANDLER_MAP =
+ new HashMap<Integer, StatusHandler>();
+
+ static {
HANDLER_MAP.put(HttpStatus.UNAUTHORIZED_401.getStatusCode(),
- AuthorizationHandler.INSTANCE);
+ AuthorizationHandler.INSTANCE);
HANDLER_MAP.put(HttpStatus.PROXY_AUTHENTICATION_REQUIRED_407.getStatusCode(),
ProxyAuthorizationHandler.INSTANCE);
HANDLER_MAP.put(HttpStatus.MOVED_PERMANENTLY_301.getStatusCode(),
@@ -1095,14 +1265,24 @@ private void addQueryString(final Request request,
RedirectHandler.INSTANCE);
HANDLER_MAP.put(HttpStatus.TEMPORARY_REDIRECT_307.getStatusCode(),
RedirectHandler.INSTANCE);
+ }
+
+ private final GrizzlyAsyncHttpProvider provider;
+ Cleanup cleanup;
+
+
+ // -------------------------------------------------------- Constructors
+
+
+ EventHandler(final GrizzlyAsyncHttpProvider provider) {
+ this.provider = provider;
}
- // --------------------------------------- Methods from HttpClientFilter
+ // ----------------------------------------------------- Event Callbacks
- @Override
public void exceptionOccurred(FilterChainContext ctx, Throwable error) {
provider.getHttpTransactionContext(ctx.getConnection()).abort(error);
@@ -1110,7 +1290,6 @@ public void exceptionOccurred(FilterChainContext ctx, Throwable error) {
}
- @Override
protected void onHttpContentParsed(HttpContent content,
FilterChainContext ctx) {
@@ -1131,7 +1310,7 @@ protected void onHttpContentParsed(HttpContent content,
}
- @Override
+ @SuppressWarnings("UnusedParameters")
protected void onHttpHeadersEncoded(HttpHeader httpHeader, FilterChainContext ctx) {
final HttpTransactionContext context = provider.getHttpTransactionContext(ctx.getConnection());
final AsyncHandler handler = context.handler;
@@ -1142,7 +1321,6 @@ protected void onHttpHeadersEncoded(HttpHeader httpHeader, FilterChainContext ct
}
}
- @Override
protected void onHttpContentEncoded(HttpContent content, FilterChainContext ctx) {
final HttpTransactionContext context = provider.getHttpTransactionContext(ctx.getConnection());
final AsyncHandler handler = context.handler;
@@ -1158,11 +1336,10 @@ protected void onHttpContentEncoded(HttpContent content, FilterChainContext ctx)
}
}
- @Override
protected void onInitialLineParsed(HttpHeader httpHeader,
FilterChainContext ctx) {
- super.onInitialLineParsed(httpHeader, ctx);
+ //super.onInitialLineParsed(httpHeader, ctx);
if (httpHeader.isSkipRemainder()) {
return;
}
@@ -1239,7 +1416,6 @@ protected void onInitialLineParsed(HttpHeader httpHeader,
}
- @Override
protected void onHttpHeaderError(final HttpHeader httpHeader,
final FilterChainContext ctx,
final Throwable t) throws IOException {
@@ -1252,11 +1428,10 @@ protected void onHttpHeaderError(final HttpHeader httpHeader,
}
@SuppressWarnings({"unchecked"})
- @Override
protected void onHttpHeadersParsed(HttpHeader httpHeader,
FilterChainContext ctx) {
- super.onHttpHeadersParsed(httpHeader, ctx);
+ //super.onHttpHeadersParsed(httpHeader, ctx);
LOGGER.debug("RESPONSE: {}", httpHeader);
if (httpHeader.containsHeader(Header.Connection)) {
if ("close".equals(httpHeader.getHeader(Header.Connection))) {
@@ -1379,25 +1554,29 @@ protected void onHttpHeadersParsed(HttpHeader httpHeader,
}
@SuppressWarnings("unchecked")
- @Override
protected boolean onHttpPacketParsed(HttpHeader httpHeader, FilterChainContext ctx) {
boolean result;
final String proxy_auth = httpHeader.getHeader(Header.ProxyAuthenticate);
-
+
if (httpHeader.isSkipRemainder() ) {
if (!ProxyAuthorizationHandler.isNTLMSecondHandShake(proxy_auth)) {
- clearResponse(ctx.getConnection());
+ cleanup.cleanup(ctx);
cleanup(ctx, provider);
return false;
} else {
- super.onHttpPacketParsed(httpHeader, ctx);
+ //super.onHttpPacketParsed(httpHeader, ctx);
+ cleanup.cleanup(ctx);
httpHeader.getProcessingState().setKeepAlive(true);
return false;
}
}
- result = super.onHttpPacketParsed(httpHeader, ctx);
+ //result = super.onHttpPacketParsed(httpHeader, ctx);
+ if (cleanup != null) {
+ cleanup.cleanup(ctx);
+ }
+ result = false;
final HttpTransactionContext context = provider.getHttpTransactionContext(ctx.getConnection());
if (context.establishingTunnel
@@ -1441,7 +1620,7 @@ private static GrizzlyWebSocketAdapter createWebSocketAdapter(final HttpTransact
AsyncHttpProviderConfig config = context.provider.clientConfig.getAsyncHttpProviderConfig();
boolean bufferFragments = true;
if (config instanceof GrizzlyAsyncHttpProviderConfig) {
- bufferFragments = (Boolean) ((GrizzlyAsyncHttpProviderConfig) config).getProperty(BUFFER_WEBSOCKET_FRAGMENTS);
+ bufferFragments = (Boolean) ((GrizzlyAsyncHttpProviderConfig) config).getProperty(Property.BUFFER_WEBSOCKET_FRAGMENTS);
}
return new GrizzlyWebSocketAdapter(ws, bufferFragments);
@@ -1478,13 +1657,6 @@ private static HttpTransactionContext cleanup(final FilterChainContext ctx,
}
- private static URI getURI(String url) {
-
- return AsyncHttpProviderUtils.createUri(url);
-
- }
-
-
private static boolean redirectCountExceeded(final HttpTransactionContext context) {
return (context.redirectCount.get() > context.maxRedirectCount);
@@ -2430,14 +2602,14 @@ public boolean doHandle(final FilterChainContext ctx,
while (!last) {
Buffer buffer = mm.allocate(MAX_CHUNK_SIZE);
buffer.allowBufferDispose(true);
-
+
final long readBytes = bodyLocal.read(buffer.toByteBuffer());
if (readBytes > 0) {
buffer.position((int) readBytes);
buffer.trim();
} else {
buffer.dispose();
-
+
if (readBytes < 0) {
last = true;
buffer = Buffers.EMPTY_BUFFER;
@@ -2458,7 +2630,7 @@ public boolean doHandle(final FilterChainContext ctx,
last(last).build();
ctx.write(content, ((!requestPacket.isCommitted()) ? ctx.getTransportContext().getCompletionHandler() : null));
}
-
+
return true;
}
@@ -2812,26 +2984,26 @@ public void getBytes(byte[] bytes) {
}
} // END GrizzlyTransferAdapter
-
-
+
+
private static final class GrizzlyWebSocketAdapter implements WebSocket {
-
+
private final SimpleWebSocket gWebSocket;
private final boolean bufferFragments;
// -------------------------------------------------------- Constructors
-
-
+
+
GrizzlyWebSocketAdapter(final SimpleWebSocket gWebSocket,
final boolean bufferFragements) {
this.gWebSocket = gWebSocket;
this.bufferFragments = bufferFragements;
}
-
-
+
+
// ------------------------------------------ Methods from AHC WebSocket
-
-
+
+
@Override
public WebSocket sendMessage(byte[] message) {
gWebSocket.send(message);
@@ -2899,7 +3071,7 @@ public boolean isOpen() {
public void close() {
gWebSocket.close();
}
-
+
} // END GrizzlyWebSocketAdapter
@@ -3068,7 +3240,65 @@ public int hashCode() {
return result;
}
} // END AHCWebSocketListenerAdapter
-
+
+ /*
+
+ public static void main(String[] args) {
+ AsyncHttpClientConfig config =
+ new AsyncHttpClientConfig.Builder().setSpdyEnabled(
+ true).build();
+ AsyncHttpClient client =
+ new AsyncHttpClient(new GrizzlyAsyncHttpProvider(config),
+ config);
+ try {
+ client.prepareGet("https://www.google.com")
+ .execute(new AsyncHandler<Object>() {
+ @Override
+ public void onThrowable(Throwable t) {
+ t.printStackTrace();
+ }
+
+ @Override
+ public STATE onBodyPartReceived(HttpResponseBodyPart bodyPart)
+ throws Exception {
+ System.out.println(
+ new String(bodyPart.getBodyPartBytes(),
+ "UTF-8"));
+ return STATE.CONTINUE;
+ }
+
+ @Override
+ public STATE onStatusReceived(HttpResponseStatus responseStatus)
+ throws Exception {
+ System.out
+ .println(
+ responseStatus.getStatusCode());
+ return STATE.CONTINUE;
+ }
+
+ @Override
+ public STATE onHeadersReceived(HttpResponseHeaders headers)
+ throws Exception {
+ System.out.println(headers.toString());
+ return STATE.CONTINUE;
+ }
+
+ @Override
+ public Object onCompleted() throws Exception {
+ System.out.println("REQUEST COMPLETE");
+ return null;
+ }
+ }).get();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ }
+ }
+
+ */
}
View
9 providers/grizzly/src/main/java/com/ning/http/client/providers/grizzly/GrizzlyAsyncHttpProviderConfig.java
@@ -65,7 +65,14 @@
* invoked with the complete message. If this functionality is not desired, set
* this property to false.
*/
- BUFFER_WEBSOCKET_FRAGMENTS(Boolean.class, true);
+ BUFFER_WEBSOCKET_FRAGMENTS(Boolean.class, true),
+
+ /**
+ * By disabling NPN support, SPDY will be used over secure or non-secure channels,
+ * but no negotiation of the protocol via NPN will occur. In short, this means
+ * that this instance of AHC will only 'speak' SPDY - HTTP is effectively disabled.
+ */
+ NPN_ENABLED(Boolean.class, true);
final Object defaultValue;
Please sign in to comment.
Something went wrong with that request. Please try again.