title: WebSocket permessage-deflate in Chrome with no context takeover
body: <p>I have this problem with compression, and I am not sure if it is a bug. My WebSocket server does not support context takeover, and I am having problems sending messages, but not receiving.</p>
  
  <p>The browser issues a request like this:</p>
  
  <pre><code>GET /socket HTTP/1.1
  Host: thirdparty.com
  Origin: http://example.com
  Connection: Upgrade
  Upgrade: websocket
  Sec-WebSocket-Version: 13
  Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
  Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits, x-webkit-deflate-frame
  </code></pre>
  
  <p>If the server does not specify any option about context takeover:</p>
  
  <pre><code>HTTP/1.1 101 Switching Protocols
  Upgrade: websocket
  Connection: Upgrade
  Access-Control-Allow-Origin: http://example.com
  Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
  Sec-WebSocket-Extensions: permessage-deflate
  </code></pre>
  
  <p>I can read and write the first message, but cannot do subsequent reads or writes, because Chrome expects the server is keeping the context.</p>
  
  <p>So my server provides this answer:</p>
  
  <pre><code>HTTP/1.1 101 Switching Protocols
  Upgrade: websocket
  Connection: Upgrade
  Access-Control-Allow-Origin: http://example.com
  Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
  Sec-WebSocket-Extensions: permessage-deflate; client_no_context_takeover; server_no_context_takeover
  </code></pre>
  
  <p>And now I can receive messages without problems, but again, I can only send the first message, the second message fails, and I see an error in Chrome saying that it failed at inflating the frame. I tried to send two identical strings, and I can see how the server is sending twice the same data, but the client fails to decompress it the second time.</p>
  
  <p>So it seems that Chrome accepts the <code>client_no_context_takeover</code> parameter that specify that the client won't use the same compression context for all messages when compressing, but ignores <code>server_no_context_takeover</code> indicates the server won't use the same context.</p>
  
  <p>Is this a bug in Chrome? I am not clear about if I can send options back that have not been offered/requested by the client.</p>
  
  <p>Is there any other option I can use to disable the client context takeover?</p>
  
  <p><strong>UPDATE:</strong></p>
  
  <p>In <strong>WebSocketPerMessageDeflate.cpp</strong> in the <a href="https://chromium.googlesource.com/chromium/blink.git/+/master/Source/modules/websockets/WebSocketPerMessageDeflate.cpp" rel="nofollow">Chromium source</a> code, I can see:</p>
  
  <pre><code>if (clientNoContextTakeover != parameters.end()) {
      if (!clientNoContextTakeover-&gt;value.isNull()) {
          m_failureReason = "Received invalid client_no_context_takeover parameter";
          return false;
      }
      mode = WebSocketDeflater::DoNotTakeOverContext;
      ++numProcessedParameters;
  }
  </code></pre>
  
  <p>But also:</p>
  
  <pre><code>if (serverNoContextTakeover != parameters.end()) {
      if (!serverNoContextTakeover-&gt;value.isNull()) {
          m_failureReason = "Received invalid server_no_context_takeover parameter";
          return false;
      }
      ++numProcessedParameters;
  }
  </code></pre>
  
  <p>In the first snippet, it is setting the "mode" variable, but in the second one is not doing nothing, so it seems it is basically ignoring the parameter.</p>
  
  <p>Cheers.</p>