Problem
triple_protocol.SetHeader and SetTrailer document a unary handler usage pattern, for example:
func (srv *Server) Greet(ctx context.Context, req *greet.GreetRequest) (*greet.GreetResponse, error) {
if err := triple.SetHeader(ctx, http.Header{"hi": []string{"triple"}}); err != nil {
return nil, err
}
if err := triple.SetTrailer(ctx, http.Header{"end": []string{"end"}}); err != nil {
return nil, err
}
return &greet.GreetResponse{}, nil
}
However, the generated Triple unary server path currently passes a ctx that does not contain the internal handlerOutgoingKey{} connection value required by SetHeader / SetTrailer.
As a result, calling either API from a generated unary service implementation returns an error similar to:
triple: failed to fetch the connection from the context ...
Why this happens
The low-level unary handler in protocol/triple/triple_protocol/handler.go embeds incoming metadata into the context with newIncomingContext(ctx, conn.RequestHeader()), but it does not expose the handler connection through handlerOutgoingKey{} before invoking the user handler.
Then SetHeader / SetTrailer in protocol/triple/triple_protocol/header.go try to fetch:
ctx.Value(handlerOutgoingKey{}).(StreamingHandlerConn)
and fail.
For generated unary handlers, the generated method wrapper also only calls the business handler and wraps the returned business response with triple_protocol.NewResponse(res), so the application has no other generated-level response metadata hook.
Expected behavior
Generated Triple unary service implementations should be able to use triple.SetHeader(ctx, ...) and triple.SetTrailer(ctx, ...) as documented, and clients should be able to capture those values with client.WithResponseHeader / client.WithResponseTrailer.
Related context
Recent client-side work exposes unary response metadata capture through call options. That solves the client read side, but this server-side generated unary write path is still not usable with the documented API.
Problem
triple_protocol.SetHeaderandSetTrailerdocument a unary handler usage pattern, for example:However, the generated Triple unary server path currently passes a
ctxthat does not contain the internalhandlerOutgoingKey{}connection value required bySetHeader/SetTrailer.As a result, calling either API from a generated unary service implementation returns an error similar to:
Why this happens
The low-level unary handler in
protocol/triple/triple_protocol/handler.goembeds incoming metadata into the context withnewIncomingContext(ctx, conn.RequestHeader()), but it does not expose the handler connection throughhandlerOutgoingKey{}before invoking the user handler.Then
SetHeader/SetTrailerinprotocol/triple/triple_protocol/header.gotry to fetch:and fail.
For generated unary handlers, the generated method wrapper also only calls the business handler and wraps the returned business response with
triple_protocol.NewResponse(res), so the application has no other generated-level response metadata hook.Expected behavior
Generated Triple unary service implementations should be able to use
triple.SetHeader(ctx, ...)andtriple.SetTrailer(ctx, ...)as documented, and clients should be able to capture those values withclient.WithResponseHeader/client.WithResponseTrailer.Related context
Recent client-side work exposes unary response metadata capture through call options. That solves the client read side, but this server-side generated unary write path is still not usable with the documented API.