diff --git a/gdk/broadway/broadway.c b/gdk/broadway/broadway.c
index e9bc2d5..f35e01b 100644
--- a/gdk/broadway/broadway.c
+++ b/gdk/broadway/broadway.c
@@ -178,23 +178,61 @@ struct BroadwayOutput {
   gboolean proto_v7_plus;
 };
 
+typedef enum {
+  Continuation = 0,
+  Text = 1,
+  Binary = 2,
+  CnxClose = 8
+} WS17OpCode;
+
 static void
-broadway_output_write_header (BroadwayOutput *output)
-{
-  if (!output->proto_v7_plus)
-    g_output_stream_write (output->out, "\0", 1, NULL, NULL);
-  else
+broadway_output_send_cmd (BroadwayOutput *output,
+			  gboolean fin, WS17OpCode code,
+			  const void *buf, gsize count)
+{
+  gboolean mask = FALSE;
+  guchar header[16];
+  size_t p;
+
+  gboolean mid_header = count > 125 && count <= 65535;
+  gboolean long_header = count > 65535;
+  header[0] = ( (fin ? 1 : 0) |
+		(code << 4) );
+  header[1] = ( (mask ? 1 : 0) |
+		(mid_header ? 126 : long_header ? 127 : count) << 1 );
+  g_warning ("header 0x%2x 0x%2x\n", header[0], header[1]);
+  p = 2;
+  if (mid_header)
+    {
+      *(guint16 *)(header + p) = GUINT16_TO_BE( (guint16)count );
+      p += 2;
+    }
+  else if (long_header)
     {
+      *(guint64 *)(header + p) = GUINT64_TO_BE( count );
+      p += 8;
     }
+  // FIXME: we should really write these as a single write
+  g_output_stream_write_all (output->out, header, p, NULL, NULL, NULL);
+  g_output_stream_write_all (output->out, buf, count, NULL, NULL, NULL);
 }
 
 static void
-broadway_output_write (BroadwayOutput *output,
-		       const void *buf, gsize count)
+broadway_output_sendmsg (BroadwayOutput *output,
+			 const void *buf, gsize count)
 {
   if (!output->proto_v7_plus)
     g_output_stream_write_all (output->out, buf, count, NULL, NULL, NULL);
   else
+    broadway_output_send_cmd (output, TRUE, Binary, buf, count);
+}
+
+static void
+broadway_output_sendmsg_initiate (BroadwayOutput *output)
+{
+  if (!output->proto_v7_plus)
+    g_output_stream_write (output->out, "\0", 1, NULL, NULL);
+  else
     {
     }
 }
@@ -204,12 +242,15 @@ broadway_output_flush (BroadwayOutput *output)
 {
   if (!output->proto_v7_plus)
     {
-      broadway_output_write (output, "\xff", 1);
-      broadway_output_write (output, "\0", 1);
+      broadway_output_sendmsg (output, "\xff", 1);
+      broadway_output_sendmsg (output, "\0", 1);
       return !output->error;
     }
   else
     {
+      g_warning ("FIXME - is this really what we want ?");
+//      broadway_output_send_cmd (output, TRUE, CnxClose, NULL, 0);
+      return !output->error;
     }
 }
 
@@ -225,7 +266,7 @@ broadway_output_new(GOutputStream *out, guint32 serial,
   output->serial = serial;
   output->proto_v7_plus = proto_v7_plus;
 
-  broadway_output_write_header (output);
+  broadway_output_sendmsg_initiate (output);
 
   return output;
 }
@@ -302,7 +343,7 @@ broadway_output_copy_rectangles (BroadwayOutput *output,  int id,
 
   assert (p == len);
 
-  broadway_output_write (output, buf, len);
+  broadway_output_sendmsg (output, buf, len);
   free (buf);
 }
 
@@ -320,7 +361,7 @@ broadway_output_grab_pointer (BroadwayOutput *output,
 
   assert (p == sizeof (buf));
 
-  broadway_output_write (output, buf, sizeof (buf));
+  broadway_output_sendmsg (output, buf, sizeof (buf));
 }
 
 guint32
@@ -335,7 +376,7 @@ broadway_output_ungrab_pointer (BroadwayOutput *output)
 
   assert (p == sizeof (buf));
 
-  broadway_output_write (output, buf, sizeof (buf));
+  broadway_output_sendmsg (output, buf, sizeof (buf));
 
   return serial;
 }
