Skip to content

Commit

Permalink
Add option to disable gzip grpc-accept-encoding (#349)
Browse files Browse the repository at this point in the history
Rather than operating as a gRPC-aware HTTP proxy, Microsoft's `dapr` sidecar is apparently compressing and decompressing each proxied gRPC message. It's using grpc-go and doesn't appear to handle asymmetric compression, so this PR introduces a mechanism to disable gzip support in connect-go clients.
  • Loading branch information
alexandrem committed Aug 17, 2022
1 parent 398f155 commit b2db5b9
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
22 changes: 22 additions & 0 deletions connect_ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -675,6 +675,28 @@ func TestCustomCompression(t *testing.T) {
assert.Equal(t, response.Msg, &pingv1.PingResponse{Text: request.Text})
}

func TestClientWithoutGzipSupport(t *testing.T) {
// See https://github.com/bufbuild/connect-go/pull/349 for why we want to
// support this. TL;DR is that Microsoft's dapr sidecar can't handle
// asymmetric compression.
t.Parallel()
mux := http.NewServeMux()
mux.Handle(pingv1connect.NewPingServiceHandler(pingServer{}))
server := httptest.NewServer(mux)
defer server.Close()

client := pingv1connect.NewPingServiceClient(server.Client(),
server.URL,
connect.WithAcceptCompression("gzip", nil, nil),
connect.WithSendGzip(),
)
request := &pingv1.PingRequest{Text: "gzip me!"}
_, err := client.Ping(context.Background(), connect.NewRequest(request))
assert.NotNil(t, err)
assert.Equal(t, connect.CodeOf(err), connect.CodeUnknown)
assert.True(t, strings.Contains(err.Error(), "unknown compression"))
}

func TestInvalidHeaderTimeout(t *testing.T) {
t.Parallel()
mux := http.NewServeMux()
Expand Down
23 changes: 20 additions & 3 deletions option.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,21 @@ type ClientOption interface {
//
// It's safe to use this option liberally: servers will ignore any
// compression algorithms they don't support. To compress requests, pair this
// option with [WithSendCompression].
// option with [WithSendCompression]. To remove support for a
// previously-registered compression algorithm, use WithAcceptCompression with
// nil decompressor and compressor constructors.
//
// Clients accept gzipped requests by default, using a compressor backed by the
// Clients accept gzipped responses by default, using a compressor backed by the
// standard library's [gzip] package with the default compression level. Use
// [WithSendGzip] to compress requests with gzip.
func WithAcceptCompression(
name string,
newDecompressor func() Decompressor,
newCompressor func() Compressor,
) ClientOption {
if newDecompressor == nil && newCompressor == nil {
return &compressionOption{Name: name}
}
return &compressionOption{
Name: name,
CompressionPool: newCompressionPool(newDecompressor, newCompressor),
Expand Down Expand Up @@ -298,7 +303,19 @@ type compressionOption struct {
}

func (o *compressionOption) applyToClient(config *clientConfig) {
if o.Name == "" || o.CompressionPool == nil {
if o.Name == "" {
return
}
if o.CompressionPool == nil {
delete(config.CompressionPools, o.Name)
var names []string
for _, name := range config.CompressionNames {
if name == o.Name {
continue
}
names = append(names, name)
}
config.CompressionNames = names
return
}
config.CompressionPools[o.Name] = o.CompressionPool
Expand Down

0 comments on commit b2db5b9

Please sign in to comment.