1package jose
2
3import "encoding/json"
4
5// Header implements a JOSE Header with the addition of some helper
6// methods, similar to net/url.Values.
7type Header map[string]interface{}
8
9// Get retrieves the value corresponding with key from the Header.
10func (h Header) Get(key string) interface{} {
11	if h == nil {
12		return nil
13	}
14	return h[key]
15}
16
17// Set sets Claims[key] = val. It'll overwrite without warning.
18func (h Header) Set(key string, val interface{}) {
19	h[key] = val
20}
21
22// Del removes the value that corresponds with key from the Header.
23func (h Header) Del(key string) {
24	delete(h, key)
25}
26
27// Has returns true if a value for the given key exists inside the Header.
28func (h Header) Has(key string) bool {
29	_, ok := h[key]
30	return ok
31}
32
33// MarshalJSON implements json.Marshaler for Header.
34func (h Header) MarshalJSON() ([]byte, error) {
35	if len(h) == 0 {
36		return nil, nil
37	}
38	b, err := json.Marshal(map[string]interface{}(h))
39	if err != nil {
40		return nil, err
41	}
42	return EncodeEscape(b), nil
43}
44
45// Base64 implements the Encoder interface.
46func (h Header) Base64() ([]byte, error) {
47	return h.MarshalJSON()
48}
49
50// UnmarshalJSON implements json.Unmarshaler for Header.
51func (h *Header) UnmarshalJSON(b []byte) error {
52	if b == nil {
53		return nil
54	}
55	b, err := DecodeEscaped(b)
56	if err != nil {
57		return err
58	}
59	return json.Unmarshal(b, (*map[string]interface{})(h))
60}
61
62// Protected Headers are base64-encoded after they're marshaled into
63// JSON.
64type Protected Header
65
66// Get retrieves the value corresponding with key from the Protected Header.
67func (p Protected) Get(key string) interface{} {
68	if p == nil {
69		return nil
70	}
71	return p[key]
72}
73
74// Set sets Protected[key] = val. It'll overwrite without warning.
75func (p Protected) Set(key string, val interface{}) {
76	p[key] = val
77}
78
79// Del removes the value that corresponds with key from the Protected Header.
80func (p Protected) Del(key string) {
81	delete(p, key)
82}
83
84// Has returns true if a value for the given key exists inside the Protected
85// Header.
86func (p Protected) Has(key string) bool {
87	_, ok := p[key]
88	return ok
89}
90
91// MarshalJSON implements json.Marshaler for Protected.
92func (p Protected) MarshalJSON() ([]byte, error) {
93	b, err := json.Marshal(map[string]interface{}(p))
94	if err != nil {
95		return nil, err
96	}
97	return EncodeEscape(b), nil
98}
99
100// Base64 implements the Encoder interface.
101func (p Protected) Base64() ([]byte, error) {
102	b, err := json.Marshal(map[string]interface{}(p))
103	if err != nil {
104		return nil, err
105	}
106	return Base64Encode(b), nil
107}
108
109// UnmarshalJSON implements json.Unmarshaler for Protected.
110func (p *Protected) UnmarshalJSON(b []byte) error {
111	var h Header
112	if err := h.UnmarshalJSON(b); err != nil {
113		return err
114	}
115	*p = Protected(h)
116	return nil
117}
118
119var (
120	_ json.Marshaler   = (Protected)(nil)
121	_ json.Unmarshaler = (*Protected)(nil)
122	_ json.Marshaler   = (Header)(nil)
123	_ json.Unmarshaler = (*Header)(nil)
124)
125