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