[hornetq-commits] JBoss hornetq SVN: r9511 - trunk/src/main/org/hornetq/core/protocol/stomp.

do-not-reply at jboss.org do-not-reply at jboss.org
Thu Aug 5 10:54:37 EDT 2010


Author: jmesnil
Date: 2010-08-05 10:54:37 -0400 (Thu, 05 Aug 2010)
New Revision: 9511

Modified:
   trunk/src/main/org/hornetq/core/protocol/stomp/WebSocketServerHandler.java
Log:
Web Sockets support

* support both draft versions of Web Sockets protocol

Modified: trunk/src/main/org/hornetq/core/protocol/stomp/WebSocketServerHandler.java
===================================================================
--- trunk/src/main/org/hornetq/core/protocol/stomp/WebSocketServerHandler.java	2010-08-05 14:54:07 UTC (rev 9510)
+++ trunk/src/main/org/hornetq/core/protocol/stomp/WebSocketServerHandler.java	2010-08-05 14:54:37 UTC (rev 9511)
@@ -15,6 +15,9 @@
  */
 package org.hornetq.core.protocol.stomp;
 
+import java.security.MessageDigest;
+
+import org.jboss.netty.buffer.ChannelBuffer;
 import org.jboss.netty.buffer.ChannelBuffers;
 import org.jboss.netty.channel.ChannelFuture;
 import org.jboss.netty.channel.ChannelFutureListener;
@@ -26,6 +29,8 @@
 import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
 import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
 import org.jboss.netty.handler.codec.http.HttpHeaders;
+import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
+import org.jboss.netty.handler.codec.http.HttpHeaders.Values;
 import org.jboss.netty.handler.codec.http.HttpMethod;
 import org.jboss.netty.handler.codec.http.HttpRequest;
 import org.jboss.netty.handler.codec.http.HttpResponse;
@@ -36,10 +41,10 @@
 import org.jboss.netty.util.CharsetUtil;
 
 /**
- * @author The Netty Project (netty-dev at lists.jboss.org)
- * @author Trustin Lee (trustin at gmail.com)
+ * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
+ * @author <a href="http://gleamynode.net/">Trustin Lee</a>
  *
- * @version $Rev$, $Date$
+ * @version $Rev: 2314 $, $Date: 2010-06-22 09:02:27 +0200 (Mar, 22 jui 2010) $
  */
 public class WebSocketServerHandler extends SimpleChannelUpstreamHandler {
 
@@ -55,31 +60,58 @@
         }
     }
 
