Skip to content

Commit 7fc7196

Browse files
committed
client: allow overriding grpc-accept-encoding header
Signed-off-by: Israel Blancas <[email protected]>
1 parent 50c6321 commit 7fc7196

File tree

4 files changed

+71
-1
lines changed

4 files changed

+71
-1
lines changed

dialoptions.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"context"
2323
"net"
2424
"net/url"
25+
"strings"
2526
"time"
2627

2728
"google.golang.org/grpc/backoff"
@@ -31,6 +32,7 @@ import (
3132
"google.golang.org/grpc/internal"
3233
internalbackoff "google.golang.org/grpc/internal/backoff"
3334
"google.golang.org/grpc/internal/binarylog"
35+
"google.golang.org/grpc/internal/grpcutil"
3436
"google.golang.org/grpc/internal/transport"
3537
"google.golang.org/grpc/keepalive"
3638
"google.golang.org/grpc/mem"
@@ -183,6 +185,16 @@ func WithSharedWriteBuffer(val bool) DialOption {
183185
})
184186
}
185187

188+
// WithAcceptedCompressionNames limits the values advertised in the
189+
// grpc-accept-encoding header for this ClientConn. Names must correspond to
190+
// compressors registered via encoding.RegisterCompressor. When empty, the
191+
// default set of registered compressors is used.
192+
func WithAcceptedCompressionNames(names ...string) DialOption {
193+
return newFuncDialOption(func(o *dialOptions) {
194+
o.copts.AcceptedCompressors = formatAcceptedCompressors(names)
195+
})
196+
}
197+
186198
// WithWriteBufferSize determines how much data can be batched before doing a
187199
// write on the wire. The default value for this buffer is 32KB.
188200
//
@@ -207,6 +219,32 @@ func WithReadBufferSize(s int) DialOption {
207219
})
208220
}
209221

222+
func formatAcceptedCompressors(names []string) string {
223+
if len(names) == 0 {
224+
return ""
225+
}
226+
sch := make([]string, 0, len(names))
227+
seen := make(map[string]struct{}, len(names))
228+
for _, name := range names {
229+
name = strings.TrimSpace(name)
230+
if name == "" {
231+
continue
232+
}
233+
if !grpcutil.IsCompressorNameRegistered(name) {
234+
continue
235+
}
236+
if _, ok := seen[name]; ok {
237+
continue
238+
}
239+
seen[name] = struct{}{}
240+
sch = append(sch, name)
241+
}
242+
if len(sch) == 0 {
243+
return ""
244+
}
245+
return strings.Join(sch, ",")
246+
}
247+
210248
// WithInitialWindowSize returns a DialOption which sets the value for initial
211249
// window size on a stream. The lower bound for window size is 64K and any value
212250
// smaller than that will be ignored.

internal/transport/http2_client.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,12 +321,17 @@ func NewHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts
321321
maxHeaderListSize = *opts.MaxHeaderListSize
322322
}
323323

324+
registeredCompressors := opts.AcceptedCompressors
325+
if registeredCompressors == "" {
326+
registeredCompressors = grpcutil.RegisteredCompressors()
327+
}
328+
324329
t := &http2Client{
325330
ctx: ctx,
326331
ctxDone: ctx.Done(), // Cache Done chan.
327332
cancel: cancel,
328333
userAgent: opts.UserAgent,
329-
registeredCompressors: grpcutil.RegisteredCompressors(),
334+
registeredCompressors: registeredCompressors,
330335
address: addr,
331336
conn: conn,
332337
remoteAddr: conn.RemoteAddr(),

internal/transport/transport.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,9 @@ type ConnectOptions struct {
531531
BufferPool mem.BufferPool
532532
// StaticWindowSize controls whether dynamic window sizing is enabled.
533533
StaticWindowSize bool
534+
// AcceptedCompressors overrides the grpc-accept-encoding header for this
535+
// connection. When empty, all registered compressors are advertised.
536+
AcceptedCompressors string
534537
}
535538

536539
// WriteOptions provides additional hints and information for message

test/compressor_test.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,30 @@ func (s) TestClientSupportedCompressors(t *testing.T) {
533533
}
534534
}
535535

536+
func (s) TestAcceptedCompressionNamesDialOption(t *testing.T) {
537+
const want = "gzip"
538+
ss := &stubserver.StubServer{
539+
EmptyCallF: func(ctx context.Context, _ *testpb.Empty) (*testpb.Empty, error) {
540+
md, _ := metadata.FromIncomingContext(ctx)
541+
if got := md.Get("grpc-accept-encoding"); len(got) != 1 || got[0] != want {
542+
t.Fatalf("unexpected grpc-accept-encoding header: %v", got)
543+
}
544+
return &testpb.Empty{}, nil
545+
},
546+
}
547+
if err := ss.Start(nil, grpc.WithAcceptedCompressionNames(want)); err != nil {
548+
t.Fatalf("failed to start server: %v", err)
549+
}
550+
defer ss.Stop()
551+
552+
ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout)
553+
defer cancel()
554+
555+
if _, err := ss.Client.EmptyCall(ctx, &testpb.Empty{}); err != nil {
556+
t.Fatalf("EmptyCall failed: %v", err)
557+
}
558+
}
559+
536560
func (s) TestCompressorRegister(t *testing.T) {
537561
for _, e := range listTestEnv() {
538562
testCompressorRegister(t, e)

0 commit comments

Comments
 (0)