diff --git a/gdk/broadway/broadway.js b/gdk/broadway/broadway.js
index 357620e..90b9d53 100644
--- a/gdk/broadway/broadway.js
+++ b/gdk/broadway/broadway.js
@@ -2769,10 +2769,19 @@ function connect()
 	    useToplevelWindows = true;
     }
 
+    var loc = window.location.toString().replace("http:", "ws:");
+    loc = loc.substr(0, loc.lastIndexOf('/')) + "/socket";
+    var ws = null;
+
     if ("WebSocket" in window) {
-	var loc = window.location.toString().replace("http:", "ws:");
-	loc = loc.substr(0, loc.lastIndexOf('/')) + "/socket";
-	var ws = new WebSocket(loc, "broadway");
+	ws = new WebSocket(loc, "broadway");
+    } else if ("MozWebSocket" in window) { // Firefox 6
+	ws = new MozWebSocket(loc);
+    } else {
+	alert("WebSocket not supported, input will not work!");
+	return;
+    }
+
 	ws.onopen = function() {
 	    inputSocket = ws;
 	    var w, h;
@@ -2797,9 +2806,7 @@ function connect()
 	ws.onmessage = function(event) {
 	    handleMessage(event.data);
 	};
-    } else {
-	alert("WebSocket not supported, input will not work!");
-    }
+
     setupDocument(document);
     window.onunload = function (ev) {
 	for (var i = 0; i < toplevelWindows.length; i++)
diff --git a/gdk/broadway/gdkdisplay-broadway.c b/gdk/broadway/gdkdisplay-broadway.c
index 6a8ca21..b984e4f 100644
--- a/gdk/broadway/gdkdisplay-broadway.c
+++ b/gdk/broadway/gdkdisplay-broadway.c
@@ -537,6 +537,57 @@ send_error (HttpRequest *request,
   http_request_free (request);
 }
 
+//borrowed from http://linuxfirmwarekit.googlecode.com/svn/trunk/plugins.c (LGPL)
+guchar *
+_hex_string_to_ascii_string (gchar *string)
+{
+  guchar *buffer;
+  int count = 0;
+
+  buffer = g_malloc (strlen (string) + 1);
+  while (*string) {
+    int value = 0;
+    int c = *string;
+    if ((c>='0') && (c<='9'))
+      value = c-'0';
+    if ((c>='A') && (c<='F'))
+      value = 10+(c-'A');
+    if ((c>='a') && (c<='f'))
+      value = 10+(c-'a');
+    string++;
+    if (! *string)
+      break;
+    c = *string;
+    value = value << 4;
+    if ((c>='0') && (c<='9'))
+      value |= c-'0';
+    if ((c>='A') && (c<='F'))
+      value |= 10+c-'A';
+    if ((c>='a') && (c<='f'))
+      value |= 10+c-'a';
+    buffer[count++] = value;
+    string++;
+  }
+  buffer[count++] = '\0';
+  return buffer;
+}
+
+gchar *
+_generate_handshake_response_wsietf_v7 (const gchar *key) {
+  const char* full_key = g_strconcat (key, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", NULL);
+  gchar* sha1_result = g_compute_checksum_for_data (G_CHECKSUM_SHA1, 
+                                                    (const guchar *)full_key,
+                                                    strlen (full_key));
+  const guchar* decoded = _hex_string_to_ascii_string (sha1_result);
+  gchar* result = g_base64_encode (decoded, (int)strlen (sha1_result) / 2);
+
+  g_free ((gpointer)full_key);
+  g_free ((gpointer)sha1_result);
+  g_free ((gpointer)decoded);
+
+  return result;
+}
+
 static void
 start_input (HttpRequest *request)
 {
@@ -556,6 +607,7 @@ start_input (HttpRequest *request)
   const void *data_buffer;
   gsize data_buffer_size;
   GInputStream *in;
+  char *key_v7;
 
   broadway_display = GDK_BROADWAY_DISPLAY (request->display);
 
@@ -605,6 +657,10 @@ start_input (HttpRequest *request)
 	  key2 /= num_space;
 	  num_key2++;
 	}
+      else if ((p = parse_line (lines[i], "Sec-WebSocket-Key")))
+	{
+	  key_v7 = p;
+	}
       else if ((p = parse_line (lines[i], "Origin")))
 	{
 	  origin = p;
@@ -615,6 +671,22 @@ start_input (HttpRequest *request)
 	}
     }
 
+  if (key_v7 != NULL)
+    {
+      char* accept = _generate_handshake_response_wsietf_v7 (key_v7);
+      res = g_strdup_printf ("HTTP/1.1 101 Switching Protocols\r\n"
+			 "Upgrade: websocket\r\n"
+			 "Connection: Upgrade\r\n"
+			 "Sec-WebSocket-Accept: %s\r\n"
+			 "\r\n"
+			 "\r\n", accept);
+
+      g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
+			     res, strlen (res), NULL, NULL, NULL);
+      g_free (res);
+    }
+  else
+    {
   if (num_key1 != 1 || num_key2 != 1 || origin == NULL || host == NULL)
     {
       g_strfreev (lines);
@@ -658,6 +730,7 @@ start_input (HttpRequest *request)
   g_free (res);
   g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
 			     challenge, 16, NULL, NULL, NULL);
+    }
 
   input = g_new0 (BroadwayInput, 1);
 
