@@ -249,34 +249,45 @@ type DialOptions struct {
249
249
// Compression sets the compression options.
250
250
// By default, compression is disabled.
251
251
// See docs on the CompressionOptions type.
252
- Compression CompressionOptions
252
+ Compression * CompressionOptions
253
253
}
254
254
255
255
// CompressionOptions describes the available compression options.
256
256
//
257
257
// See https://tools.ietf.org/html/rfc7692
258
258
//
259
- // Enabling compression may spike memory usage as each flate.Writer takes up 1.2 MB.
259
+ // The NoContextTakeover variables control whether a flate.Writer or flate.Reader is allocated
260
+ // for every connection (context takeover) versus shared from a pool (no context takeover).
261
+ //
262
+ // The advantage to context takeover is more efficient compression as the sliding window from previous
263
+ // messages will be used instead of being reset between every message.
264
+ //
265
+ // The advantage to no context takeover is that the flate structures are allocated as needed
266
+ // and shared between connections instead of giving each connection a fixed flate.Writer and
267
+ // flate.Reader.
268
+ //
269
+ // See https://www.igvita.com/2013/11/27/configuring-and-optimizing-websocket-compression.
270
+ //
271
+ // Enabling compression will increase memory and CPU usage.
272
+ // Thus it is not ideal for every use case and disabled by default.
260
273
// See https://github.com/gorilla/websocket/issues/203
261
- // Benchmark before enabling in production.
274
+ // Profile before enabling in production.
262
275
//
263
276
// This API is experimental and subject to change.
264
277
type CompressionOptions struct {
265
- // ContextTakeover controls whether context takeover is enabled.
266
- //
267
- // If ContextTakeover == false, then a flate.Writer will be grabbed
268
- // from the pool as needed for every message written to the connection.
278
+ // ServerNoContextTakeover controls whether the server should use context takeover.
279
+ // See docs on CompressionOptions for discussion regarding context takeover.
269
280
//
270
- // If ContextTakeover == true, then a flate.Writer will be allocated for each connection .
271
- // This allows more efficient compression as the sliding window from previous
272
- // messages will be used instead of resetting in between every message.
273
- // The downside is that for every connection there will be a fixed allocation
274
- // for the flate.Writer .
281
+ // If set by the client, will guarantee that the server does not use context takeover .
282
+ ServerNoContextTakeover bool
283
+
284
+ // ClientNoContextTakeover controls whether the client should use context takeover.
285
+ // See docs on CompressionOptions for discussion regarding context takeover .
275
286
//
276
- // See https://www.igvita.com/2013/11/27/configuring-and-optimizing-websocket-compression .
277
- ContextTakeover bool
287
+ // If set by the server, will guarantee that the client does not use context takeover .
288
+ ClientNoContextTakeover bool
278
289
279
- // Level controls the compression level negotiated .
290
+ // Level controls the compression level used .
280
291
// Defaults to flate.BestSpeed.
281
292
Level int
282
293
@@ -355,6 +366,9 @@ func dial(ctx context.Context, u string, opts *DialOptions) (_ *Conn, _ *http.Re
355
366
if len (opts .Subprotocols ) > 0 {
356
367
req .Header .Set ("Sec-WebSocket-Protocol" , strings .Join (opts .Subprotocols , "," ))
357
368
}
369
+ if opts .Compression != nil {
370
+ req .Header .Set ("Sec-WebSocket-Extensions" , "permessage-deflate; server_no_context_takeover; client_no_context_takeover" )
371
+ }
358
372
359
373
resp , err := opts .HTTPClient .Do (req )
360
374
if err != nil {
0 commit comments