11package explore
22
33import (
4- "encoding/base64"
5- "encoding/json"
6- "log"
74 "net/http"
85 "time"
96
@@ -13,13 +10,6 @@ import (
1310 "github.com/google/go-containerregistry/pkg/v1/remote/transport"
1411)
1512
16- type CookieValue struct {
17- Reg string
18- PingResp * transport.PingResp
19- Repo string
20- TokenResponse * transport.TokenResponse
21- }
22-
2313type RedirectCookie struct {
2414 Digest string
2515 Url string
@@ -33,102 +23,60 @@ func (h *handler) transportFromCookie(w http.ResponseWriter, r *http.Request, re
3323 scopes := []string {parsed .Scope (transport .PullScope )}
3424 reg := parsed .Registry
3525
36- var (
37- pr * transport.PingResp
38- tok * transport.TokenResponse
39- )
40- if regCookie , err := r .Cookie ("registry_token" ); err == nil {
41- b , err := base64 .URLEncoding .DecodeString (regCookie .Value )
42- if err != nil {
43- return nil , err
44- }
45- var v CookieValue
46- if err := json .Unmarshal (b , & v ); err != nil {
47- return nil , err
48- }
49- if v .Reg == reg .String () {
50- pr = v .PingResp
51- if v .Repo == repo {
52- tok = v .TokenResponse
53- }
54- }
55- }
56-
5726 t := remote .DefaultTransport
5827 t = transport .NewRetry (t )
5928 t = transport .NewUserAgent (t , h .userAgent )
6029 if r .URL .Query ().Get ("trace" ) != "" {
6130 t = transport .NewTracer (t )
6231 }
6332
64- if pr == nil {
65- if cpr , ok := h .pings [reg .String ()]; ok {
66- if debug {
67- log .Printf ("cached ping: %v" , cpr )
68- }
69- pr = cpr
70- } else {
71- if debug {
72- log .Printf ("pinging %s" , reg .String ())
73- }
74- pr , err = transport .Ping (r .Context (), reg , t )
75- if err != nil {
76- return nil , err
77- }
78- h .pings [reg .String ()] = pr
79- }
80- }
81-
82- if tok == nil {
83- if debug {
84- log .Printf ("getting token %s" , reg .String ())
85- }
86- t , tok , err = transport .NewBearer (r .Context (), pr , reg , auth , t , scopes )
33+ h .Lock ()
34+ pr , ok := h .pings [reg .String ()]
35+ h .Unlock ()
36+ if ! ok {
37+ pr , err = transport .Ping (r .Context (), reg , t )
8738 if err != nil {
8839 return nil , err
8940 }
41+ h .Lock ()
42+ h .pings [reg .String ()] = pr
43+ h .Unlock ()
44+ }
9045
91- // Probably no auth needed.
92- if tok == nil {
93- return t , nil
94- }
46+ h .Lock ()
47+ tok , ok := h .tokens [parsed .String ()]
48+ h .Unlock ()
49+ if ok && ! tok .Expires .Before (time .Now ().Add (30 * time .Second )) {
50+ // If this won't expire within 30 seconds, reuse it.
51+ return transport .OldBearer (pr , tok .TokenResponse , reg , auth , t , scopes )
52+ }
9553
96- // Clear this to make cookies smaller.
97- tok .AccessToken = ""
54+ // We don't have a cached token or it's expired (or about to), so get a new one.
55+ rt , tr , err := transport .NewBearer (r .Context (), pr , reg , auth , t , scopes )
56+ if err != nil {
57+ return nil , err
58+ }
9859
99- v := & CookieValue {
100- Reg : reg .String (),
101- PingResp : pr ,
102- Repo : repo ,
103- TokenResponse : tok ,
104- }
105- b , err := json .Marshal (v )
106- if err != nil {
107- return nil , err
108- }
109- cv := base64 .URLEncoding .EncodeToString (b )
110- cookie := & http.Cookie {
111- Name : "registry_token" ,
112- Value : cv ,
113- Secure : true ,
114- HttpOnly : true ,
115- SameSite : http .SameSiteLaxMode ,
116- }
117- if tok .ExpiresIn == 0 {
118- tok .ExpiresIn = 60
119- }
120- exp := time .Now ().Add (time .Second * time .Duration (tok .ExpiresIn ))
121- cookie .Expires = exp
122- http .SetCookie (w , cookie )
123- } else {
124- if debug {
125- log .Printf ("restoring bearer %s" , reg .String ())
126- }
127- t , err = transport .OldBearer (pr , tok , reg , auth , t , scopes )
128- if err != nil {
129- return nil , err
130- }
60+ // Probably no auth needed.
61+ if tr == nil {
62+ return rt , nil
63+ }
64+
65+ // Clear this to make cache smaller (sometimes this duplicates Token).
66+ tr .AccessToken = ""
67+
68+ if tr .ExpiresIn == 0 {
69+ tr .ExpiresIn = 60
13170 }
71+ exp := time .Now ().Add (time .Second * time .Duration (tr .ExpiresIn ))
72+ tok = token {
73+ TokenResponse : tr ,
74+ Expires : exp ,
75+ }
76+
77+ h .Lock ()
78+ h .tokens [parsed .String ()] = tok
79+ h .Unlock ()
13280
133- return t , nil
81+ return rt , nil
13482}
0 commit comments