11package apns2
22
33import (
4+ "sync"
5+ "time"
6+
47"container/list"
58"crypto/sha1"
69"crypto/tls"
7- "sync"
8- "time "
10+
11+ "github.com/sideshow/apns2/token "
912)
1013
1114type managerItem struct {
@@ -31,6 +34,10 @@ type ClientManager struct {
3134// manager.
3235Factory func (certificate tls.Certificate ) * Client
3336
37+ // FactoryToken is the function which constructs clients if not found in the
38+ // manager when token auth is used
39+ FactoryToken func (token * token.Token ) * Client
40+
3441cache map [[sha1 .Size ]byte ]* list.Element
3542ll * list.List
3643mu sync.Mutex
@@ -48,9 +55,10 @@ type ClientManager struct {
4855// a Client with default options.
4956func NewClientManager () * ClientManager {
5057manager := & ClientManager {
51- MaxSize : 64 ,
52- MaxAge : 10 * time .Minute ,
53- Factory : NewClient ,
58+ MaxSize : 64 ,
59+ MaxAge : 10 * time .Minute ,
60+ Factory : NewClient ,
61+ FactoryToken : NewTokenClient ,
5462}
5563
5664manager .initInternals ()
@@ -65,7 +73,14 @@ func (m *ClientManager) Add(client *Client) {
6573m .mu .Lock ()
6674defer m .mu .Unlock ()
6775
68- key := cacheKey (client .Certificate )
76+ var key [sha1 .Size ]byte
77+
78+ if client .Token != nil {
79+ key = cacheTokenKey (client .Token )
80+ } else {
81+ key = cacheKey (client .Certificate )
82+ }
83+
6984now := time .Now ()
7085if ele , hit := m .cache [key ]; hit {
7186item := ele .Value .(* managerItem )
@@ -88,16 +103,35 @@ func (m *ClientManager) Add(client *Client) {
88103// the ClientManager's Factory function, store the result in the manager if
89104// non-nil, and return it.
90105func (m * ClientManager ) Get (certificate tls.Certificate ) * Client {
106+ key := cacheKey (certificate )
107+
108+ return m .get (key , func () * Client {
109+ return m .Factory (certificate )
110+ })
111+ }
112+
113+ // Get gets a Client from the manager. If a Client is not found in the manager
114+ // or if a Client has remained in the manager longer than MaxAge, Get will call
115+ // the ClientManager's Factory function, store the result in the manager if
116+ // non-nil, and return it.
117+ func (m * ClientManager ) GetByToken (token * token.Token ) * Client {
118+ key := cacheTokenKey (token )
119+
120+ return m .get (key , func () * Client {
121+ return m .FactoryToken (token )
122+ })
123+ }
124+
125+ func (m * ClientManager ) get (key [sha1 .Size ]byte , factory func () * Client ) * Client {
91126m .initInternals ()
92127m .mu .Lock ()
93128defer m .mu .Unlock ()
94129
95- key := cacheKey (certificate )
96130now := time .Now ()
97131if ele , hit := m .cache [key ]; hit {
98132item := ele .Value .(* managerItem )
99133if m .MaxAge != 0 && item .lastUsed .Before (now .Add (- m .MaxAge )) {
100- c := m . Factory ( certificate )
134+ c := factory ( )
101135if c == nil {
102136return nil
103137}
@@ -108,7 +142,7 @@ func (m *ClientManager) Get(certificate tls.Certificate) *Client {
108142return item .client
109143}
110144
111- c := m . Factory ( certificate )
145+ c := factory ( )
112146if c == nil {
113147return nil
114148}
@@ -160,3 +194,7 @@ func cacheKey(certificate tls.Certificate) [sha1.Size]byte {
160194
161195return sha1 .Sum (data )
162196}
197+
198+ func cacheTokenKey (token * token.Token ) [sha1 .Size ]byte {
199+ return sha1 .Sum ([]byte (token .Bearer ))
200+ }
0 commit comments