Reorganize the SPDY example

- Move the server example to spdy.server
- Move the client example to spdy.client
- Fix inspection warnings
This commit is contained in:
Trustin Lee 2014-02-05 15:03:03 -08:00
parent 20d2fb8c2e
commit cadaeb658d
13 changed files with 71 additions and 71 deletions

View File

@ -13,7 +13,7 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package io.netty.example.spdyclient; package io.netty.example.spdy.client;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
@ -69,20 +69,20 @@ public class HttpResponseClientHandler extends SimpleChannelInboundHandler<HttpO
if (content instanceof LastHttpContent) { if (content instanceof LastHttpContent) {
System.out.println("} END OF CONTENT"); System.out.println("} END OF CONTENT");
this.queue.add(ctx.channel().newSucceededFuture()); queue.add(ctx.channel().newSucceededFuture());
} }
} }
} }
@Override @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
this.queue.add(ctx.channel().newFailedFuture(cause)); queue.add(ctx.channel().newFailedFuture(cause));
cause.printStackTrace(); cause.printStackTrace();
ctx.close(); ctx.close();
} }
public BlockingQueue<ChannelFuture> queue() { public BlockingQueue<ChannelFuture> queue() {
return this.queue; return queue;
} }
} }

View File

@ -13,9 +13,8 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package io.netty.example.spdyclient; package io.netty.example.spdy.client;
import static java.util.concurrent.TimeUnit.SECONDS;
import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
@ -32,13 +31,15 @@ import io.netty.handler.codec.http.HttpVersion;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import static java.util.concurrent.TimeUnit.*;
/** /**
* An SPDY client that allows you to send HTTP GET to a SPDY server. * An SPDY client that allows you to send HTTP GET to a SPDY server.
* <p> * <p>
* This class must be run with the JVM parameter: {@code java -Xbootclasspath/p:<path_to_npn_boot_jar> ...}. The * This class must be run with the JVM parameter: {@code java -Xbootclasspath/p:<path_to_npn_boot_jar> ...}. The
* "path_to_npn_boot_jar" is the path on the file system for the NPN Boot Jar file which can be downloaded from Maven at * "path_to_npn_boot_jar" is the path on the file system for the NPN Boot Jar file which can be downloaded from Maven at
* coordinates org.mortbay.jetty.npn:npn-boot. Different versions applies to different OpenJDK versions. See * coordinates org.mortbay.jetty.npn:npn-boot. Different versions applies to different OpenJDK versions. See
* {@link http://www.eclipse.org/jetty/documentation/current/npn-chapter.html Jetty docs} for more information. * <a href="http://www.eclipse.org/jetty/documentation/current/npn-chapter.html">Jetty docs</a> for more information.
* <p> * <p>
*/ */
public class SpdyClient { public class SpdyClient {
@ -52,54 +53,54 @@ public class SpdyClient {
public SpdyClient(String host, int port) { public SpdyClient(String host, int port) {
this.host = host; this.host = host;
this.port = port; this.port = port;
this.httpResponseHandler = new HttpResponseClientHandler(); httpResponseHandler = new HttpResponseClientHandler();
} }
public void start() { public void start() {
if (this.channel != null) { if (channel != null) {
System.out.println("Already running!"); System.out.println("Already running!");
return; return;
} }
this.workerGroup = new NioEventLoopGroup(); workerGroup = new NioEventLoopGroup();
Bootstrap b = new Bootstrap(); Bootstrap b = new Bootstrap();
b.group(workerGroup); b.group(workerGroup);
b.channel(NioSocketChannel.class); b.channel(NioSocketChannel.class);
b.option(ChannelOption.SO_KEEPALIVE, true); b.option(ChannelOption.SO_KEEPALIVE, true);
b.remoteAddress(new InetSocketAddress(this.host, this.port)); b.remoteAddress(new InetSocketAddress(host, port));
b.handler(new SpdyClientInitializer(this.httpResponseHandler)); b.handler(new SpdyClientInitializer(httpResponseHandler));
// Start the client. // Start the client.
this.channel = b.connect().syncUninterruptibly().channel(); channel = b.connect().syncUninterruptibly().channel();
System.out.println("Connected to [" + this.host + ":" + this.port + "]"); System.out.println("Connected to [" + host + ':' + port + ']');
} }
public void stop() { public void stop() {
try { try {
// Wait until the connection is closed. // Wait until the connection is closed.
this.channel.close().syncUninterruptibly(); channel.close().syncUninterruptibly();
} finally { } finally {
if (this.workerGroup != null) { if (workerGroup != null) {
this.workerGroup.shutdownGracefully(); workerGroup.shutdownGracefully();
} }
} }
} }
public ChannelFuture send(HttpRequest request) { public ChannelFuture send(HttpRequest request) {
// Sends the HTTP request. // Sends the HTTP request.
return this.channel.writeAndFlush(request); return channel.writeAndFlush(request);
} }
public HttpRequest get() { public HttpRequest get() {
HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, ""); HttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "");
request.headers().set(HttpHeaders.Names.HOST, this.host); request.headers().set(HttpHeaders.Names.HOST, host);
request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP); request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING, HttpHeaders.Values.GZIP);
return request; return request;
} }
public BlockingQueue<ChannelFuture> httpResponseQueue() { public BlockingQueue<ChannelFuture> httpResponseQueue() {
return this.httpResponseHandler.queue(); return httpResponseHandler.queue();
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {

View File

@ -13,10 +13,8 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package io.netty.example.spdyclient; package io.netty.example.spdy.client;
import static io.netty.handler.codec.spdy.SpdyVersion.SPDY_3_1;
import static io.netty.util.internal.logging.InternalLogLevel.INFO;
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.SocketChannel;
@ -27,10 +25,12 @@ import io.netty.handler.codec.spdy.SpdyHttpDecoder;
import io.netty.handler.codec.spdy.SpdyHttpEncoder; import io.netty.handler.codec.spdy.SpdyHttpEncoder;
import io.netty.handler.codec.spdy.SpdySessionHandler; import io.netty.handler.codec.spdy.SpdySessionHandler;
import io.netty.handler.ssl.SslHandler; import io.netty.handler.ssl.SslHandler;
import org.eclipse.jetty.npn.NextProtoNego;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.npn.NextProtoNego; import static io.netty.handler.codec.spdy.SpdyVersion.*;
import static io.netty.util.internal.logging.InternalLogLevel.*;
public class SpdyClientInitializer extends ChannelInitializer<SocketChannel> { public class SpdyClientInitializer extends ChannelInitializer<SocketChannel> {

View File

@ -13,14 +13,13 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package io.netty.example.spdyclient; package io.netty.example.spdy.client;
import static io.netty.handler.codec.spdy.SpdyOrHttpChooser.SelectedProtocol.HTTP_1_1; import org.eclipse.jetty.npn.NextProtoNego.ClientProvider;
import static io.netty.handler.codec.spdy.SpdyOrHttpChooser.SelectedProtocol.SPDY_3_1;
import java.util.List; import java.util.List;
import org.eclipse.jetty.npn.NextProtoNego.ClientProvider; import static io.netty.handler.codec.spdy.SpdyOrHttpChooser.SelectedProtocol.*;
/** /**
* The Jetty project provides an implementation of the Transport Layer Security (TLS) extension for Next Protocol * The Jetty project provides an implementation of the Transport Layer Security (TLS) extension for Next Protocol
@ -33,7 +32,7 @@ import org.eclipse.jetty.npn.NextProtoNego.ClientProvider;
* "path_to_npn_boot_jar" is the path on the file system for the NPN Boot Jar file which can be downloaded from Maven * "path_to_npn_boot_jar" is the path on the file system for the NPN Boot Jar file which can be downloaded from Maven
* at coordinates org.mortbay.jetty.npn:npn-boot. Different versions applies to different OpenJDK versions. * at coordinates org.mortbay.jetty.npn:npn-boot. Different versions applies to different OpenJDK versions.
* *
* @see http://www.eclipse.org/jetty/documentation/current/npn-chapter.html * @see <a href="http://www.eclipse.org/jetty/documentation/current/npn-chapter.html">Jetty documentation</a>
*/ */
public class SpdyClientProvider implements ClientProvider { public class SpdyClientProvider implements ClientProvider {
@ -54,6 +53,6 @@ public class SpdyClientProvider implements ClientProvider {
@Override @Override
public void unsupported() { public void unsupported() {
this.selectedProtocol = HTTP_1_1.protocolName(); selectedProtocol = HTTP_1_1.protocolName();
} }
} }

View File

@ -13,7 +13,7 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package io.netty.example.spdyclient; package io.netty.example.spdy.client;
import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
@ -37,7 +37,7 @@ public class SpdyClientStreamIdHandler extends ChannelHandlerAdapter {
if (acceptOutboundMessage(msg)) { if (acceptOutboundMessage(msg)) {
HttpMessage httpMsg = (HttpMessage) msg; HttpMessage httpMsg = (HttpMessage) msg;
if (!httpMsg.headers().contains(SpdyHttpHeaders.Names.STREAM_ID)) { if (!httpMsg.headers().contains(SpdyHttpHeaders.Names.STREAM_ID)) {
SpdyHttpHeaders.setStreamId(httpMsg, this.currentStreamId); SpdyHttpHeaders.setStreamId(httpMsg, currentStreamId);
// Client stream IDs are always odd // Client stream IDs are always odd
currentStreamId += 2; currentStreamId += 2;
} }

View File

@ -13,7 +13,7 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package io.netty.example.spdyclient; package io.netty.example.spdy.client;
import io.netty.channel.ChannelHandlerAdapter; import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
@ -40,7 +40,7 @@ public class SpdyFrameLogger extends ChannelHandlerAdapter {
throw new NullPointerException("level"); throw new NullPointerException("level");
} }
this.logger = InternalLoggerFactory.getInstance(getClass()); logger = InternalLoggerFactory.getInstance(getClass());
this.level = level; this.level = level;
} }
@ -60,16 +60,16 @@ public class SpdyFrameLogger extends ChannelHandlerAdapter {
super.write(ctx, msg, promise); super.write(ctx, msg, promise);
} }
private boolean acceptMessage(Object msg) throws Exception { private static boolean acceptMessage(Object msg) throws Exception {
return msg instanceof SpdyFrame; return msg instanceof SpdyFrame;
} }
private void log(SpdyFrame msg, Direction d) { private void log(SpdyFrame msg, Direction d) {
if (logger.isEnabled(this.level)) { if (logger.isEnabled(level)) {
StringBuilder b = new StringBuilder("\n----------------").append(d.name()).append("--------------------\n"); StringBuilder b = new StringBuilder("\n----------------").append(d.name()).append("--------------------\n");
b.append(msg.toString()); b.append(msg);
b.append("\n------------------------------------"); b.append("\n------------------------------------");
logger.log(this.level, b.toString()); logger.log(level, b.toString());
} }
} }
} }

View File

@ -16,21 +16,22 @@
/** /**
* This package contains an example SPDY HTTP client. It will behave like a SPDY-enabled browser and you can see the * This package contains an example SPDY HTTP client. It will behave like a SPDY-enabled browser and you can see the
* SPDY frames flowing in and out using the {@link io.netty.example.spdyclient.SpdyFrameLogger}. * SPDY frames flowing in and out using the {@link io.netty.example.spdy.client.SpdyFrameLogger}.
* *
* <p> * <p>
* This package relies on the Jetty project's implementation of the Transport Layer Security (TLS) extension for Next * This package relies on the Jetty project's implementation of the Transport Layer Security (TLS) extension for Next
* Protocol Negotiation (NPN) for OpenJDK 7 is required. NPN allows the application layer to negotiate which * Protocol Negotiation (NPN) for OpenJDK 7 is required. NPN allows the application layer to negotiate which
* protocol, SPDY or HTTP, to use. * protocol, SPDY or HTTP, to use.
* <p> * <p>
* To start, run {@link io.netty.example.spdy.SpdyServer} with the JVM parameter: * To start, run {@link io.netty.example.spdy.server.SpdyServer} with the JVM parameter:
* {@code java -Xbootclasspath/p:<path_to_npn_boot_jar> ...}. * {@code java -Xbootclasspath/p:<path_to_npn_boot_jar> ...}.
* The "path_to_npn_boot_jar" is the path on the file system for the NPN Boot Jar file which can be downloaded from * The "path_to_npn_boot_jar" is the path on the file system for the NPN Boot Jar file which can be downloaded from
* Maven at coordinates org.mortbay.jetty.npn:npn-boot. Different versions applies to different OpenJDK versions. * Maven at coordinates org.mortbay.jetty.npn:npn-boot. Different versions applies to different OpenJDK versions.
* See {@link http://www.eclipse.org/jetty/documentation/current/npn-chapter.html Jetty docs} for more information. * See <a href="http://www.eclipse.org/jetty/documentation/current/npn-chapter.html">Jetty docs</a> for more
* information.
* <p> * <p>
* After that, you can run {@link io.netty.example.spdyclient.SpdyClient}, also settings the JVM parameter * After that, you can run {@link io.netty.example.spdy.client.SpdyClient}, also settings the JVM parameter
* mentioned above. * mentioned above.
*/ */
package io.netty.example.spdyclient; package io.netty.example.spdy.client;

View File

@ -13,15 +13,13 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package io.netty.example.spdy; package io.netty.example.spdy.server;
import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.npn.NextProtoNego;
import io.netty.channel.ChannelHandler; import io.netty.channel.ChannelHandler;
import io.netty.handler.codec.spdy.SpdyOrHttpChooser; import io.netty.handler.codec.spdy.SpdyOrHttpChooser;
import org.eclipse.jetty.npn.NextProtoNego;
import javax.net.ssl.SSLEngine;
import java.util.logging.Logger; import java.util.logging.Logger;
/** /**
@ -54,5 +52,4 @@ public class SpdyOrHttpHandler extends SpdyOrHttpChooser {
protected ChannelHandler createHttpRequestHandlerForHttp() { protected ChannelHandler createHttpRequestHandlerForHttp() {
return new SpdyServerHandler(); return new SpdyServerHandler();
} }
} }

View File

@ -13,7 +13,7 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package io.netty.example.spdy; package io.netty.example.spdy.server;
import io.netty.bootstrap.ServerBootstrap; import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel; import io.netty.channel.Channel;
@ -28,10 +28,11 @@ import io.netty.channel.socket.nio.NioServerSocketChannel;
* This class must be run with the JVM parameter: {@code java -Xbootclasspath/p:<path_to_npn_boot_jar> ...}. * This class must be run with the JVM parameter: {@code java -Xbootclasspath/p:<path_to_npn_boot_jar> ...}.
* The "path_to_npn_boot_jar" is the path on the file system for the NPN Boot Jar file which can be downloaded from * The "path_to_npn_boot_jar" is the path on the file system for the NPN Boot Jar file which can be downloaded from
* Maven at coordinates org.mortbay.jetty.npn:npn-boot. Different versions applies to different OpenJDK versions. * Maven at coordinates org.mortbay.jetty.npn:npn-boot. Different versions applies to different OpenJDK versions.
* See {@link http://www.eclipse.org/jetty/documentation/current/npn-chapter.html Jetty docs} for more information. * See <a href="http://www.eclipse.org/jetty/documentation/current/npn-chapter.html">Jetty docs</a> for more
* information.
* <p> * <p>
* Once started, you can test the server with your * Once started, you can test the server with your
* {@link http://en.wikipedia.org/wiki/SPDY#Browser_support_and_usage SPDY enabled web browser} by navigating * <a href="http://en.wikipedia.org/wiki/SPDY#Browser_support_and_usage">SPDY enabled web browser</a> by navigating
* to https://localhost:8443/. * to https://localhost:8443/.
*/ */
public class SpdyServer { public class SpdyServer {

View File

@ -13,9 +13,7 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package io.netty.example.spdy; package io.netty.example.spdy.server;
import java.util.Date;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
@ -27,6 +25,8 @@ import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequest;
import io.netty.util.CharsetUtil; import io.netty.util.CharsetUtil;
import java.util.Date;
import static io.netty.handler.codec.http.HttpHeaders.Names.*; import static io.netty.handler.codec.http.HttpHeaders.Names.*;
import static io.netty.handler.codec.http.HttpHeaders.*; import static io.netty.handler.codec.http.HttpHeaders.*;
import static io.netty.handler.codec.http.HttpResponseStatus.*; import static io.netty.handler.codec.http.HttpResponseStatus.*;
@ -51,7 +51,7 @@ public class SpdyServerHandler extends SimpleChannelInboundHandler<Object> {
} }
boolean keepAlive = isKeepAlive(req); boolean keepAlive = isKeepAlive(req);
ByteBuf content = Unpooled.copiedBuffer("Hello World " + (new Date()).toString(), CharsetUtil.UTF_8); ByteBuf content = Unpooled.copiedBuffer("Hello World " + new Date(), CharsetUtil.UTF_8);
FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, content); FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, content);
response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8"); response.headers().set(CONTENT_TYPE, "text/plain; charset=UTF-8");

View File

@ -13,17 +13,16 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package io.netty.example.spdy; package io.netty.example.spdy.server;
import javax.net.ssl.SSLEngine;
import org.eclipse.jetty.npn.NextProtoNego;
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline; import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.SocketChannel;
import io.netty.example.securechat.SecureChatSslContextFactory; import io.netty.example.securechat.SecureChatSslContextFactory;
import io.netty.handler.ssl.SslHandler; import io.netty.handler.ssl.SslHandler;
import org.eclipse.jetty.npn.NextProtoNego;
import javax.net.ssl.SSLEngine;
/** /**
* Sets up the Netty pipeline * Sets up the Netty pipeline

View File

@ -13,14 +13,14 @@
* License for the specific language governing permissions and limitations * License for the specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package io.netty.example.spdy; package io.netty.example.spdy.server;
import java.util.Arrays;
import java.util.List;
import io.netty.handler.codec.spdy.SpdyOrHttpChooser; import io.netty.handler.codec.spdy.SpdyOrHttpChooser;
import org.eclipse.jetty.npn.NextProtoNego.ServerProvider; import org.eclipse.jetty.npn.NextProtoNego.ServerProvider;
import java.util.Arrays;
import java.util.List;
/** /**
* The Jetty project provides an implementation of the Transport Layer Security (TLS) extension for Next * The Jetty project provides an implementation of the Transport Layer Security (TLS) extension for Next
* Protocol Negotiation (NPN) for OpenJDK 7 or greater. NPN allows the application layer to negotiate which * Protocol Negotiation (NPN) for OpenJDK 7 or greater. NPN allows the application layer to negotiate which
@ -32,7 +32,7 @@ import org.eclipse.jetty.npn.NextProtoNego.ServerProvider;
* "path_to_npn_boot_jar" is the path on the file system for the NPN Boot Jar file which can be downloaded from * "path_to_npn_boot_jar" is the path on the file system for the NPN Boot Jar file which can be downloaded from
* Maven at coordinates org.mortbay.jetty.npn:npn-boot. Different versions applies to different OpenJDK versions. * Maven at coordinates org.mortbay.jetty.npn:npn-boot. Different versions applies to different OpenJDK versions.
* *
* @see http://www.eclipse.org/jetty/documentation/current/npn-chapter.html * @see <a href="http://www.eclipse.org/jetty/documentation/current/npn-chapter.html">Jetty documentation</a>
*/ */
public class SpdyServerProvider implements ServerProvider { public class SpdyServerProvider implements ServerProvider {

View File

@ -21,13 +21,15 @@
* Protocol Negotiation (NPN) for OpenJDK 7 is required. NPN allows the application layer to negotiate which * Protocol Negotiation (NPN) for OpenJDK 7 is required. NPN allows the application layer to negotiate which
* protocol, SPDY or HTTP, to use. * protocol, SPDY or HTTP, to use.
* <p> * <p>
* To start, run {@link SpdyServer} with the JVM parameter: {@code java -Xbootclasspath/p:<path_to_npn_boot_jar> ...}. * To start, run {@link io.netty.example.spdy.server.SpdyServer} with the JVM parameter:
* {@code java -Xbootclasspath/p:<path_to_npn_boot_jar> ...}.
* The "path_to_npn_boot_jar" is the path on the file system for the NPN Boot Jar file which can be downloaded from * The "path_to_npn_boot_jar" is the path on the file system for the NPN Boot Jar file which can be downloaded from
* Maven at coordinates org.mortbay.jetty.npn:npn-boot. Different versions applies to different OpenJDK versions. * Maven at coordinates org.mortbay.jetty.npn:npn-boot. Different versions applies to different OpenJDK versions.
* See {@link http://www.eclipse.org/jetty/documentation/current/npn-chapter.html Jetty docs} for more information. * See <a href="http://www.eclipse.org/jetty/documentation/current/npn-chapter.html">Jetty docs</a> for more
* information.
* <p> * <p>
* Once started, you can test the server with your * Once started, you can test the server with your
* {@link http://en.wikipedia.org/wiki/SPDY#Browser_support_and_usage SPDY enabled web browser} by navigating * <a href="http://en.wikipedia.org/wiki/SPDY#Browser_support_and_usage">SPDY enabled web browser</a> by navigating
* to https://localhost:8443/. * to <a href="https://localhost:8443/">https://localhost:8443/</a>
*/ */
package io.netty.example.spdy; package io.netty.example.spdy.server;