...

Source file src/github.com/aws/smithy-go/transport/http/middleware_header_comment.go

Documentation: github.com/aws/smithy-go/transport/http

     1  package http
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net/http"
     7  
     8  	"github.com/aws/smithy-go/middleware"
     9  )
    10  
    11  // WithHeaderComment instruments a middleware stack to append an HTTP field
    12  // comment to the given header as specified in RFC 9110
    13  // (https://www.rfc-editor.org/rfc/rfc9110#name-comments).
    14  //
    15  // The header is case-insensitive. If the provided header exists when the
    16  // middleware runs, the content will be inserted as-is enclosed in parentheses.
    17  //
    18  // Note that per the HTTP specification, comments are only allowed in fields
    19  // containing "comment" as part of their field value definition, but this API
    20  // will NOT verify whether the provided header is one of them.
    21  //
    22  // WithHeaderComment MAY be applied more than once to a middleware stack and/or
    23  // more than once per header.
    24  func WithHeaderComment(header, content string) func(*middleware.Stack) error {
    25  	return func(s *middleware.Stack) error {
    26  		m, err := getOrAddHeaderComment(s)
    27  		if err != nil {
    28  			return fmt.Errorf("get or add header comment: %v", err)
    29  		}
    30  
    31  		m.values.Add(header, content)
    32  		return nil
    33  	}
    34  }
    35  
    36  type headerCommentMiddleware struct {
    37  	values http.Header // hijack case-insensitive access APIs
    38  }
    39  
    40  func (*headerCommentMiddleware) ID() string {
    41  	return "headerComment"
    42  }
    43  
    44  func (m *headerCommentMiddleware) HandleBuild(ctx context.Context, in middleware.BuildInput, next middleware.BuildHandler) (
    45  	out middleware.BuildOutput, metadata middleware.Metadata, err error,
    46  ) {
    47  	r, ok := in.Request.(*Request)
    48  	if !ok {
    49  		return out, metadata, fmt.Errorf("unknown transport type %T", in.Request)
    50  	}
    51  
    52  	for h, contents := range m.values {
    53  		for _, c := range contents {
    54  			if existing := r.Header.Get(h); existing != "" {
    55  				r.Header.Set(h, fmt.Sprintf("%s (%s)", existing, c))
    56  			}
    57  		}
    58  	}
    59  
    60  	return next.HandleBuild(ctx, in)
    61  }
    62  
    63  func getOrAddHeaderComment(s *middleware.Stack) (*headerCommentMiddleware, error) {
    64  	id := (*headerCommentMiddleware)(nil).ID()
    65  	m, ok := s.Build.Get(id)
    66  	if !ok {
    67  		m := &headerCommentMiddleware{values: http.Header{}}
    68  		if err := s.Build.Add(m, middleware.After); err != nil {
    69  			return nil, fmt.Errorf("add build: %v", err)
    70  		}
    71  
    72  		return m, nil
    73  	}
    74  
    75  	hc, ok := m.(*headerCommentMiddleware)
    76  	if !ok {
    77  		return nil, fmt.Errorf("existing middleware w/ id %s is not *headerCommentMiddleware", id)
    78  	}
    79  
    80  	return hc, nil
    81  }
    82  

View as plain text