@@ -5,23 +5,43 @@ import (
55 "encoding/json"
66 "errors"
77 "fmt"
8+ "io"
89 "os"
910 "time"
1011
1112 "github.com/ipfs/boxo/ipns"
1213 "github.com/ipfs/boxo/routing/http/client"
1314 "github.com/ipfs/boxo/routing/http/types"
15+ "github.com/ipfs/boxo/routing/http/types/iter"
1416 "github.com/ipfs/go-cid"
1517 "github.com/libp2p/go-libp2p/core/peer"
1618)
1719
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 ) {
1927 drc , err := client .New (endpoint )
2028 if err != nil {
21- return err
29+ return nil , err
2230 }
2331
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 )
2545 if err != nil {
2646 return err
2747 }
@@ -40,33 +60,24 @@ func findProviders(ctx context.Context, key cid.Cid, endpoint string, prettyOutp
4060 return nil
4161 }
4262
43- if prettyOutput {
63+ if a . pretty {
4464 switch res .Val .GetSchema () {
4565 case types .SchemaPeer :
4666 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 )
5970 default :
6071 // 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 )
6273 if err != nil {
6374 return err
6475 }
6576 }
6677
67- fmt .Fprintln (os . Stdout )
78+ fmt .Fprintln (a . out )
6879 } else {
69- err := json .NewEncoder (os . Stdout ).Encode (res .Val )
80+ err := json .NewEncoder (a . out ).Encode (res .Val )
7081 if err != nil {
7182 return err
7283 }
@@ -76,13 +87,56 @@ func findProviders(ctx context.Context, key cid.Cid, endpoint string, prettyOutp
7687 return nil
7788}
7889
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 ... )
8199 if err != nil {
82100 return err
83101 }
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+ }
84134
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 )
86140 if err != nil {
87141 return err
88142 }
@@ -101,13 +155,13 @@ func findPeers(ctx context.Context, pid peer.ID, endpoint string, prettyOutput b
101155 return nil
102156 }
103157
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 )
109163 } else {
110- err := json .NewEncoder (os . Stdout ).Encode (res .Val )
164+ err := json .NewEncoder (a . out ).Encode (res .Val )
111165 if err != nil {
112166 return err
113167 }
@@ -117,18 +171,30 @@ func findPeers(ctx context.Context, pid peer.ID, endpoint string, prettyOutput b
117171 return nil
118172}
119173
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 ... )
122183 if err != nil {
123184 return err
124185 }
186+ defer recordsIter .Close ()
125187
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 )
127193 if err != nil {
128194 return err
129195 }
130196
131- if prettyOutput {
197+ if a . pretty {
132198 v , err := rec .Value ()
133199 if err != nil {
134200 return err
@@ -144,19 +210,19 @@ func getIPNS(ctx context.Context, name ipns.Name, endpoint string, prettyOutput
144210 return err
145211 }
146212
147- fmt .Printf ( "/ipns/%s\n " , name )
213+ fmt .Fprintf ( a . out , "/ipns/%s\n " , name )
148214
149215 // Since [client.Client.GetIPNS] verifies if the retrieved record is valid, we
150216 // do not need to verify it again. However, if you were not using this specific
151217 // client, but using some other tool, you should always validate the IPNS Record
152218 // 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 ))
158224 if ttl , err := rec .TTL (); err == nil {
159- fmt .Println ( "\t TTL:" , ttl .String ())
225+ fmt .Fprintln ( a . out , "\t TTL:" , ttl .String ())
160226 }
161227
162228 return nil
@@ -167,20 +233,15 @@ func getIPNS(ctx context.Context, name ipns.Name, endpoint string, prettyOutput
167233 return err
168234 }
169235
170- _ , err = os . Stdout .Write (raw )
236+ _ , err = a . out .Write (raw )
171237 return err
172238}
173239
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 {
180241 rec , err := ipns .UnmarshalRecord (record )
181242 if err != nil {
182243 return err
183244 }
184245
185- return drc .PutIPNS (ctx , name , rec )
246+ return a . drc .PutIPNS (ctx , name , rec )
186247}
0 commit comments