1 /*
2 * Copyright 2012 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16 package io.netty.example.http.cors;
17
18 import io.netty.bootstrap.ServerBootstrap;
19 import io.netty.channel.EventLoopGroup;
20 import io.netty.channel.nio.NioEventLoopGroup;
21 import io.netty.channel.socket.nio.NioServerSocketChannel;
22 import io.netty.handler.logging.LogLevel;
23 import io.netty.handler.logging.LoggingHandler;
24 import io.netty.handler.ssl.SslContext;
25 import io.netty.handler.ssl.SslContextBuilder;
26 import io.netty.handler.ssl.util.SelfSignedCertificate;
27
28 /**
29 * This example server aims to demonstrate
30 * <a href="http://www.w3.org/TR/cors/">Cross Origin Resource Sharing</a> (CORS) in Netty.
31 * It does not have a client like most of the other examples, but instead has
32 * a html page that is loaded to try out CORS support in a web browser.
33 * <p>
34 *
35 * CORS is configured in {@link HttpCorsServerInitializer} and by updating the config you can
36 * try out various combinations, like using a specific origin instead of a
37 * wildcard origin ('*').
38 * <p>
39 *
40 * The file {@code src/main/resources/cors/cors.html} contains a very basic example client
41 * which can be used to try out different configurations. For example, you can add
42 * custom headers to force a CORS preflight request to make the request fail. Then
43 * to enable a successful request, configure the CorsHandler to allow that/those
44 * request headers.
45 *
46 * <h2>Testing CORS</h2>
47 * You can either load the file {@code src/main/resources/cors/cors.html} using a web server
48 * or load it from the file system using a web browser.
49 *
50 * <h3>Using a web server</h3>
51 * To test CORS support you can serve the file {@code src/main/resources/cors/cors.html}
52 * using a web server. You can then add a new host name to your systems hosts file, for
53 * example if you are on Linux you may update /etc/hosts to add an additional name
54 * for you local system:
55 * <pre>
56 * 127.0.0.1 localhost domain1.com
57 * </pre>
58 * Now, you should be able to access {@code http://domain1.com/cors.html} depending on how you
59 * have configured you local web server the exact url may differ.
60 *
61 * <h3>Using a web browser</h3>
62 * Open the file {@code src/main/resources/cors/cors.html} in a web browser. You should see
63 * loaded page and in the text area the following message:
64 * <pre>
65 * 'CORS is not working'
66 * </pre>
67 *
68 * If you inspect the headers being sent using your browser you'll see that the 'Origin'
69 * request header is {@code 'null'}. This is expected and happens when you load a file from the
70 * local file system. Netty can handle this by configuring the CorsHandler which is done
71 * in the {@link HttpCorsServerInitializer}.
72 *
73 */
74 public final class HttpCorsServer {
75
76 static final boolean SSL = System.getProperty("ssl") != null;
77 static final int PORT = Integer.parseInt(System.getProperty("port", SSL? "8443" : "8080"));
78
79 public static void main(String[] args) throws Exception {
80 // Configure SSL.
81 final SslContext sslCtx;
82 if (SSL) {
83 SelfSignedCertificate ssc = new SelfSignedCertificate();
84 sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
85 } else {
86 sslCtx = null;
87 }
88
89 EventLoopGroup bossGroup = new NioEventLoopGroup(1);
90 EventLoopGroup workerGroup = new NioEventLoopGroup();
91 try {
92 ServerBootstrap b = new ServerBootstrap();
93 b.group(bossGroup, workerGroup)
94 .channel(NioServerSocketChannel.class)
95 .handler(new LoggingHandler(LogLevel.INFO))
96 .childHandler(new HttpCorsServerInitializer(sslCtx));
97
98 b.bind(PORT).sync().channel().closeFuture().sync();
99 } finally {
100 bossGroup.shutdownGracefully();
101 workerGroup.shutdownGracefully();
102 }
103 }
104 }