@@ -358,7 +399,7 @@ broadway_output_new_surface(BroadwayOutput *output,
 
   assert (p == sizeof (buf));
 
-  broadway_output_write (output, buf, sizeof (buf));
+  broadway_output_sendmsg (output, buf, sizeof (buf));
 }
 
 void
@@ -372,7 +413,7 @@ broadway_output_show_surface(BroadwayOutput *output,  int id)
 
   assert (p == sizeof (buf));
 
-  broadway_output_write (output, buf, sizeof (buf));
+  broadway_output_sendmsg (output, buf, sizeof (buf));
 }
 
 void
@@ -386,7 +427,7 @@ broadway_output_hide_surface(BroadwayOutput *output,  int id)
 
   assert (p == sizeof (buf));
 
-  broadway_output_write (output, buf, sizeof (buf));
+  broadway_output_sendmsg (output, buf, sizeof (buf));
 }
 
 void
@@ -400,7 +441,7 @@ broadway_output_destroy_surface(BroadwayOutput *output,  int id)
 
   assert (p == sizeof (buf));
 
-  broadway_output_write (output, buf, sizeof (buf));
+  broadway_output_sendmsg (output, buf, sizeof (buf));
 }
 
 
@@ -438,7 +479,7 @@ broadway_output_move_resize_surface (BroadwayOutput *output,
     }
   assert (p <= sizeof (buf));
 
-  broadway_output_write (output, buf, p);
+  broadway_output_sendmsg (output, buf, p);
 }
 
 void
@@ -456,7 +497,7 @@ broadway_output_set_transient_for (BroadwayOutput *output,
 
   assert (p == sizeof (buf));
 
-  broadway_output_write (output, buf, sizeof (buf));
+  broadway_output_sendmsg (output, buf, sizeof (buf));
 }
 
 
@@ -464,27 +505,31 @@ void
 broadway_output_put_rgb (BroadwayOutput *output,  int id, int x, int y,
 			 int w, int h, int byte_stride, void *data)
 {
-  char buf[HEADER_LEN + 15];
-  gsize len;
-  char *url;
+  gsize buf_size;
+  gsize url_len;
+  char *url, *buf;
   int p;
 
+  url = to_png_rgb (w, h, byte_stride, (guint32*)data);
+  url_len = strlen (url);
+
+  buf_size = HEADER_LEN + 15 + url_len;
+  buf = g_malloc (buf_size);
+
   p = write_header (output, buf, 'i');
 
   append_uint16 (id, buf, &p);
   append_uint16 (x, buf, &p);
   append_uint16 (y, buf, &p);
 
-  url = to_png_rgb (w, h, byte_stride, (guint32*)data);
-  len = strlen (url);
-  append_uint32 (len, buf, &p);
+  append_uint32 (url_len, buf, &p);
 
-  assert (p == sizeof (buf));
+  g_assert (p == HEADER_LEN + 15);
+  strncpy (buf + p, url, url_len);
 
-  broadway_output_write (output, buf, sizeof (buf));
-
-  broadway_output_write (output, url, len);
+  broadway_output_sendmsg (output, buf, buf_size);
 
+  g_free (buf);
   free (url);
 }
 