-    private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) {
+    private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
         // Allow only GET methods.
         if (req.getMethod() != HttpMethod.GET) {
             sendHttpResponse(
-                    ctx, req, new DefaultHttpResponse(
-                            HttpVersion.HTTP_1_1, HttpResponseStatus.FORBIDDEN));
+                    ctx, req, new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.FORBIDDEN));
             return;
         }
 
         // Serve the WebSocket handshake request.
         if (req.getUri().equals(WEBSOCKET_PATH) &&
-            HttpHeaders.Values.UPGRADE.equalsIgnoreCase(req.getHeader(HttpHeaders.Names.CONNECTION)) &&
-            HttpHeaders.Values.WEBSOCKET.equalsIgnoreCase(req.getHeader(HttpHeaders.Names.UPGRADE))) {
+            Values.UPGRADE.equalsIgnoreCase(req.getHeader(Names.CONNECTION)) &&
+            Values.WEBSOCKET.equalsIgnoreCase(req.getHeader(Names.UPGRADE))) {
 
             // Create the WebSocket handshake response.
             HttpResponse res = new DefaultHttpResponse(
                     HttpVersion.HTTP_1_1,
                     new HttpResponseStatus(101, "Web Socket Protocol Handshake"));
-            res.addHeader(HttpHeaders.Names.UPGRADE, HttpHeaders.Values.WEBSOCKET);
-            res.addHeader(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.UPGRADE);
-            res.addHeader(HttpHeaders.Names.WEBSOCKET_ORIGIN, req.getHeader(HttpHeaders.Names.ORIGIN));
-            res.addHeader(HttpHeaders.Names.WEBSOCKET_LOCATION, getWebSocketLocation(req));
-            String protocol = req.getHeader(HttpHeaders.Names.WEBSOCKET_PROTOCOL);
-            if (protocol != null) {
-                res.addHeader(HttpHeaders.Names.WEBSOCKET_PROTOCOL, protocol);
+            res.addHeader(Names.UPGRADE, Values.WEBSOCKET);
+            res.addHeader(Names.CONNECTION, Values.UPGRADE);
+
+            // Fill in the headers and contents depending on handshake method.
+            if (req.containsHeader(Names.SEC_WEBSOCKET_KEY1) &&
+                req.containsHeader(Names.SEC_WEBSOCKET_KEY2)) {
+                // New handshake method with a challenge:
+                res.addHeader(Names.SEC_WEBSOCKET_ORIGIN, req.getHeader(Names.ORIGIN));
+                res.addHeader(Names.SEC_WEBSOCKET_LOCATION, getWebSocketLocation(req));
+                String protocol = req.getHeader(Names.SEC_WEBSOCKET_PROTOCOL);
+                if (protocol != null) {
+                    res.addHeader(Names.SEC_WEBSOCKET_PROTOCOL, protocol);
+                }
+
+                // Calculate the answer of the challenge.
+                String key1 = req.getHeader(Names.SEC_WEBSOCKET_KEY1);
+                String key2 = req.getHeader(Names.SEC_WEBSOCKET_KEY2);
+                int a = (int) (Long.parseLong(key1.replaceAll("[^0-9]", "")) / key1.replaceAll("[^ ]", "").length());
+                int b = (int) (Long.parseLong(key2.replaceAll("[^0-9]", "")) / key2.replaceAll("[^ ]", "").length());
+                long c = req.getContent().readLong();
+                ChannelBuffer input = ChannelBuffers.buffer(16);
+                input.writeInt(a);
+                input.writeInt(b);
+                input.writeLong(c);
+                ChannelBuffer output = ChannelBuffers.wrappedBuffer(
+                        MessageDigest.getInstance("MD5").digest(input.array()));
+                res.setContent(output);
+            } else {
+                // Old handshake method with no challenge:
+                res.addHeader(Names.WEBSOCKET_ORIGIN, req.getHeader(Names.ORIGIN));
+                res.addHeader(Names.WEBSOCKET_LOCATION, getWebSocketLocation(req));
+                String protocol = req.getHeader(Names.WEBSOCKET_PROTOCOL);
+                if (protocol != null) {
+                    res.addHeader(Names.WEBSOCKET_PROTOCOL, protocol);
+                }
             }
 
             // Upgrade the connection and send the handshake response.
@@ -95,8 +127,7 @@
 
         // Send an error page otherwise.
         sendHttpResponse(
-                ctx, req, new DefaultHttpResponse(
-                        HttpVersion.HTTP_1_1, HttpResponseStatus.FORBIDDEN));
+                ctx, req, new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.FORBIDDEN));
     }
 
     private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
@@ -110,9 +141,7 @@
             res.setContent(
                     ChannelBuffers.copiedBuffer(
                             res.getStatus().toString(), CharsetUtil.UTF_8));
-            res.setHeader(
-                    HttpHeaders.Names.CONTENT_LENGTH,
-                    Integer.toString(res.getContent().readableBytes()));
+            HttpHeaders.setContentLength(res, res.getContent().readableBytes());
         }
 
         // Send the response and close the connection if necessary.
@@ -132,4 +161,4 @@
     private String getWebSocketLocation(HttpRequest req) {
         return "ws://" + req.getHeader(HttpHeaders.Names.HOST) + WEBSOCKET_PATH;
     }
-}
\ No newline at end of file
+}



More information about the hornetq-commits mailing list