@@ -20,13 +20,25 @@ type ClientPeerIDAuth struct {
20
20
tm tokenMap
21
21
}
22
22
23
+ type clientAsRoundTripper struct {
24
+ * http.Client
25
+ }
26
+
27
+ func (c clientAsRoundTripper ) RoundTrip (req * http.Request ) (* http.Response , error ) {
28
+ return c .Client .Do (req )
29
+ }
30
+
23
31
// AuthenticatedDo is like http.Client.Do, but it does the libp2p peer ID auth
24
32
// handshake if needed.
25
33
//
26
34
// It is recommended to pass in an http.Request with `GetBody` set, so that this
27
35
// method can retry sending the request in case a previously used token has
28
36
// expired.
29
37
func (a * ClientPeerIDAuth ) AuthenticatedDo (client * http.Client , req * http.Request ) (peer.ID , * http.Response , error ) {
38
+ return a .AuthenticateWithRoundTripper (clientAsRoundTripper {client }, req )
39
+ }
40
+
41
+ func (a * ClientPeerIDAuth ) AuthenticateWithRoundTripper (rt http.RoundTripper , req * http.Request ) (peer.ID , * http.Response , error ) {
30
42
hostname := req .Host
31
43
ti , hasToken := a .tm .get (hostname , a .TokenTTL )
32
44
handshake := handshake.PeerIDAuthHandshakeClient {
@@ -36,7 +48,7 @@ func (a *ClientPeerIDAuth) AuthenticatedDo(client *http.Client, req *http.Reques
36
48
37
49
if hasToken {
38
50
// We have a token. Attempt to use that, but fallback to server initiated challenge if it fails.
39
- peer , resp , err := a .doWithToken (client , req , ti )
51
+ peer , resp , err := a .doWithToken (rt , req , ti )
40
52
switch {
41
53
case err == nil :
42
54
return peer , resp , nil
@@ -62,7 +74,7 @@ func (a *ClientPeerIDAuth) AuthenticatedDo(client *http.Client, req *http.Reques
62
74
handshake .SetInitiateChallenge ()
63
75
}
64
76
65
- serverPeerID , resp , err := a .runHandshake (client , req , clearBody (req ), & handshake )
77
+ serverPeerID , resp , err := a .runHandshake (rt , req , clearBody (req ), & handshake )
66
78
if err != nil {
67
79
return "" , nil , fmt .Errorf ("failed to run handshake: %w" , err )
68
80
}
@@ -74,7 +86,12 @@ func (a *ClientPeerIDAuth) AuthenticatedDo(client *http.Client, req *http.Reques
74
86
return serverPeerID , resp , nil
75
87
}
76
88
77
- func (a * ClientPeerIDAuth ) runHandshake (client * http.Client , req * http.Request , b bodyMeta , hs * handshake.PeerIDAuthHandshakeClient ) (peer.ID , * http.Response , error ) {
89
+ func (a * ClientPeerIDAuth ) HasToken (hostname string ) bool {
90
+ _ , hasToken := a .tm .get (hostname , a .TokenTTL )
91
+ return hasToken
92
+ }
93
+
94
+ func (a * ClientPeerIDAuth ) runHandshake (rt http.RoundTripper , req * http.Request , b bodyMeta , hs * handshake.PeerIDAuthHandshakeClient ) (peer.ID , * http.Response , error ) {
78
95
maxSteps := 5 // Avoid infinite loops in case of buggy handshake. Shouldn't happen.
79
96
var resp * http.Response
80
97
@@ -92,7 +109,7 @@ func (a *ClientPeerIDAuth) runHandshake(client *http.Client, req *http.Request,
92
109
b .setBody (req )
93
110
}
94
111
95
- resp , err = client . Do (req )
112
+ resp , err = rt . RoundTrip (req )
96
113
if err != nil {
97
114
return "" , nil , err
98
115
}
@@ -119,10 +136,10 @@ func (a *ClientPeerIDAuth) runHandshake(client *http.Client, req *http.Request,
119
136
120
137
var errTokenRejected = errors .New ("token rejected" )
121
138
122
- func (a * ClientPeerIDAuth ) doWithToken (client * http.Client , req * http.Request , ti tokenInfo ) (peer.ID , * http.Response , error ) {
139
+ func (a * ClientPeerIDAuth ) doWithToken (rt http.RoundTripper , req * http.Request , ti tokenInfo ) (peer.ID , * http.Response , error ) {
123
140
// Try to make the request with the token
124
141
req .Header .Set ("Authorization" , ti .token )
125
- resp , err := client . Do (req )
142
+ resp , err := rt . RoundTrip (req )
126
143
if err != nil {
127
144
return "" , nil , err
128
145
}
0 commit comments