Skip to content

Commit 90ce72a

Browse files
authored
Add websocket compression mode option (#1116)
* add compression mode option * update lints * Update README.md
1 parent 230601c commit 90ce72a

File tree

5 files changed

+58
-3
lines changed

5 files changed

+58
-3
lines changed

go/grpcweb/DOC.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,15 @@ The default behaviour is to deny all requests from remote origins.
165165
The relevant CORS pre-flight docs:
166166
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
167167

168+
#### func WithWebsocketCompressionMode
169+
170+
```go
171+
func WithWebsocketCompressionMode(compressionMode websocket.CompressionMode) Option
172+
```
173+
WithWebsocketCompressionMode sets compression mode for websocket requests
174+
175+
The default mode is CompressionNoContextTakeover
176+
168177
#### func WithWebsocketOriginFunc
169178

170179
```go

go/grpcweb/options.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ package grpcweb
66
import (
77
"net/http"
88
"time"
9+
10+
"nhooyr.io/websocket"
911
)
1012

1113
var (
@@ -15,6 +17,7 @@ var (
1517
originFunc: func(origin string) bool { return false },
1618
allowNonRootResources: false,
1719
corsMaxAge: 10 * time.Minute,
20+
websocketCompressionMode: websocket.CompressionNoContextTakeover,
1821
}
1922
)
2023

@@ -27,6 +30,7 @@ type options struct {
2730
websocketPingInterval time.Duration
2831
websocketOriginFunc func(req *http.Request) bool
2932
websocketReadLimit int64
33+
websocketCompressionMode websocket.CompressionMode
3034
allowNonRootResources bool
3135
endpointsFunc *func() []string
3236
}
@@ -166,3 +170,12 @@ func WithAllowNonRootResource(allowNonRootResources bool) Option {
166170
o.allowNonRootResources = allowNonRootResources
167171
}
168172
}
173+
174+
// WithWebsocketCompressionMode sets compression mode for websocket requests
175+
//
176+
// The default mode is CompressionNoContextTakeover
177+
func WithWebsocketCompressionMode(compressionMode websocket.CompressionMode) Option {
178+
return func(o *options) {
179+
o.websocketCompressionMode = compressionMode
180+
}
181+
}

go/grpcweb/wrapper.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ func (w *WrappedGrpcServer) HandleGrpcWebsocketRequest(resp http.ResponseWriter,
169169
wsConn, err := websocket.Accept(resp, req, &websocket.AcceptOptions{
170170
InsecureSkipVerify: true, // managed by ServeHTTP
171171
Subprotocols: []string{"grpc-websockets"},
172+
CompressionMode: w.opts.websocketCompressionMode,
172173
})
173174
if err != nil {
174175
grpclog.Errorf("Unable to upgrade websocket request: %v", err)

go/grpcwebproxy/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,18 @@ $GOPATH/bin/grpcwebproxy \
6868
--use_websockets
6969
```
7070

71+
### Changing Websocket Compression
72+
By default, websocket compression is used as `no context takover`. To override compression type, use the `--websocket_compression_mode` option.
73+
Available options are `no_context_takeover`, `context_takeover`, `disabled`. Websocket compression types are described in [RFC 7692](https://datatracker.ietf.org/doc/html/rfc7692).
74+
75+
For example, for disabling websocket compression run the following:
76+
```
77+
$GOPATH/bin/grpcwebproxy \
78+
--backend_addr=localhost:9090 \
79+
--use_websockets \
80+
--websocket_compression_mode=disabled
81+
```
82+
7183
### Changing the Maximum Receive Message Size
7284

7385
By default, grpcwebproxy will limit the message size that the backend sends to the client. This is currently 4MB.

go/grpcwebproxy/main.go

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"sync"
1111
"time"
1212

13+
"nhooyr.io/websocket"
14+
1315
"crypto/tls"
1416

1517
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
@@ -40,9 +42,10 @@ var (
4042
runHttpServer = pflag.Bool("run_http_server", true, "whether to run HTTP server")
4143
runTlsServer = pflag.Bool("run_tls_server", true, "whether to run TLS server")
4244

43-
useWebsockets = pflag.Bool("use_websockets", false, "whether to use beta websocket transport layer")
44-
websocketPingInterval = pflag.Duration("websocket_ping_interval", 0, "whether to use websocket keepalive pinging. Only used when using websockets. Configured interval must be >= 1s.")
45-
websocketReadLimit = pflag.Int64("websocket_read_limit", 0, "sets the maximum message read limit on the underlying websocket. The default message read limit is 32769 bytes.")
45+
useWebsockets = pflag.Bool("use_websockets", false, "whether to use beta websocket transport layer")
46+
websocketPingInterval = pflag.Duration("websocket_ping_interval", 0, "whether to use websocket keepalive pinging. Only used when using websockets. Configured interval must be >= 1s.")
47+
websocketReadLimit = pflag.Int64("websocket_read_limit", 0, "sets the maximum message read limit on the underlying websocket. The default message read limit is 32769 bytes.")
48+
websocketCompressionMode = pflag.String("websocket_compression_mode", "no_context_takeover", "set compression mode for websocket. Values are no_context_takeover (, context_takeover, disabled. The default value is no_context_takeover.")
4649

4750
flagHttpMaxWriteTimeout = pflag.Duration("server_http_max_write_timeout", 10*time.Second, "HTTP server config, max write duration.")
4851
flagHttpMaxReadTimeout = pflag.Duration("server_http_max_read_timeout", 10*time.Second, "HTTP server config, max read duration.")
@@ -100,6 +103,23 @@ func main() {
100103
options,
101104
grpcweb.WithWebsocketPingInterval(*websocketPingInterval),
102105
)
106+
107+
var compressionMode websocket.CompressionMode
108+
switch *websocketCompressionMode {
109+
case "no_context_takeover":
110+
compressionMode = websocket.CompressionNoContextTakeover
111+
case "context_takeover":
112+
compressionMode = websocket.CompressionContextTakeover
113+
case "disabled":
114+
compressionMode = websocket.CompressionDisabled
115+
default:
116+
logrus.Fatalf("unknwon param for websocket compression mode: %s", *websocketCompressionMode)
117+
}
118+
119+
options = append(
120+
options,
121+
grpcweb.WithWebsocketCompressionMode(compressionMode),
122+
)
103123
}
104124

105125
if len(*flagAllowedHeaders) > 0 {

0 commit comments

Comments
 (0)