github.com/lestrrat-go/jwx/v2@v2.0.21/jws/headers.go (about) 1 package jws 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/lestrrat-go/iter/mapiter" 8 "github.com/lestrrat-go/jwx/v2/internal/iter" 9 ) 10 11 // Iterate returns a channel that successively returns all the 12 // header name and values. 13 func (h *stdHeaders) Iterate(ctx context.Context) Iterator { 14 pairs := h.makePairs() 15 ch := make(chan *HeaderPair, len(pairs)) 16 go func(ctx context.Context, ch chan *HeaderPair, pairs []*HeaderPair) { 17 defer close(ch) 18 for _, pair := range pairs { 19 select { 20 case <-ctx.Done(): 21 return 22 case ch <- pair: 23 } 24 } 25 }(ctx, ch, pairs) 26 return mapiter.New(ch) 27 } 28 29 func (h *stdHeaders) Walk(ctx context.Context, visitor Visitor) error { 30 return iter.WalkMap(ctx, h, visitor) 31 } 32 33 func (h *stdHeaders) AsMap(ctx context.Context) (map[string]interface{}, error) { 34 return iter.AsMap(ctx, h) 35 } 36 37 func (h *stdHeaders) Copy(_ context.Context, dst Headers) error { 38 for _, pair := range h.makePairs() { 39 //nolint:forcetypeassert 40 key := pair.Key.(string) 41 if err := dst.Set(key, pair.Value); err != nil { 42 return fmt.Errorf(`failed to set header %q: %w`, key, err) 43 } 44 } 45 return nil 46 } 47 48 // mergeHeaders merges two headers, and works even if the first Header 49 // object is nil. This is not exported because ATM it felt like this 50 // function is not frequently used, and MergeHeaders seemed a clunky name 51 func mergeHeaders(ctx context.Context, h1, h2 Headers) (Headers, error) { 52 h3 := NewHeaders() 53 54 if h1 != nil { 55 if err := h1.Copy(ctx, h3); err != nil { 56 return nil, fmt.Errorf(`failed to copy headers from first Header: %w`, err) 57 } 58 } 59 60 if h2 != nil { 61 if err := h2.Copy(ctx, h3); err != nil { 62 return nil, fmt.Errorf(`failed to copy headers from second Header: %w`, err) 63 } 64 } 65 66 return h3, nil 67 } 68 69 func (h *stdHeaders) Merge(ctx context.Context, h2 Headers) (Headers, error) { 70 return mergeHeaders(ctx, h, h2) 71 }