libp2p / go-libp2p-http

HTTP on top of libp2p
MIT License
63 stars 20 forks source link

Protocols not supported error #92

Closed alrevuelta closed 8 months ago

alrevuelta commented 8 months ago

Should this example work as it is? It's almost a copy-paste from the docs but I'm getting the following error:

protocols not supported: [/libp2p-http]

To Reproduce

In two terminals run the following. It should work as it is.

go run main.go server

And:

go run main.go client

Code here:

package main

import (
    "fmt"
    "math"
    "net/http"
    "os"
    "os/signal"
    "syscall"

    log "github.com/sirupsen/logrus"

    "github.com/libp2p/go-libp2p"
    gostream "github.com/libp2p/go-libp2p-gostream"
    p2phttp "github.com/libp2p/go-libp2p-http"
    "github.com/libp2p/go-libp2p/core/crypto"
    "github.com/libp2p/go-libp2p/core/peer"
    "github.com/multiformats/go-multiaddr"
    "github.com/urfave/cli/v2"
)

func main() {

    app := &cli.App{
        Commands: []*cli.Command{
            {
                Name: "server",
                Action: func(cCtx *cli.Context) error {
                    Server()
                    return nil
                },
            },
            {
                Name: "client",
                Action: func(cCtx *cli.Context) error {
                    Client()
                    return nil
                },
            },
        },
    }

    if err := app.Run(os.Args); err != nil {
        log.Fatal(err)
    }

    // Wait for signal.
    sigCh := make(chan os.Signal, 1)
    signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM, os.Interrupt)

    for {
        sig := <-sigCh

        if sig == syscall.SIGINT || sig == syscall.SIGTERM || sig == os.Interrupt || sig == os.Kill {
            break
        }
    }

    log.Info("Stopped")
}

func Server() {

    privKey, err := crypto.UnmarshalPrivateKey([]byte{8, 2, 18, 32, 73, 86, 57, 125, 178, 117, 93, 80, 93, 190, 241, 90, 74, 102, 209, 143, 142, 65, 218, 198, 114, 127, 65, 164, 191, 227, 20, 115, 115, 32, 201, 253})
    if err != nil {
        log.Fatal("error unmarshaling private key: ", err)
    }

    host, err := libp2p.New(
        libp2p.Identity(privKey),
        libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 4000)),
    )

    if err != nil {
        log.Fatal("error creating host: ", err)
    }

    log.Info("Host addresses: ", host.Addrs())
    log.Info("Host peerid: ", host.ID().String())

    listener, err := gostream.Listen(host, p2phttp.DefaultP2PProtocol)
    if err != nil {
        log.Fatal("error creating listener: ", err)
    }

    //defer listener.Close()
    go func() {
        http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
            w.Write([]byte("Hi!"))
        })
        server := &http.Server{}
        server.Serve(listener)
    }()
}

func Client() {

    host, err := libp2p.New(
        libp2p.ListenAddrStrings(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 4001)),
    )
    if err != nil {
        log.Fatal("error creating host: ", err)
    }

    log.Info("Host addresses: ", host.Addrs())
    log.Info("Host peerid: ", host.ID().String())

    destNode, err := peer.Decode("16Uiu2HAkuYuv5y1oGQSccX5kxYnW6MDZ2QqPi5y6HjL2baUSDP9W")
    if err != nil {
        log.Fatal("error decoding peerId: ", err)
    }

    destMulti, err := multiaddr.NewMultiaddr("/ip4/127.0.0.1/tcp/4000")
    if err != nil {
        log.Fatal("error parsin multiaddr: ", err)
    }

    host.Peerstore().AddAddr(destNode, destMulti, math.MaxInt64)

    tr := &http.Transport{}
    tr.RegisterProtocol("libp2p", p2phttp.NewTransport(host, p2phttp.ProtocolOption(p2phttp.DefaultP2PProtocol)))
    client := &http.Client{Transport: tr}
    res, err := client.Get("libp2p://16Uiu2HAkuYuv5y1oGQSccX5kxYnW6MDZ2QqPi5y6HjL2baUSDP9W/hello")
    if err != nil {
        log.Fatal("failed in client.get", err)
    }

    log.Info("Respnse: ", res)
}
hsanjuan commented 8 months ago

What version of libp2p are you using? I don't find the source of this error anywhere in libp2p code.

With the latest libp2p version the test (which is pretty much the same as your code) does work: https://github.com/libp2p/go-libp2p-http/pull/93

I've looked at your code and I don't see an issue, unless you are trying to talk to the wrong peer ID somehow.

alrevuelta commented 8 months ago

My bad thanks, just figured out that the defer listener.Close() before the go func() {}() was closing the listener prematurely in my function. Fixing that solves the issue.