1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.jboss.netty.example.http.snoop;
17
18 import static org.jboss.netty.handler.codec.http.HttpHeaders.*;
19 import static org.jboss.netty.handler.codec.http.HttpHeaders.Names.*;
20 import static org.jboss.netty.handler.codec.http.HttpResponseStatus.*;
21 import static org.jboss.netty.handler.codec.http.HttpVersion.*;
22
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Map.Entry;
26 import java.util.Set;
27
28 import org.jboss.netty.buffer.ChannelBuffer;
29 import org.jboss.netty.buffer.ChannelBuffers;
30 import org.jboss.netty.channel.ChannelFuture;
31 import org.jboss.netty.channel.ChannelFutureListener;
32 import org.jboss.netty.channel.ChannelHandlerContext;
33 import org.jboss.netty.channel.ExceptionEvent;
34 import org.jboss.netty.channel.MessageEvent;
35 import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
36 import org.jboss.netty.handler.codec.http.Cookie;
37 import org.jboss.netty.handler.codec.http.CookieDecoder;
38 import org.jboss.netty.handler.codec.http.CookieEncoder;
39 import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
40 import org.jboss.netty.handler.codec.http.HttpChunk;
41 import org.jboss.netty.handler.codec.http.HttpChunkTrailer;
42 import org.jboss.netty.handler.codec.http.HttpRequest;
43 import org.jboss.netty.handler.codec.http.HttpResponse;
44 import org.jboss.netty.handler.codec.http.QueryStringDecoder;
45 import org.jboss.netty.util.CharsetUtil;
46
47
48
49
50
51
52
53
54 public class HttpRequestHandler extends SimpleChannelUpstreamHandler {
55
56 private HttpRequest request;
57 private boolean readingChunks;
58
59 private final StringBuilder buf = new StringBuilder();
60
61 @Override
62 public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
63 if (!readingChunks) {
64 HttpRequest request = this.request = (HttpRequest) e.getMessage();
65
66 if (is100ContinueExpected(request)) {
67 send100Continue(e);
68 }
69
70 buf.setLength(0);
71 buf.append("WELCOME TO THE WILD WILD WEB SERVER\r\n");
72 buf.append("===================================\r\n");
73
74 buf.append("VERSION: " + request.getProtocolVersion() + "\r\n");
75 buf.append("HOSTNAME: " + getHost(request, "unknown") + "\r\n");
76 buf.append("REQUEST_URI: " + request.getUri() + "\r\n\r\n");
77
78 for (Map.Entry<String, String> h: request.getHeaders()) {
79 buf.append("HEADER: " + h.getKey() + " = " + h.getValue() + "\r\n");
80 }
81 buf.append("\r\n");
82
83 QueryStringDecoder queryStringDecoder = new QueryStringDecoder(request.getUri());
84 Map<String, List<String>> params = queryStringDecoder.getParameters();
85 if (!params.isEmpty()) {
86 for (Entry<String, List<String>> p: params.entrySet()) {
87 String key = p.getKey();
88 List<String> vals = p.getValue();
89 for (String val : vals) {
90 buf.append("PARAM: " + key + " = " + val + "\r\n");
91 }
92 }
93 buf.append("\r\n");
94 }
95
96 if (request.isChunked()) {
97 readingChunks = true;
98 } else {
99 ChannelBuffer content = request.getContent();
100 if (content.readable()) {
101 buf.append("CONTENT: " + content.toString(CharsetUtil.UTF_8) + "\r\n");
102 }
103 writeResponse(e);
104 }
105 } else {
106 HttpChunk chunk = (HttpChunk) e.getMessage();
107 if (chunk.isLast()) {
108 readingChunks = false;
109 buf.append("END OF CONTENT\r\n");
110
111 HttpChunkTrailer trailer = (HttpChunkTrailer) chunk;
112 if (!trailer.getHeaderNames().isEmpty()) {
113 buf.append("\r\n");
114 for (String name: trailer.getHeaderNames()) {
115 for (String value: trailer.getHeaders(name)) {
116 buf.append("TRAILING HEADER: " + name + " = " + value + "\r\n");
117 }
118 }
119 buf.append("\r\n");
120 }
121
122 writeResponse(e);
123 } else {
124 buf.append("CHUNK: " + chunk.getContent().toString(CharsetUtil.UTF_8) + "\r\n");
125 }
126 }
127 }
128
129 private void writeResponse(MessageEvent e) {
130
131 boolean keepAlive = isKeepAlive(request);
132
133
134 HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
135 response.setContent(ChannelBuffers.copiedBuffer(buf.toString(), CharsetUtil.UTF_8));
136 response.setHeader(CONTENT_TYPE, "text/plain; charset=UTF-8");
137
138 if (keepAlive) {
139
140 response.setHeader(CONTENT_LENGTH, response.getContent().readableBytes());
141 }
142
143
144 String cookieString = request.getHeader(COOKIE);
145 if (cookieString != null) {
146 CookieDecoder cookieDecoder = new CookieDecoder();
147 Set<Cookie> cookies = cookieDecoder.decode(cookieString);
148 if(!cookies.isEmpty()) {
149
150 CookieEncoder cookieEncoder = new CookieEncoder(true);
151 for (Cookie cookie : cookies) {
152 cookieEncoder.addCookie(cookie);
153 }
154 response.addHeader(SET_COOKIE, cookieEncoder.encode());
155 }
156 }
157
158
159 ChannelFuture future = e.getChannel().write(response);
160
161
162 if (!keepAlive) {
163 future.addListener(ChannelFutureListener.CLOSE);
164 }
165 }
166
167 private void send100Continue(MessageEvent e) {
168 HttpResponse response = new DefaultHttpResponse(HTTP_1_1, CONTINUE);
169 e.getChannel().write(response);
170 }
171
172 @Override
173 public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e)
174 throws Exception {
175 e.getCause().printStackTrace();
176 e.getChannel().close();
177 }
178 }