@@ -5,23 +5,43 @@ import (
5
5
"encoding/json"
6
6
"errors"
7
7
"fmt"
8
+ "io"
8
9
"os"
9
10
"time"
10
11
11
12
"github.com/ipfs/boxo/ipns"
12
13
"github.com/ipfs/boxo/routing/http/client"
13
14
"github.com/ipfs/boxo/routing/http/types"
15
+ "github.com/ipfs/boxo/routing/http/types/iter"
14
16
"github.com/ipfs/go-cid"
15
17
"github.com/libp2p/go-libp2p/core/peer"
16
18
)
17
19
18
- func findProviders (ctx context.Context , key cid.Cid , endpoint string , prettyOutput bool ) error {
20
+ type askClient struct {
21
+ drc * client.Client
22
+ out io.Writer
23
+ pretty bool
24
+ }
25
+
26
+ func newAskClient (endpoint string , prettyOutput bool , out io.Writer ) (* askClient , error ) {
19
27
drc , err := client .New (endpoint )
20
28
if err != nil {
21
- return err
29
+ return nil , err
22
30
}
23
31
24
- recordsIter , err := drc .FindProviders (ctx , key )
32
+ if out == nil {
33
+ out = os .Stdout
34
+ }
35
+
36
+ return & askClient {
37
+ drc : drc ,
38
+ pretty : prettyOutput ,
39
+ out : out ,
40
+ }, nil
41
+ }
42
+
43
+ func (a * askClient ) findProviders (ctx context.Context , key cid.Cid ) error {
44
+ recordsIter , err := a .drc .FindProviders (ctx , key )
25
45
if err != nil {
26
46
return err
27
47
}
@@ -40,33 +60,24 @@ func findProviders(ctx context.Context, key cid.Cid, endpoint string, prettyOutp
40
60
return nil
41
61
}
42
62
43
- if prettyOutput {
63
+ if a . pretty {
44
64
switch res .Val .GetSchema () {
45
65
case types .SchemaPeer :
46
66
record := res .Val .(* types.PeerRecord )
47
- fmt .Fprintln (os .Stdout , record .ID )
48
- fmt .Fprintln (os .Stdout , "\t Protocols:" , record .Protocols )
49
- fmt .Fprintln (os .Stdout , "\t Addresses:" , record .Addrs )
50
-
51
- //lint:ignore SA1019 // ignore staticcheck
52
- case types .SchemaBitswap :
53
- //lint:ignore SA1019 // ignore staticcheck
54
- record := res .Val .(* types.BitswapRecord )
55
- fmt .Fprintln (os .Stdout , record .ID )
56
- fmt .Fprintln (os .Stdout , "\t Protocol:" , record .Protocol )
57
- fmt .Fprintln (os .Stdout , "\t Addresses:" , record .Addrs )
58
-
67
+ fmt .Fprintln (a .out , record .ID )
68
+ fmt .Fprintln (a .out , "\t Protocols:" , record .Protocols )
69
+ fmt .Fprintln (a .out , "\t Addresses:" , record .Addrs )
59
70
default :
60
71
// This is an unknown schema. Let's just print it raw.
61
- err := json .NewEncoder (os . Stdout ).Encode (res .Val )
72
+ err := json .NewEncoder (a . out ).Encode (res .Val )
62
73
if err != nil {
63
74
return err
64
75
}
65
76
}
66
77
67
- fmt .Fprintln (os . Stdout )
78
+ fmt .Fprintln (a . out )
68
79
} else {
69
- err := json .NewEncoder (os . Stdout ).Encode (res .Val )
80
+ err := json .NewEncoder (a . out ).Encode (res .Val )
70
81
if err != nil {
71
82
return err
72
83
}
@@ -76,13 +87,56 @@ func findProviders(ctx context.Context, key cid.Cid, endpoint string, prettyOutp
76
87
return nil
77
88
}
78
89
79
- func findPeers (ctx context.Context , pid peer.ID , endpoint string , prettyOutput bool ) error {
80
- drc , err := client .New (endpoint )
90
+ func (a * askClient ) provide (ctx context.Context , records ... * types.AnnouncementRecord ) error {
91
+ for _ , rec := range records {
92
+ err := rec .Verify ()
93
+ if err != nil {
94
+ return err
95
+ }
96
+ }
97
+
98
+ recordsIter , err := a .drc .ProvideRecords (ctx , records ... )
81
99
if err != nil {
82
100
return err
83
101
}
102
+ defer recordsIter .Close ()
103
+ return a .printProvideResult (recordsIter )
104
+ }
105
+
106
+ func (a * askClient ) printProvideResult (recordsIter iter.ResultIter [* types.AnnouncementResponseRecord ]) error {
107
+ for recordsIter .Next () {
108
+ res := recordsIter .Val ()
109
+
110
+ // Check for error, but do not complain if we exceeded the timeout. We are
111
+ // expecting that to happen: we explicitly defined a timeout.
112
+ if res .Err != nil {
113
+ if ! errors .Is (res .Err , context .DeadlineExceeded ) {
114
+ return res .Err
115
+ }
116
+
117
+ return nil
118
+ }
119
+
120
+ if a .pretty {
121
+ if res .Val .Error != "" {
122
+ fmt .Fprintf (a .out , "Error: %s" , res .Val .Error )
123
+ } else {
124
+ fmt .Fprintf (a .out , "TTL: %s" , res .Val .TTL )
125
+ }
126
+ fmt .Fprintln (a .out )
127
+ } else {
128
+ err := json .NewEncoder (a .out ).Encode (res .Val )
129
+ if err != nil {
130
+ return err
131
+ }
132
+ }
133
+ }
84
134
85
- recordsIter , err := drc .FindPeers (ctx , pid )
135
+ return nil
136
+ }
137
+
138
+ func (a * askClient ) findPeers (ctx context.Context , pid peer.ID ) error {
139
+ recordsIter , err := a .drc .FindPeers (ctx , pid )
86
140
if err != nil {
87
141
return err
88
142
}
@@ -101,13 +155,13 @@ func findPeers(ctx context.Context, pid peer.ID, endpoint string, prettyOutput b
101
155
return nil
102
156
}
103
157
104
- if prettyOutput {
105
- fmt .Fprintln (os . Stdout , res .Val .ID )
106
- fmt .Fprintln (os . Stdout , "\t Protocols:" , res .Val .Protocols )
107
- fmt .Fprintln (os . Stdout , "\t Addresses:" , res .Val .Addrs )
108
- fmt .Fprintln (os . Stdout )
158
+ if a . pretty {
159
+ fmt .Fprintln (a . out , res .Val .ID )
160
+ fmt .Fprintln (a . out , "\t Protocols:" , res .Val .Protocols )
161
+ fmt .Fprintln (a . out , "\t Addresses:" , res .Val .Addrs )
162
+ fmt .Fprintln (a . out )
109
163
} else {
110
- err := json .NewEncoder (os . Stdout ).Encode (res .Val )
164
+ err := json .NewEncoder (a . out ).Encode (res .Val )
111
165
if err != nil {
112
166
return err
113
167
}
@@ -117,18 +171,30 @@ func findPeers(ctx context.Context, pid peer.ID, endpoint string, prettyOutput b
117
171
return nil
118
172
}
119
173
120
- func getIPNS (ctx context.Context , name ipns.Name , endpoint string , prettyOutput bool ) error {
121
- drc , err := client .New (endpoint )
174
+ func (a * askClient ) providePeer (ctx context.Context , records ... * types.AnnouncementRecord ) error {
175
+ for _ , rec := range records {
176
+ err := rec .Verify ()
177
+ if err != nil {
178
+ return err
179
+ }
180
+ }
181
+
182
+ recordsIter , err := a .drc .ProvidePeerRecords (ctx , records ... )
122
183
if err != nil {
123
184
return err
124
185
}
186
+ defer recordsIter .Close ()
125
187
126
- rec , err := drc .GetIPNS (ctx , name )
188
+ return a .printProvideResult (recordsIter )
189
+ }
190
+
191
+ func (a * askClient ) getIPNS (ctx context.Context , name ipns.Name ) error {
192
+ rec , err := a .drc .GetIPNS (ctx , name )
127
193
if err != nil {
128
194
return err
129
195
}
130
196
131
- if prettyOutput {
197
+ if a . pretty {
132
198
v , err := rec .Value ()
133
199
if err != nil {
134
200
return err
@@ -144,19 +210,19 @@ func getIPNS(ctx context.Context, name ipns.Name, endpoint string, prettyOutput
144
210
return err
145
211
}
146
212
147
- fmt .Printf ( "/ipns/%s\n " , name )
213
+ fmt .Fprintf ( a . out , "/ipns/%s\n " , name )
148
214
149
215
// Since [client.Client.GetIPNS] verifies if the retrieved record is valid, we
150
216
// do not need to verify it again. However, if you were not using this specific
151
217
// client, but using some other tool, you should always validate the IPNS Record
152
218
// using the [ipns.Validate] or [ipns.ValidateWithName] functions.
153
- fmt .Println ( "\t Signature Validated" )
154
- fmt .Println ( "\t Value:" , v .String ())
155
- fmt .Println ( "\t Sequence:" , seq )
156
- fmt .Println ( "\t ValidityType : EOL/End-of-Life" )
157
- fmt .Println ( "\t Validity:" , eol .Format (time .RFC3339 ))
219
+ fmt .Fprintln ( a . out , "\t Signature Validated" )
220
+ fmt .Fprintln ( a . out , "\t Value:" , v .String ())
221
+ fmt .Fprintln ( a . out , "\t Sequence:" , seq )
222
+ fmt .Fprintln ( a . out , "\t ValidityType : EOL/End-of-Life" )
223
+ fmt .Fprintln ( a . out , "\t Validity:" , eol .Format (time .RFC3339 ))
158
224
if ttl , err := rec .TTL (); err == nil {
159
- fmt .Println ( "\t TTL:" , ttl .String ())
225
+ fmt .Fprintln ( a . out , "\t TTL:" , ttl .String ())
160
226
}
161
227
162
228
return nil
@@ -167,20 +233,15 @@ func getIPNS(ctx context.Context, name ipns.Name, endpoint string, prettyOutput
167
233
return err
168
234
}
169
235
170
- _ , err = os . Stdout .Write (raw )
236
+ _ , err = a . out .Write (raw )
171
237
return err
172
238
}
173
239
174
- func putIPNS (ctx context.Context , name ipns.Name , record []byte , endpoint string ) error {
175
- drc , err := client .New (endpoint )
176
- if err != nil {
177
- return err
178
- }
179
-
240
+ func (a * askClient ) putIPNS (ctx context.Context , name ipns.Name , record []byte ) error {
180
241
rec , err := ipns .UnmarshalRecord (record )
181
242
if err != nil {
182
243
return err
183
244
}
184
245
185
- return drc .PutIPNS (ctx , name , rec )
246
+ return a . drc .PutIPNS (ctx , name , rec )
186
247
}
0 commit comments