diff --git a/lib/modules/Protocols.pmod/WebSocket.pmod b/lib/modules/Protocols.pmod/WebSocket.pmod
index 2fc6657a7501bcbaf1801675a83f09dba461e0bb..36f9c599b66d61dbcaf722c53ebe5564284d0293 100644
--- a/lib/modules/Protocols.pmod/WebSocket.pmod
+++ b/lib/modules/Protocols.pmod/WebSocket.pmod
@@ -62,20 +62,6 @@ enum CLOSE_STATUS {
     CLOSE_UNEXPECTED,
 };
 
-//! WebSocket RSV extension bits.
-enum RSV {
-
-    //!
-    RSV1 = 0x40,
-
-    //!
-    RSV2 = 0x20,
-
-    //!
-    RSV3 = 0x10
-
-};
-
 //! WebSocket frame compression heuristics override
 enum COMPRESSION {
 
@@ -87,19 +73,6 @@ enum COMPRESSION {
 
 };
 
-//! Global default options for all WebSocket connections.
-mapping(string:mixed) options = ([
-#if constant(Gz.deflate)
-    "compressionLevel":3,
-    "compressionThreshold":5,
-    "compressionThresholdNoContext":256,
-    "compressionStrategy":Gz.DEFAULT_STRATEGY,
-    "compressionWindowSize":15,
-    "decompressionWindowSize":15,
-    "compressionHeuristics":HEURISTICS_COMPRESS,
-#endif
-]);
-
 #define FOO(x)  if (op == x) return #x
 string describe_opcode(FRAME op) {
     FOO(FRAME_CONTINUATION);
@@ -123,7 +96,7 @@ class Parser {
 
     //! Parses and returns one WebSocket frame from the internal buffer. If
     //! the buffer does not contain a full frame, @expr{0@} is returned.
-    Frame parse(Connection con) {
+    Frame parse() {
 	if (sizeof(buf) < 2) return 0;
 
 	int opcode, len, hlen = 2;
@@ -165,38 +138,13 @@ class Parser {
 
         Frame f = Frame(opcode & 15);
         f->fin = opcode >> 7;
-        f->rsv = opcode;
-        if (con.lastopcode & 0x80)	       // FIN
-            con.firstrsv = opcode;
-        con.lastopcode = opcode;
         f->mask = mask;
 
         data = buf->read(len);
 
-        if (masked)
+        if (masked) {
             data = MASK(data, mask);
-
-#if constant(Gz.deflate)
-        mapping options = con.options;
-        if (options->compressionLevel && con.firstrsv & RSV1 && sizeof(data)) {
-            f->rsv &= ~RSV1;
-            Gz.inflate uncompress = con.uncompress;
-            if (!uncompress)
-                uncompress = Gz.inflate(-options->decompressionWindowSize);
-            data = uncompress.inflate(data + "\0\0\377\377");
-            string s;
-            while (s = uncompress.end_of_stream()) {
-                // FIXME uncompress.create(...) should have been sufficient.
-                // Probably due to an upstream bug in zlib, this does not work.
-                uncompress = Gz.inflate(-options->decompressionWindowSize);
-                if (s != "\0\0\377\377")
-                    data += uncompress.inflate(s);
-            }
-            if (options->decompressionNoContextTakeover)
-              uncompress = 0;	      // Save memory between packets
-            con.uncompress = uncompress;
         }
-#endif
 
         f->data = data;
 
@@ -212,11 +160,6 @@ class Frame {
     //! fragmented message or a non-fragmentation frame.
     int(0..1) fin = 1;
 
-    //! Three reserved extension bits.  Binary-and with @expr{RSV1@},
-    //! @expr{RSV2@} or @expr{RSV3@} to single out the corresponding
-    //! extension.  Typically @expr{RSV1@} is set for compressed frames.
-    int rsv;
-
     //! Generic options for this frame.
     mapping(string:mixed) options;
 
@@ -256,10 +199,8 @@ class Frame {
     }
 
     protected string _sprintf(int type) {
-      return type=='O' && sprintf("%O(%s, fin: %d, rsv: %d, %d bytes)",
-                       this_program,
-                       describe_opcode(opcode), fin, rsv & (RSV1|RSV2|RSV3),
-                       sizeof(data));
+      return type=='O' && sprintf("%O(%s, fin: %d, %d bytes)", this_program,
+                       describe_opcode(opcode), fin, sizeof(data));
     }
 
     //! @decl string text
@@ -298,7 +239,7 @@ class Frame {
 
     //!
     void encode(Stdio.Buffer buf) {
-        buf->add_int8(fin << 7 | rsv | opcode);
+        buf->add_int8(fin << 7 | opcode);
 
         if (sizeof(data) > 0xffff) {
             buf->add_int8(!!mask << 7 | 127);
@@ -346,16 +287,6 @@ class Connection {
     protected int(0..1) will_write = 1;
     protected mixed id;
 
-    mapping options;
-
-#if constant(Gz.deflate)
-    final Gz.inflate uncompress;
-    private Gz.deflate compress;
-#endif
-
-    final int lastopcode = 0x80;   // FIN
-    final int firstrsv;
-
     //! If true, all outgoing frames are masked.
     int(0..1) masking;
 
@@ -388,17 +319,14 @@ class Connection {
 
     //! Create a WebSocket client
     protected void create() {
-      options = ([]);
 	  // Clients start in state CLOSED.
       state = CLOSED;
-      masking = 1;
+	  masking = 1;
       parser = Parser();
     }
 
     //! Create a WebSocket server out of the given Stdio.File-like object
-    protected variant void create(Stdio.File|SSL.File f,
-     void|mapping _options) {
-        options = .WebSocket.options + (_options || ([]));
+    protected variant void create(Stdio.File|SSL.File f) {
         state = CONNECTING;
         parser = Parser();
         stream = f;
@@ -585,7 +513,7 @@ class Connection {
         if (state == CLOSED) return;
         parser->feed(data);
 
-        while (Frame frame = parser->parse(this)) {
+        while (Frame frame = parser->parse()) {
 #ifdef WEBSOCKET_DEBUG
             werror("%O in %O\n", this, frame);
 #endif
@@ -645,71 +573,9 @@ class Connection {
 
     //! Send a WebSocket frame.
     void send(Frame frame) {
-        if (state != OPEN)
-            error("WebSocket connection is not open: %O.\n", this);
-        if (sizeof(frame->data)) {
-            if (masking)
-                frame->mask = Crypto.Random.random_string(4);
-#if constant(Gz.deflate)
-            mapping(string:mixed) opts = options;
-            if (frame.options)
-              opts += frame.options;
-            if (opts->compressionLevel
-             && sizeof(frame->data) >=
-                 (opts->compressionNoContextTakeover
-                  ? opts->compressionThresholdNoContext
-                  : opts->compressionThreshold)) {
-                if (!compress)
-                    compress = Gz.deflate(-opts->compressionLevel,
-                     opts->compressionStrategy,
-                     opts->compressionWindowSize);
-                int wsize = opts->compressionWindowSize
-                 ? 1<<opts->compressionWindowSize : 1<<15;
-                if (opts->compressionNoContextTakeover) {
-                    string s
-                     = compress.deflate(frame->data, Gz.SYNC_FLUSH)[..<4];
-                    if (sizeof(s) < sizeof(frame->data)) {
-                        frame->data = s;
-                        frame->rsv |= RSV1;
-                    }
-                    compress = 0;
-                } else {
-                    if (opts->compressionHeuristics == OVERRIDE_COMPRESS
-                     || frame->opcode == FRAME_TEXT) {
-                        // Assume text frames are always compressible.
-                        frame->data
-                         = compress.deflate(frame->data, Gz.SYNC_FLUSH)[..<4];
-                        frame->rsv |= RSV1;
-                    } else if (4*sizeof(frame->data) <= wsize) {
-                        // If a binary frame is smaller than 25% of the
-                        // LZ77 window size, test if adding it to the
-                        // stream results in zero overhead.  If so, add it,
-                        // if not, reset compression state to before adding it.
-                        Gz.inflate save = compress.clone();
-                        string s
-                         = compress.deflate(frame->data, Gz.SYNC_FLUSH);
-                        if (sizeof(s) < sizeof(frame->data)) {
-                            frame->data = s[..<4];
-                            frame->rsv |= RSV1;
-                        } else
-                          compress = save;
-                    } else {
-                        // Large binary frames we sample the first 1KB of.
-                        // If it compresses better than 6.25%, add them
-                        // to the compressed stream.
-                        Gz.inflate ctest = compress.clone();
-                        string sold = frame->data[..1023];
-                        string s = ctest.deflate(sold, Gz.PARTIAL_FLUSH);
-                        if (sizeof(s) + 64 < sizeof(sold)) {
-                            frame->data = compress.deflate(frame->data,
-                             Gz.SYNC_FLUSH)[..<4];
-                            frame->rsv |= RSV1;
-                        }
-                    }
-                }
-            }
-#endif
-        }
+        if (state != OPEN) error("WebSocket connection is not open: %O.\n", this);
+        if (masking && sizeof(frame->data))
+            frame->mask = Crypto.Random.random_string(4);
         frame->encode(buf);
         if (frame->opcode == FRAME_CLOSE) {
             state = CLOSING;
@@ -757,122 +623,17 @@ class Request(function(array(string), Request:void) cb) {
     //! handshake. The protocol should be either @expr{0@} or a protocol
     //! advertised by the client when initiating the WebSocket connection.
     //! The returned connection object is in state @[Connection.OPEN].
-    Connection websocket_accept(string protocol, void|mapping _options) {
-        options += _options || ([]);
+    Connection websocket_accept(string protocol) {
 	string s = request_headers["sec-websocket-key"] + websocket_id;
 	mapping heads = ([
 	    "Upgrade" : "websocket",
 	    "Connection" : "Upgrade",
-	    "Sec-WebSocket-Accept" : MIME.encode_base64(Crypto.SHA1.hash(s)),
-            "Sec-WebSocket-Version" : "13",
+	    "sec-websocket-accept" : MIME.encode_base64(Crypto.SHA1.hash(s)),
+            "sec-websocket-version" : "13",
 	]);
+	if (protocol) heads["sec-websocket-protocol"] = protocol;
 
-        array parse_extensions() {
-          string exs;
-          array retval;
-          if (exs = request_headers["sec-websocket-extensions"]) {
-            // Parses extensions conforming RFCs, supports quoted values.
-            // FIXME Violates the RFC when commas or semicolons are quoted.
-            array v;
-            int i;
-            retval = array_sscanf(exs,
-             "%*[ \t\r\n]%{%{%[^ \t\r\n=;,]%*[= \t\r\n]%[^;,]%*[ \t\r\n;]%}"
-             "%*[ \t\r\n,]%}")[0];
-            foreach (retval; i; v) {
-              mapping m;
-              array d;
-              v = v[0];
-              retval[i] = ({v[0][0], m = ([])});
-              v = v[1..];
-              foreach (v;; d) {
-                string sv = String.trim_whites(d[1]);
-                if (sizeof(sv) && sv[0] == '"')
-                  sv = sv[1..<1];	    // Strip doublequotes
-                int|float|string tv;	    // Store numeric values natively
-                if ((string)(tv=(int)sv)!=sv && (string)(tv=(float)sv)!=sv)
-                  tv = sv;
-                m[d[0]] = tv;
-              }
-            }
-          } else
-            retval = ({});
-          return retval;
-        };
-
-        mapping rext = ([]);
-
-        // Code has been tuned for serverside.  If used as clientside,
-        // it will need tweaking.
-        foreach (parse_extensions();; array ext) {
-            string name = ext[0];
-            mapping parm = ext[1], rparm = ([]);
-            int|float|string p;
-            switch (name) {
-#if constant(Gz.deflate)
-                case "permessage-deflate":
-                    if (rext[name] || !options->compressionLevel)
-                        continue;
-                    if (parm->client_no_context_takeover
-                     || options->decompressionNoContextTakeover) {
-                        options->decompressionNoContextTakeover = 1;
-                        rparm->client_no_context_takeover = "";
-                    }
-                    if (stringp(p = parm->client_max_window_bits)) {
-                        if ((p = options->decompressionWindowSize) < 15)
-                            rparm->client_max_window_bits = p;
-                    } else if (!zero_type(p)) {
-                        p = min(p, options->decompressionWindowSize);
-                        options->decompressionWindowSize
-                         = max(rparm->client_max_window_bits = p, 8);
-                    }
-                    if (parm->server_no_context_takeover
-                     || options->compressionNoContextTakeover) {
-                        options->compressionNoContextTakeover = 1;
-                        rparm->server_no_context_takeover = "";
-                    }
-                    if (stringp(p = parm->server_max_window_bits)) {
-                        if ((p = options->compressionWindowSize) < 15)
-                        rparm->server_max_window_bits = p;
-                    } else if (!zero_type(p)) {
-                        p = min(p, options->compressionWindowSize);
-                        if (p < 8)
-                            continue;
-                        options->compressionWindowSize
-                         = rparm->server_max_window_bits = p;
-                    }
-                    rext[name] = rparm;
-                    break;
-#endif
-            }
-        }
-
-        if (sizeof(rext)) {
-            if (!rext["permessage-deflate"])
-                m_delete(options, "compressionLevel");
-            array ev = ({});
-            foreach (rext; string name; mapping ext) {
-                array res = ({name});
-                foreach (ext; string pname; int|float|string pval) {
-                    // FIXME We only look for embedded spaces to decide if
-                    // we need to quote the parametervalue.  If you want to
-                    // embed tabs or other whitespace, this needs to be
-                    // amended.
-                    if (stringp(pval) && has_value(pval, " "))
-                        pval = "\"" + pval + "\"";
-                    pval = (string)pval;
-                    if (sizeof(pval))
-                        pval = "="+pval;
-                    res += ({pname+pval});
-                }
-                ev += ({res * ";"});
-            }
-            heads["Sec-WebSocket-Extensions"] = ev * ",";
-        } else
-            m_delete(options, "compressionLevel");
-
-	if (protocol) heads["Sec-WebSocket-Protocol"] = protocol;
-
-        Connection ws = Connection(my_fd, options);
+        Connection ws = Connection(my_fd);
         my_fd = 0;
 
         array a = allocate(1 + sizeof(heads));