@@ -715,8 +760,6 @@ void
 broadway_output_put_rgba (BroadwayOutput *output,  int id, int x, int y,
 			  int w, int h, int byte_stride, void *data)
 {
-  char buf[HEADER_LEN + 15];
-  gsize len;
   char *url;
   BroadwayBox *rects;
   int p, i, n_rects;
@@ -726,6 +769,13 @@ broadway_output_put_rgba (BroadwayOutput *output,  int id, int x, int y,
 
   for (i = 0; i < n_rects; i++)
     {
+      gsize url_len, buf_size;
+      char *buf;
+
+      url_len = strlen (url);
+      buf_size = HEADER_LEN + 15 + url_len;
+      buf = g_malloc (buf_size);
+
       subdata = (guint8 *)data + rects[i].x1 * 4 + rects[i].y1 * byte_stride;
 
       p = write_header (output, buf, 'i');
@@ -736,16 +786,14 @@ broadway_output_put_rgba (BroadwayOutput *output,  int id, int x, int y,
       url = to_png_rgba (rects[i].x2 - rects[i].x1,
 			 rects[i].y2 - rects[i].y1,
 			 byte_stride, (guint32*)subdata);
-      len = strlen (url);
-      append_uint32 (len, buf, &p);
-
-      assert (p == sizeof (buf));
-
-      broadway_output_write (output, buf, sizeof (buf));
+      append_uint32 (url_len, buf, &p);
+      g_assert (p == HEADER_LEN + 15);
+      strncpy (buf + p, url, url_len);
 
-      broadway_output_write (output, url, len);
+      broadway_output_sendmsg (output, buf, buf_size);
 
       free (url);
+      g_free (buf);
     }
 
   free (rects);
@@ -761,35 +809,7 @@ broadway_output_surface_flush (BroadwayOutput *output,
   p = write_header (output, buf, 'f');
   append_uint16 (id, buf, &p);
 
-  assert (p == sizeof (buf));
+  g_assert (p == sizeof (buf));
 
-  broadway_output_write (output, buf, sizeof (buf));
+  broadway_output_sendmsg (output, buf, sizeof (buf));
 }
-
-#if 0
-static void
-send_image_a (BroadwayOutput *output,  int id, int x, int y,
-	      int w, int h, int byte_stride, guint8 *data)
-{
-  char buf[HEADER_LEN + 15];
-  gsize len;
-  char *url;
-
-  p = write_header (output, buf, 'i');
-  append_uint16 (id, buf, &p);
-  append_uint16 (x, buf, &p);
-  append_uint16 (y, buf, &p);
-
-  url = to_png_a (w, h, byte_stride, data);
-  len = strlen (url);
-  append_uint32 (len, buf, &p);
-
-  assert (p == sizeof (buf));
-
-  broadway_output_write (output, buf, sizeof (buf));
-
-  broadway_output_write (output, url, len);
-
-  free (url);
-}
-#endif
diff --git a/gdk/broadway/gdkdisplay-broadway.c b/gdk/broadway/gdkdisplay-broadway.c
index 76e7486..6496cb6 100644
--- a/gdk/broadway/gdkdisplay-broadway.c
+++ b/gdk/broadway/gdkdisplay-broadway.c
@@ -557,7 +557,8 @@ generate_handshake_response_wsietf_v7 (const gchar *key)
 
   g_checksum_update (checksum, full_key, strlen ((char *)full_key));
 
-  digest = g_alloca (g_checksum_type_get_length (G_CHECKSUM_SHA1) + 1);
+  digest_len = g_checksum_type_get_length (G_CHECKSUM_SHA1) + 1;
+  digest = g_alloca (digest_len);
   g_checksum_get_digest (checksum, digest, &digest_len);
   g_checksum_free (checksum);
   gchar* result = g_base64_encode (digest, digest_len);
@@ -597,6 +598,7 @@ start_input (HttpRequest *request)
       return;
     }
 
+  g_warning ("request '%s'\n", request->request->str);
   lines = g_strsplit (request->request->str, "\n", 0);
 
   num_key1 = 0;
