@@ -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,24 +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 )
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 )
50
70
default :
51
71
// This is an unknown schema. Let's just print it raw.
52
- err := json .NewEncoder (os . Stdout ).Encode (res .Val )
72
+ err := json .NewEncoder (a . out ).Encode (res .Val )
53
73
if err != nil {
54
74
return err
55
75
}
56
76
}
57
77
58
- fmt .Fprintln (os . Stdout )
78
+ fmt .Fprintln (a . out )
59
79
} else {
60
- err := json .NewEncoder (os . Stdout ).Encode (res .Val )
80
+ err := json .NewEncoder (a . out ).Encode (res .Val )
61
81
if err != nil {
62
82
return err
63
83
}
@@ -67,13 +87,56 @@ func findProviders(ctx context.Context, key cid.Cid, endpoint string, prettyOutp
67
87
return nil
68
88
}
69
89
70
- func findPeers (ctx context.Context , pid peer.ID , endpoint string , prettyOutput bool ) error {
71
- 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 ... )
72
99
if err != nil {
73
100
return err
74
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 ()
75
109
76
- recordsIter , err := drc .FindPeers (ctx , pid )
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
+ }
134
+
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 )
77
140
if err != nil {
78
141
return err
79
142
}
@@ -92,13 +155,13 @@ func findPeers(ctx context.Context, pid peer.ID, endpoint string, prettyOutput b
92
155
return nil
93
156
}
94
157
95
- if prettyOutput {
96
- fmt .Fprintln (os . Stdout , res .Val .ID )
97
- fmt .Fprintln (os . Stdout , "\t Protocols:" , res .Val .Protocols )
98
- fmt .Fprintln (os . Stdout , "\t Addresses:" , res .Val .Addrs )
99
- 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 )
100
163
} else {
101
- err := json .NewEncoder (os . Stdout ).Encode (res .Val )
164
+ err := json .NewEncoder (a . out ).Encode (res .Val )
102
165
if err != nil {
103
166
return err
104
167
}
@@ -108,18 +171,30 @@ func findPeers(ctx context.Context, pid peer.ID, endpoint string, prettyOutput b
108
171
return nil
109
172
}
110
173
111
- func getIPNS (ctx context.Context , name ipns.Name , endpoint string , prettyOutput bool ) error {
112
- 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 ... )
113
183
if err != nil {
114
184
return err
115
185
}
186
+ defer recordsIter .Close ()
116
187
117
- 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 )
118
193
if err != nil {
119
194
return err
120
195
}
121
196
122
- if prettyOutput {
197
+ if a . pretty {
123
198
v , err := rec .Value ()
124
199
if err != nil {
125
200
return err
@@ -135,19 +210,19 @@ func getIPNS(ctx context.Context, name ipns.Name, endpoint string, prettyOutput
135
210
return err
136
211
}
137
212
138
- fmt .Printf ( "/ipns/%s\n " , name )
213
+ fmt .Fprintf ( a . out , "/ipns/%s\n " , name )
139
214
140
215
// Since [client.Client.GetIPNS] verifies if the retrieved record is valid, we
141
216
// do not need to verify it again. However, if you were not using this specific
142
217
// client, but using some other tool, you should always validate the IPNS Record
143
218
// using the [ipns.Validate] or [ipns.ValidateWithName] functions.
144
- fmt .Println ( "\t Signature Validated" )
145
- fmt .Println ( "\t Value:" , v .String ())
146
- fmt .Println ( "\t Sequence:" , seq )
147
- fmt .Println ( "\t ValidityType : EOL/End-of-Life" )
148
- 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 ))
149
224
if ttl , err := rec .TTL (); err == nil {
150
- fmt .Println ( "\t TTL:" , ttl .String ())
225
+ fmt .Fprintln ( a . out , "\t TTL:" , ttl .String ())
151
226
}
152
227
153
228
return nil
@@ -158,20 +233,15 @@ func getIPNS(ctx context.Context, name ipns.Name, endpoint string, prettyOutput
158
233
return err
159
234
}
160
235
161
- _ , err = os . Stdout .Write (raw )
236
+ _ , err = a . out .Write (raw )
162
237
return err
163
238
}
164
239
165
- func putIPNS (ctx context.Context , name ipns.Name , record []byte , endpoint string ) error {
166
- drc , err := client .New (endpoint )
167
- if err != nil {
168
- return err
169
- }
170
-
240
+ func (a * askClient ) putIPNS (ctx context.Context , name ipns.Name , record []byte ) error {
171
241
rec , err := ipns .UnmarshalRecord (record )
172
242
if err != nil {
173
243
return err
174
244
}
175
245
176
- return drc .PutIPNS (ctx , name , rec )
246
+ return a . drc .PutIPNS (ctx , name , rec )
177
247
}
0 commit comments