d7e7c6311aac2d5ffac85197a1d15a936de22fdf
[platform/upstream/iotivity.git] / cloud / stack / src / main / java / org / iotivity / cloud / base / HttpClient.java
1 /*
2  *******************************************************************
3  *
4  * Copyright 2016 Samsung Electronics All Rights Reserved.
5  *
6  *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21  */
22 package org.iotivity.cloud.base;
23
24 import java.net.URI;
25 import java.net.URISyntaxException;
26
27 import javax.net.ssl.SSLException;
28
29 import io.netty.bootstrap.Bootstrap;
30 import io.netty.channel.Channel;
31 import io.netty.channel.ChannelHandlerContext;
32 import io.netty.channel.ChannelInitializer;
33 import io.netty.channel.ChannelPipeline;
34 import io.netty.channel.EventLoopGroup;
35 import io.netty.channel.SimpleChannelInboundHandler;
36 import io.netty.channel.nio.NioEventLoopGroup;
37 import io.netty.channel.socket.SocketChannel;
38 import io.netty.channel.socket.nio.NioSocketChannel;
39 import io.netty.handler.codec.http.ClientCookieEncoder;
40 import io.netty.handler.codec.http.DefaultCookie;
41 import io.netty.handler.codec.http.DefaultFullHttpRequest;
42 import io.netty.handler.codec.http.HttpClientCodec;
43 import io.netty.handler.codec.http.HttpContent;
44 import io.netty.handler.codec.http.HttpContentDecompressor;
45 import io.netty.handler.codec.http.HttpHeaders;
46 import io.netty.handler.codec.http.HttpMethod;
47 import io.netty.handler.codec.http.HttpObject;
48 import io.netty.handler.codec.http.HttpRequest;
49 import io.netty.handler.codec.http.HttpResponse;
50 import io.netty.handler.codec.http.HttpVersion;
51 import io.netty.handler.codec.http.LastHttpContent;
52 import io.netty.handler.ssl.SslContext;
53 import io.netty.handler.ssl.SslContextBuilder;
54 import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
55 import io.netty.util.CharsetUtil;
56
57 public class HttpClient {
58
59     private static class HttpClientInitializer
60             extends ChannelInitializer<SocketChannel> {
61
62         public static class HttpSnoopClientHandler
63                 extends SimpleChannelInboundHandler<HttpObject> {
64
65             @Override
66             public void channelRead0(ChannelHandlerContext ctx,
67                     HttpObject msg) {
68                 if (msg instanceof HttpResponse) {
69                     HttpResponse response = (HttpResponse) msg;
70
71                     System.err.println("STATUS: " + response.getStatus());
72                     System.err.println(
73                             "VERSION: " + response.getProtocolVersion());
74                     System.err.println();
75
76                     if (!response.headers().isEmpty()) {
77                         for (String name : response.headers().names()) {
78                             for (String value : response.headers()
79                                     .getAll(name)) {
80                                 System.err.println(
81                                         "HEADER: " + name + " = " + value);
82                             }
83                         }
84                         System.err.println();
85                     }
86
87                     if (HttpHeaders.isTransferEncodingChunked(response)) {
88                         System.err.println("CHUNKED CONTENT {");
89                     } else {
90                         System.err.println("CONTENT {");
91                     }
92                 }
93                 if (msg instanceof HttpContent) {
94                     HttpContent content = (HttpContent) msg;
95
96                     System.err.print(
97                             content.content().toString(CharsetUtil.UTF_8));
98                     System.err.flush();
99
100                     if (content instanceof LastHttpContent) {
101                         System.err.println("} END OF CONTENT");
102                         ctx.close();
103                     }
104                 }
105             }
106
107             @Override
108             public void exceptionCaught(ChannelHandlerContext ctx,
109                     Throwable cause) {
110                 cause.printStackTrace();
111                 ctx.close();
112             }
113         }
114
115         private final SslContext sslCtx;
116
117         public HttpClientInitializer(SslContext sslCtx) {
118             this.sslCtx = sslCtx;
119         }
120
121         @Override
122         public void initChannel(SocketChannel ch) {
123             ChannelPipeline p = ch.pipeline();
124
125             // Enable HTTPS if necessary.
126             if (sslCtx != null) {
127                 p.addLast(sslCtx.newHandler(ch.alloc()));
128             }
129
130             p.addLast(new HttpClientCodec());
131
132             // Remove the following line if you don't want automatic content
133             // decompression.
134             p.addLast(new HttpContentDecompressor());
135
136             // Uncomment the following line if you don't want to handle
137             // HttpContents.
138             // p.addLast(new HttpObjectAggregator(1048576));
139
140             p.addLast(new HttpSnoopClientHandler());
141         }
142     }
143
144     public void connect(String strUrl)
145             throws URISyntaxException, InterruptedException, SSLException {
146         URI uri = new URI(strUrl);
147
148         String scheme = uri.getScheme() == null ? "http" : uri.getScheme();
149         String host = uri.getHost() == null ? "127.0.0.1" : uri.getHost();
150
151         int port = uri.getPort();
152
153         if (port == -1) {
154             if ("http".equalsIgnoreCase(scheme)) {
155                 port = 80;
156             } else if ("https".equalsIgnoreCase(scheme)) {
157                 port = 443;
158             }
159         }
160
161         if (!"http".equalsIgnoreCase(scheme)
162                 && !"https".equalsIgnoreCase(scheme)) {
163             return;
164         }
165
166         final boolean ssl = "https".equalsIgnoreCase(scheme);
167         final SslContext sslCtx;
168
169         if (ssl) {
170             sslCtx = SslContextBuilder.forClient()
171                     .trustManager(InsecureTrustManagerFactory.INSTANCE).build();
172         } else {
173             sslCtx = null;
174         }
175
176         EventLoopGroup group = new NioEventLoopGroup();
177
178         try {
179             Bootstrap b = new Bootstrap();
180             b.group(group);
181             b.channel(NioSocketChannel.class);
182             b.handler(new HttpClientInitializer(sslCtx));
183
184             Channel ch = b.connect(host, port).sync().channel();
185
186             HttpRequest request = new DefaultFullHttpRequest(
187                     HttpVersion.HTTP_1_1, HttpMethod.GET, uri.getRawPath());
188             request.headers().set(HttpHeaders.Names.HOST, host);
189             request.headers().set(HttpHeaders.Names.CONNECTION,
190                     HttpHeaders.Values.CLOSE);
191             request.headers().set(HttpHeaders.Names.ACCEPT_ENCODING,
192                     HttpHeaders.Values.GZIP);
193
194             request.headers().set(HttpHeaders.Names.COOKIE,
195                     ClientCookieEncoder.encode(
196                             new DefaultCookie("my-cookie", "foo"),
197                             new DefaultCookie("another-cookie", "bar")));
198
199             ch.writeAndFlush(request);
200
201             ch.closeFuture().sync();
202         } finally {
203             group.shutdownGracefully();
204         }
205     }
206
207 }