44 "context"
55 "encoding/json"
66 "fmt"
7+ "io"
78 "net/http"
9+ "net/url"
810 "strings"
911 "time"
1012)
@@ -35,7 +37,21 @@ var defaultProtocols = []p2pProtocol{
3537
3638// registerKuboProtocols registers p2p protocol listeners on kubo via its HTTP API.
3739// Each protocol maps a libp2p stream protocol to a local TCP address.
40+ // It first closes ALL existing p2p listeners to clear any stale state from
41+ // previous go-fula processes, then registers fresh listeners.
3842func registerKuboProtocols (kuboAPI string ) error {
43+ // Close all existing p2p listeners first to clear stale state.
44+ // This is safe because go-fula owns all p2p protocol registrations on kubo.
45+ closeAllURL := fmt .Sprintf ("http://%s/api/v0/p2p/close?all=true" , kuboAPI )
46+ closeResp , err := http .Post (closeAllURL , "" , nil )
47+ if err != nil {
48+ log .Warnw ("Could not close existing p2p listeners" , "err" , err )
49+ } else {
50+ body , _ := io .ReadAll (closeResp .Body )
51+ closeResp .Body .Close ()
52+ log .Debugw ("Closed existing p2p listeners" , "status" , closeResp .StatusCode , "response" , string (body ))
53+ }
54+
3955 for _ , p := range defaultProtocols {
4056 if err := registerSingleProtocol (kuboAPI , p .name , p .target ); err != nil {
4157 return fmt .Errorf ("failed to register protocol %s: %w" , p .name , err )
@@ -46,21 +62,9 @@ func registerKuboProtocols(kuboAPI string) error {
4662}
4763
4864func registerSingleProtocol (kuboAPI , protocol , target string ) error {
49- // First close any existing listener for this protocol (idempotent).
50- // Use only arg=<protocol> so it matches regardless of listen/target address.
51- closeURL := fmt .Sprintf ("http://%s/api/v0/p2p/close?arg=%s" ,
52- kuboAPI , protocol )
53- closeResp , err := http .Post (closeURL , "" , nil )
54- if err != nil {
55- log .Debugw ("Could not close existing p2p listener (may not exist)" , "protocol" , protocol , "err" , err )
56- } else {
57- closeResp .Body .Close ()
58- }
59-
60- // Register the protocol
61- url := fmt .Sprintf ("http://%s/api/v0/p2p/listen?arg=%s&arg=%s&allow-custom-protocol=true" ,
62- kuboAPI , protocol , target )
63- resp , err := http .Post (url , "" , nil )
65+ listenURL := fmt .Sprintf ("http://%s/api/v0/p2p/listen?arg=%s&arg=%s&allow-custom-protocol=true" ,
66+ kuboAPI , url .QueryEscape (protocol ), url .QueryEscape (target ))
67+ resp , err := http .Post (listenURL , "" , nil )
6468 if err != nil {
6569 return fmt .Errorf ("kubo API request failed: %w" , err )
6670 }
@@ -70,7 +74,6 @@ func registerSingleProtocol(kuboAPI, protocol, target string) error {
7074 body := make ([]byte , 512 )
7175 n , _ := resp .Body .Read (body )
7276 bodyStr := string (body [:n ])
73- // "listener already registered" means the protocol is active — not an error
7477 if strings .Contains (bodyStr , "listener already registered" ) {
7578 log .Debugw ("Protocol already registered, treating as success" , "protocol" , protocol )
7679 return nil
0 commit comments