Repository: libp2p/go-libp2p
Pull request #2757 (2024-04-03 18:23:59)

libp2phttp: Rename well-known resource
Renaming the well-known libp2p http resource. Context here: https://github.com/libp2p/specs/pull/508#discussion_r1550043195


Patch:
diff --git a/p2p/http/libp2phttp.go b/p2p/http/libp2phttp.go
index fbd8a64f..21b18890 100644
--- a/p2p/http/libp2phttp.go
+++ b/p2p/http/libp2phttp.go
@@ -30,6 +30,7 @@ import (
 var log = logging.Logger("libp2phttp")
 
 const ProtocolIDForMultistreamSelect = "/http/1.1"
+const WellKnownProtocols = "/.well-known/libp2p/protocols"
 const peerMetadataLimit = 8 << 10 // 8KB
 const peerMetadataLRUSize = 256   // How many different peer's metadata to keep in our LRU cache
 
@@ -41,7 +42,7 @@ type ProtocolMeta struct {
 
 type PeerMeta map[protocol.ID]ProtocolMeta
 
-// WellKnownHandler is an http.Handler that serves the .well-known/libp2p resource
+// WellKnownHandler is an http.Handler that serves the well-known resource
 type WellKnownHandler struct {
 	wellknownMapMu   sync.Mutex
 	wellKnownMapping PeerMeta
@@ -137,7 +138,7 @@ type Host struct {
 	// `http.Transport` on first use.
 	DefaultClientRoundTripper *http.Transport
 
-	// WellKnownHandler is the http handler for the `.well-known/libp2p`
+	// WellKnownHandler is the http handler for the well-known
 	// resource. It is responsible for sharing this node's protocol metadata
 	// with other nodes. Users only care about this if they set their own
 	// ServeMux with pre-existing routes. By default, new protocols are added
@@ -270,7 +271,7 @@ func (h *Host) Serve() error {
 	}
 
 	h.serveMuxInit()
-	h.ServeMux.Handle("/.well-known/libp2p", &h.WellKnownHandler)
+	h.ServeMux.Handle(WellKnownProtocols, &h.WellKnownHandler)
 
 	h.httpTransportInit()
 
@@ -352,7 +353,7 @@ func (h *Host) Close() error {
 }
 
 // SetHTTPHandler sets the HTTP handler for a given protocol. Automatically
-// manages the .well-known/libp2p mapping.
+// manages the well-known resource mapping.
 // http.StripPrefix is called on the handler, so the handler will be unaware of
 // its prefix path.
 func (h *Host) SetHTTPHandler(p protocol.ID, handler http.Handler) {
@@ -360,7 +361,7 @@ func (h *Host) SetHTTPHandler(p protocol.ID, handler http.Handler) {
 }
 
 // SetHTTPHandlerAtPath sets the HTTP handler for a given protocol using the
-// given path. Automatically manages the .well-known/libp2p mapping.
+// given path. Automatically manages the well-known resource mapping.
 // http.StripPrefix is called on the handler, so the handler will be unaware of
 // its prefix path.
 func (h *Host) SetHTTPHandlerAtPath(p protocol.ID, path string, handler http.Handler) {
@@ -743,7 +744,7 @@ func (h *Host) getAndStorePeerMetadata(roundtripper http.RoundTripper, server pe
 		return meta, nil
 	}
 
-	req, err := http.NewRequest("GET", "/.well-known/libp2p", nil)
+	req, err := http.NewRequest("GET", WellKnownProtocols, nil)
 	if err != nil {
 		return nil, err
 	}
diff --git a/p2p/transport/quic/cmd/client/main.go b/p2p/transport/quic/cmd/client/main.go
index 5736d895..78736253 100644
--- a/p2p/transport/quic/cmd/client/main.go
+++ b/p2p/transport/quic/cmd/client/main.go
@@ -1,11 +1,20 @@
 package main
 
 import (
+	"context"
+	"crypto/rand"
 	"fmt"
+	"io"
 	"log"
 	"os"
 
-	cmdlib "github.com/libp2p/go-libp2p/p2p/transport/quic/cmd/lib"
+	ic "github.com/libp2p/go-libp2p/core/crypto"
+	"github.com/libp2p/go-libp2p/core/peer"
+	libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
+	"github.com/libp2p/go-libp2p/p2p/transport/quicreuse"
+
+	ma "github.com/multiformats/go-multiaddr"
+	"github.com/quic-go/quic-go"
 )
 
 func main() {
@@ -13,7 +22,57 @@ func main() {
 		fmt.Printf("Usage: %s <multiaddr> <peer id>", os.Args[0])
 		return
 	}
-	if err := cmdlib.RunClient(os.Args[1], os.Args[2]); err != nil {
+	if err := run(os.Args[1], os.Args[2]); err != nil {
 		log.Fatalf(err.Error())
 	}
 }
+
+func run(raddr string, p string) error {
+	peerID, err := peer.Decode(p)
+	if err != nil {
+		return err
+	}
+	addr, err := ma.NewMultiaddr(raddr)
+	if err != nil {
+		return err
+	}
+	priv, _, err := ic.GenerateECDSAKeyPair(rand.Reader)
+	if err != nil {
+		return err
+	}
+
+	reuse, err := quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
+	if err != nil {
+		return err
+	}
+	t, err := libp2pquic.NewTransport(priv, reuse, nil, nil, nil)
+	if err != nil {
+		return err
+	}
+
+	log.Printf("Dialing %s\n", addr.String())
+	conn, err := t.Dial(context.Background(), addr, peerID)
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+	str, err := conn.OpenStream(context.Background())
+	if err != nil {
+		return err
+	}
+	defer str.Close()
+	const msg = "Hello world!"
+	log.Printf("Sending: %s\n", msg)
+	if _, err := str.Write([]byte(msg)); err != nil {
+		return err
+	}
+	if err := str.CloseWrite(); err != nil {
+		return err
+	}
+	data, err := io.ReadAll(str)
+	if err != nil {
+		return err
+	}
+	log.Printf("Received: %s\n", data)
+	return nil
+}
diff --git a/p2p/transport/quic/cmd/lib/lib.go b/p2p/transport/quic/cmd/lib/lib.go
deleted file mode 100644
index fd2a270a..00000000
--- a/p2p/transport/quic/cmd/lib/lib.go
+++ /dev/null
@@ -1,129 +0,0 @@
-package cmdlib
-
-import (
-	"context"
-	"crypto/rand"
-	"fmt"
-	"io"
-	"log"
-
-	ic "github.com/libp2p/go-libp2p/core/crypto"
-	"github.com/libp2p/go-libp2p/core/peer"
-	tpt "github.com/libp2p/go-libp2p/core/transport"
-	libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
-	"github.com/libp2p/go-libp2p/p2p/transport/quicreuse"
-
-	ma "github.com/multiformats/go-multiaddr"
-	"github.com/quic-go/quic-go"
-)
-
-func RunClient(raddr string, p string) error {
-	peerID, err := peer.Decode(p)
-	if err != nil {
-		return err
-	}
-	addr, err := ma.NewMultiaddr(raddr)
-	if err != nil {
-		return err
-	}
-	priv, _, err := ic.GenerateECDSAKeyPair(rand.Reader)
-	if err != nil {
-		return err
-	}
-
-	reuse, err := quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
-	if err != nil {
-		return err
-	}
-	t, err := libp2pquic.NewTransport(priv, reuse, nil, nil, nil)
-	if err != nil {
-		return err
-	}
-
-	log.Printf("Dialing %s\n", addr.String())
-	conn, err := t.Dial(context.Background(), addr, peerID)
-	if err != nil {
-		return err
-	}
-	defer conn.Close()
-	str, err := conn.OpenStream(context.Background())
-	if err != nil {
-		return err
-	}
-	defer str.Close()
-	const msg = "Hello world!"
-	log.Printf("Sending: %s\n", msg)
-	if _, err := str.Write([]byte(msg)); err != nil {
-		return err
-	}
-	if err := str.CloseWrite(); err != nil {
-		return err
-	}
-	data, err := io.ReadAll(str)
-	if err != nil {
-		return err
-	}
-	log.Printf("Received: %s\n", data)
-	return nil
-}
-
-func RunServer(port string, location chan peer.AddrInfo) error {
-	addr, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/0.0.0.0/udp/%s/quic-v1", port))
-	if err != nil {
-		return err
-	}
-	priv, _, err := ic.GenerateECDSAKeyPair(rand.Reader)
-	if err != nil {
-		return err
-	}
-	peerID, err := peer.IDFromPrivateKey(priv)
-	if err != nil {
-		return err
-	}
-
-	reuse, err := quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
-	if err != nil {
-		return err
-	}
-	t, err := libp2pquic.NewTransport(priv, reuse, nil, nil, nil)
-	if err != nil {
-		return err
-	}
-
-	ln, err := t.Listen(addr)
-	if err != nil {
-		return err
-	}
-	fmt.Printf("Listening. Now run: go run cmd/client/main.go %s %s\n", ln.Multiaddr(), peerID)
-	if location != nil {
-		location <- peer.AddrInfo{ID: peerID, Addrs: []ma.Multiaddr{ln.Multiaddr()}}
-	}
-	for {
-		conn, err := ln.Accept()
-		if err != nil {
-			return err
-		}
-		log.Printf("Accepted new connection from %s (%s)\n", conn.RemotePeer(), conn.RemoteMultiaddr())
-		go func() {
-			if err := handleConn(conn); err != nil {
-				log.Printf("handling conn failed: %s", err.Error())
-			}
-		}()
-	}
-}
-
-func handleConn(conn tpt.CapableConn) error {
-	str, err := conn.AcceptStream()
-	if err != nil {
-		return err
-	}
-	data, err := io.ReadAll(str)
-	if err != nil {
-		return err
-	}
-	log.Printf("Received: %s\n", data)
-	if _, err := str.Write(data); err != nil {
-		return err
-	}
-	return str.Close()
-}
diff --git a/p2p/transport/quic/cmd/server/main.go b/p2p/transport/quic/cmd/server/main.go
index ef3f90a4..222841d4 100644
--- a/p2p/transport/quic/cmd/server/main.go
+++ b/p2p/transport/quic/cmd/server/main.go
@@ -1,11 +1,20 @@
 package main
 
 import (
+	"crypto/rand"
 	"fmt"
+	"io"
 	"log"
 	"os"
 
-	cmdlib "github.com/libp2p/go-libp2p/p2p/transport/quic/cmd/lib"
+	ic "github.com/libp2p/go-libp2p/core/crypto"
+	"github.com/libp2p/go-libp2p/core/peer"
+	tpt "github.com/libp2p/go-libp2p/core/transport"
+	libp2pquic "github.com/libp2p/go-libp2p/p2p/transport/quic"
+	"github.com/libp2p/go-libp2p/p2p/transport/quicreuse"
+
+	ma "github.com/multiformats/go-multiaddr"
+	"github.com/quic-go/quic-go"
 )
 
 func main() {
@@ -13,7 +22,65 @@ func main() {
 		fmt.Printf("Usage: %s <port>", os.Args[0])
 		return
 	}
-	if err := cmdlib.RunServer(os.Args[1], nil); err != nil {
+	if err := run(os.Args[1]); err != nil {
 		log.Fatalf(err.Error())
 	}
 }
+
+func run(port string) error {
+	addr, err := ma.NewMultiaddr(fmt.Sprintf("/ip4/0.0.0.0/udp/%s/quic", port))
+	if err != nil {
+		return err
+	}
+	priv, _, err := ic.GenerateECDSAKeyPair(rand.Reader)
+	if err != nil {
+		return err
+	}
+	peerID, err := peer.IDFromPrivateKey(priv)
+	if err != nil {
+		return err
+	}
+
+	reuse, err := quicreuse.NewConnManager(quic.StatelessResetKey{}, quic.TokenGeneratorKey{})
+	if err != nil {
+		return err
+	}
+	t, err := libp2pquic.NewTransport(priv, reuse, nil, nil, nil)
+	if err != nil {
+		return err
+	}
+
+	ln, err := t.Listen(addr)
+	if err != nil {
+		return err
+	}
+	fmt.Printf("Listening. Now run: go run cmd/client/main.go %s %s\n", ln.Multiaddr(), peerID)
+	for {
+		conn, err := ln.Accept()
+		if err != nil {
+			return err
+		}
+		log.Printf("Accepted new connection from %s (%s)\n", conn.RemotePeer(), conn.RemoteMultiaddr())
+		go func() {
+			if err := handleConn(conn); err != nil {
+				log.Printf("handling conn failed: %s", err.Error())
+			}
+		}()
+	}
+}
+
+func handleConn(conn tpt.CapableConn) error {
+	str, err := conn.AcceptStream()
+	if err != nil {
+		return err
+	}
+	data, err := io.ReadAll(str)
+	if err != nil {
+		return err
+	}
+	log.Printf("Received: %s\n", data)
+	if _, err := str.Write(data); err != nil {
+		return err
+	}
+	return str.Close()
+}


Test patch:
diff --git a/p2p/http/example_test.go b/p2p/http/example_test.go
index 2e90f8cc..a9992d34 100644
--- a/p2p/http/example_test.go
+++ b/p2p/http/example_test.go
@@ -57,7 +57,7 @@ func ExampleHost_withAStockGoHTTPClient() {
 }
 
 func ExampleHost_listenOnHTTPTransportAndStreams() {
-	serverStreamHost, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/127.0.0.1/udp/0/quic-v1"))
+	serverStreamHost, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/127.0.0.1/udp/50124/quic-v1"))
 	if err != nil {
 		log.Fatal(err)
 	}
@@ -65,18 +65,14 @@ func ExampleHost_listenOnHTTPTransportAndStreams() {
 
 	server := libp2phttp.Host{
 		InsecureAllowHTTP: true, // For our example, we'll allow insecure HTTP
-		ListenAddrs:       []ma.Multiaddr{ma.StringCast("/ip4/127.0.0.1/tcp/0/http")},
+		ListenAddrs:       []ma.Multiaddr{ma.StringCast("/ip4/127.0.0.1/tcp/50124/http")},
 		StreamHost:        serverStreamHost,
 	}
 	go server.Serve()
 	defer server.Close()
 
-	for _, a := range server.Addrs() {
-		_, transport := ma.SplitLast(a)
-		fmt.Printf("Server listening on transport: %s\n", transport)
-	}
-	// Output: Server listening on transport: /quic-v1
-	// Server listening on transport: /http
+	fmt.Println("Server listening on:", server.Addrs())
+	// Output: Server listening on: [/ip4/127.0.0.1/udp/50124/quic-v1 /ip4/127.0.0.1/tcp/50124/http]
 }
 
 func ExampleHost_overLibp2pStreams() {
@@ -339,11 +335,11 @@ func ExampleWellKnownHandler() {
 	}
 
 	defer listener.Close()
-	// Serve `.well-known/libp2p`. Note, this is handled automatically if you use the libp2phttp.Host.
+	// Serve the well-known resource. Note, this is handled automatically if you use the libp2phttp.Host.
 	go http.Serve(listener, &h)
 
-	// Get the `.well-known/libp2p` resource
-	resp, err := http.Get("http://" + listener.Addr().String() + "/.well-known/libp2p")
+	// Get the well-known resource
+	resp, err := http.Get("http://" + listener.Addr().String() + libp2phttp.WellKnownProtocols)
 	if err != nil {
 		log.Fatal(err)
 	}
diff --git a/p2p/http/libp2phttp_test.go b/p2p/http/libp2phttp_test.go
index 57dd0cc8..c5616fea 100644
--- a/p2p/http/libp2phttp_test.go
+++ b/p2p/http/libp2phttp_test.go
@@ -205,7 +205,7 @@ func TestRoundTrippers(t *testing.T) {
 				})
 			}
 
-			// Read the .well-known/libp2p resource
+			// Read the well-known resource
 			wk, err := rt.(libp2phttp.PeerMetadataGetter).GetPeerMetadata()
 			require.NoError(t, err)
 
@@ -219,7 +219,7 @@ func TestRoundTrippers(t *testing.T) {
 func TestPlainOldHTTPServer(t *testing.T) {
 	mux := http.NewServeMux()
 	wk := libp2phttp.WellKnownHandler{}
-	mux.Handle("/.well-known/libp2p", &wk)
+	mux.Handle(libp2phttp.WellKnownProtocols, &wk)
 
 	mux.Handle("/ping/", httpping.Ping{})
 	wk.AddProtocolMeta(httpping.PingProtocolID, libp2phttp.ProtocolMeta{Path: "/ping/"})
@@ -270,7 +270,7 @@ func TestPlainOldHTTPServer(t *testing.T) {
 			},
 			getWellKnown: func(t *testing.T) (libp2phttp.PeerMeta, error) {
 				client := http.Client{}
-				resp, err := client.Get("http://" + l.Addr().String() + "/.well-known/libp2p")
+				resp, err := client.Get("http://" + l.Addr().String() + libp2phttp.WellKnownProtocols)
 				require.NoError(t, err)
 
 				b, err := io.ReadAll(resp.Body)
diff --git a/p2p/transport/quic/cmd/lib/lib_test.go b/p2p/transport/quic/cmd/lib/lib_test.go
deleted file mode 100644
index 1058b078..00000000
--- a/p2p/transport/quic/cmd/lib/lib_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package cmdlib
-
-import (
-	"testing"
-
-	"github.com/libp2p/go-libp2p/core/peer"
-	"github.com/multiformats/go-multiaddr"
-)
-
-func TestCmd(t *testing.T) {
-	serverLocation := make(chan peer.AddrInfo)
-	go RunServer("0", serverLocation)
-
-	l := <-serverLocation
-
-	ip, rest := multiaddr.SplitFirst(l.Addrs[0])
-	if ip.Protocol().Code == multiaddr.P_IP4 && ip.Value() == "0.0.0.0" {
-		// Windows can't dial to 0.0.0.0 so replace with localhost
-		var err error
-		ip, err = multiaddr.NewComponent("ip4", "127.0.0.1")
-		if err != nil {
-			t.Fatal(err)
-		}
-	}
-
-	err := RunClient(multiaddr.Join(ip, rest).String(), l.ID.String())
-	if err != nil {
-		t.Fatal(err)
-	}
-}