Skip to content

Commit

Permalink
integration: fix wrapping of response writer causing endless test loop
Browse files Browse the repository at this point in the history
  • Loading branch information
johanbrandhorst committed Mar 23, 2024
1 parent 7e2a7fd commit afffa97
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 9 deletions.
8 changes: 7 additions & 1 deletion docs/docs/operations/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ func (rsp *logResponseWriter) WriteHeader(code int) {
rsp.ResponseWriter.WriteHeader(code)
}

// Unwrap returns the original http.ResponseWriter. This is necessary
// to expose Flush() and Push() on the underlying response writer.
func (rsp *logResponseWriter) Unwrap() http.ResponseWriter {
return rsp.ResponseWriter
}

func newLogResponseWriter(w http.ResponseWriter) *logResponseWriter {
return &logResponseWriter{w, http.StatusOK}
}
Expand Down Expand Up @@ -58,4 +64,4 @@ func logRequestBody(h http.Handler) http.Handler {
s := &http.Server{
Handler: logRequestBody(mux),
}
```
```
6 changes: 6 additions & 0 deletions examples/internal/gateway/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ func (rsp *logResponseWriter) WriteHeader(code int) {
rsp.ResponseWriter.WriteHeader(code)
}

// Unwrap returns the original http.ResponseWriter. This is necessary
// to expose Flush() and Push() on the underlying response writer.
func (rsp *logResponseWriter) Unwrap() http.ResponseWriter {
return rsp.ResponseWriter
}

func newLogResponseWriter(w http.ResponseWriter) *logResponseWriter {
return &logResponseWriter{w, http.StatusOK}
}
Expand Down
20 changes: 12 additions & 8 deletions runtime/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,8 @@ import (

// ForwardResponseStream forwards the stream from gRPC server to REST client.
func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshaler, w http.ResponseWriter, req *http.Request, recv func() (proto.Message, error), opts ...func(context.Context, http.ResponseWriter, proto.Message) error) {
f, ok := w.(http.Flusher)
if !ok {
grpclog.Infof("Flush not supported in %T", w)
http.Error(w, "unexpected type of web server", http.StatusInternalServerError)
return
}

// nolint: bodyclose
rc := http.NewResponseController(w)
md, ok := ServerMetadataFromContext(ctx)
if !ok {
grpclog.Infof("Failed to extract ServerMetadata from context")
Expand Down Expand Up @@ -94,7 +89,16 @@ func ForwardResponseStream(ctx context.Context, mux *ServeMux, marshaler Marshal
grpclog.Infof("Failed to send delimiter chunk: %v", err)
return
}
f.Flush()
err = rc.Flush()
if err != nil {
if errors.Is(err, http.ErrNotSupported) {
grpclog.Infof("Flush not supported in %T", w)
http.Error(w, "unexpected type of web server", http.StatusInternalServerError)
return
}
grpclog.Infof("Failed to flush response to client: %v", err)
return
}
}
}

Expand Down

0 comments on commit afffa97

Please sign in to comment.