Java tutorial
/* * Copyright 2014 The Netty Project * * The Netty Project licenses this file to you under the Apache License, * version 2.0 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package http2.server; import http2.config.Config; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http2.Http2SecurityUtil; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.*; import io.netty.handler.ssl.ApplicationProtocolConfig.Protocol; import io.netty.handler.ssl.ApplicationProtocolConfig.SelectedListenerFailureBehavior; import io.netty.handler.ssl.ApplicationProtocolConfig.SelectorFailureBehavior; import io.netty.handler.ssl.util.SelfSignedCertificate; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMReader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.KeyManagerFactory; import java.io.FileReader; import java.security.KeyPair; import java.security.KeyStore; import java.security.Security; import java.security.cert.X509Certificate; /** * A HTTP/2 Server that responds to requests with a Hello World. Once started, you can test the * server with the example client. */ public final class Http2Server { private static final Logger logger = LoggerFactory.getLogger(Http2Server.class); static final boolean SSL = true; static final int PORT = Config.getInt("port"); private static KeyManagerFactory kmf; private static Object getPem(String fileName) throws Exception { try (FileReader reader = new FileReader(fileName); PEMReader pem = new PEMReader(reader)) { return pem.readObject(); } catch (Exception e) { logger.error("get pem exception : ", e); throw new Exception(e); } } public static void main(String[] args) throws Exception { System.setProperty("jsse.enableSNIExtension", "true"); // Configure SSL. try { String password = "http2"; if (Security.getProvider("BC") == null) { Security.addProvider(new BouncyCastleProvider()); } KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(null); ks.setKeyEntry("alias", ((KeyPair) getPem(Config.getString("privateKey"))).getPrivate(), password.toCharArray(), new java.security.cert.Certificate[] { (X509Certificate) getPem(Config.getString("certificate")) }); kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, password.toCharArray()); } catch (Exception e) { logger.error("transfer from pem file to pkcs12 failed!", e); } final SslContext sslCtx; if (SSL) { SslProvider provider = OpenSsl.isAlpnSupported() ? SslProvider.OPENSSL : SslProvider.JDK; sslCtx = SslContextBuilder.forServer(kmf).sslProvider(provider) /* NOTE: the cipher filter may not include all ciphers required by the HTTP/2 specification. * Please refer to the HTTP/2 specification for cipher requirements. */ .ciphers(Http2SecurityUtil.CIPHERS, SupportedCipherSuiteFilter.INSTANCE) .applicationProtocolConfig(new ApplicationProtocolConfig(Protocol.ALPN, // NO_ADVERTISE is currently the only mode supported by both OpenSsl and JDK providers. SelectorFailureBehavior.NO_ADVERTISE, // ACCEPT is currently the only mode supported by both OpenSsl and JDK providers. SelectedListenerFailureBehavior.ACCEPT, ApplicationProtocolNames.HTTP_2, ApplicationProtocolNames.HTTP_1_1)) .build(); } else { sslCtx = null; } // Configure the server. EventLoopGroup group = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.option(ChannelOption.SO_BACKLOG, 1024); b.group(group).channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.INFO)) .childHandler(new Http2ServerInitializer(sslCtx)); Channel ch = b.bind(PORT).sync().channel(); System.err.println("Open your HTTP/2-enabled web browser and navigate to " + (SSL ? "https" : "http") + "://127.0.0.1:" + PORT + '/'); ch.closeFuture().sync(); } finally { group.shutdownGracefully(); } } }