diff --git a/private/server/handler.go b/private/server/handler.go index 5791c2b..666e378 100644 --- a/private/server/handler.go +++ b/private/server/handler.go @@ -301,7 +301,13 @@ func NewHandler(service protoreflect.ServiceDescriptor, faker fauxrpc.ProtoFaker func grpcWriteStatus(w http.ResponseWriter, st *status.Status) { w.Header().Set("Grpc-Status", strconv.FormatInt(int64(st.Code()), 10)) w.Header().Set("Grpc-Message", st.Message()) - if details, err := proto.Marshal(st.Proto()); err != nil { + + p := st.Proto() + if len(p.Details) == 0 { + return + } + + if details, err := proto.Marshal(p); err != nil { slog.Error("error serializing validation details", "error", err) } else { w.Header().Set("Grpc-Status-Details-Bin", base64.StdEncoding.EncodeToString(details)) diff --git a/private/server/handler_bench_test.go b/private/server/handler_bench_test.go index d205816..31b37ad 100644 --- a/private/server/handler_bench_test.go +++ b/private/server/handler_bench_test.go @@ -3,6 +3,7 @@ package server import ( "bytes" "encoding/binary" + "net/http" "net/http/httptest" "testing" @@ -12,6 +13,8 @@ import ( "github.com/sudorandom/fauxrpc" fauxlog "github.com/sudorandom/fauxrpc/private/log" "github.com/sudorandom/fauxrpc/private/stubs" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "google.golang.org/protobuf/proto" ) @@ -64,3 +67,33 @@ func BenchmarkHandler_RequestAllocation(b *testing.B) { handler.ServeHTTP(w, req) } } + +type mockWriter struct { + h http.Header +} + +func (m *mockWriter) Header() http.Header { + return m.h +} + +func (m *mockWriter) Write([]byte) (int, error) { + return 0, nil +} + +func (m *mockWriter) WriteHeader(statusCode int) {} + +func BenchmarkGRPCWriteStatus(b *testing.B) { + st := status.New(codes.NotFound, "not found") + w := &mockWriter{h: make(http.Header)} + + b.ResetTimer() + b.ReportAllocs() + + for i := 0; i < b.N; i++ { + grpcWriteStatus(w, st) + // Reset header + for k := range w.h { + delete(w.h, k) + } + } +}