libp2p / go-libp2p-http

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

Where is the definition of Serve in the line of server.Serve(listener)? #69

Closed askquestions closed 3 years ago

askquestions commented 3 years ago

In the following code snippet in p2phttp_test.go, where is the definition of Serve in the line of server.Serve(listener)? go func() { http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() body, err := ioutil.ReadAll(r.Body) if err != nil { http.Error(w, err.Error(), 500) return } resp := fmt.Sprintf("Hi %s!", body) w.Write([]byte(resp)) }) server := &http.Server{} server.Serve(listener) }()

hsanjuan commented 3 years ago

See line above. server is an http.Server.

askquestions commented 3 years ago

I am asking for the definition of "Serve." I could not find its definition. Please help me. Thanks.

hsanjuan commented 3 years ago

I am asking for the definition of "Serve." I could not find its definition. Please help me. Thanks.

https://golang.org/pkg/net/http/#Server.Serve

askquestions commented 3 years ago

Thank you for the response.

I would like to follow up the discussion on making use of go-libp2p-http to construct "zero client" as mentioned in this link: https://medium.com/swlh/the-client-server-peer-to-peer-blockchain-application-78cc893cb54c The terms of "thin client" and "zero client" are mentioned in the section of "In the blockchain ecosystem, the trend is toward public gateways" of this post. To my understanding, "thin client" and "zero client" are the conventional "client" and "server", respectively, in the client/server model.

I am looking for a solution of client/server over P2P with a simplistic topology of: thin client <--> peer1 <--> peer2 <--> zero client. I could be able to make the portion "thin client <--> peer1 <--> peer2" to happen because there are examples of making a thin client to connect with a P2P network. However, I could not find a good example to make the portion "peer2 <--> zero client" to happen.

After I see the go-libp2p-http project, I am wondering that this project can be used to make "peer2 <--> zero client" to happen. I plan to make a "zero client" (non-P2P server) and peer2 to run in the same VM or computer node. The "zero client" listens at 127.0.0.1:server_port. Then, I need to make "HandleFunc" to write a REST API request to 127.0.0.1:server_port and to read response from 127.0.0.1:server_port. Since I am not quite familiar to go-libp2p programming, I am unsure whether it is possible to make a P2P peer to interact with 127.0.0.1:server_port.

I can see that a pair of conventional client and server can interact with each other over P2P network by using a commercial tool called remote.it (https://github.com/remoteit). That tool is an overkill to my use case. I am interested to finding a simpler solution.

Any suggestion or help? Thank you very much.

I would say that this project has the potential of being widely adopted in constructing blockchain applications over P2P network.

hsanjuan commented 3 years ago

Check IPFS http proxy feature: https://github.com/ipfs/go-ipfs/blob/master/docs/experimental-features.md#p2p-http-proxy, as it essentially uses this library and allows to launch listeners and proxies.

askquestions commented 3 years ago

I have tested your suggestion. Your suggestion almost worked with only one more issue.

So far, I could use "curl http://localhost:8080/p2p/$SERVER_ID/http/" as a client to send an http request to an http server. The client and server are connected over a path of 2 P2P peers. In the server log, I can see that the request has been fed into the server. $SERVER_ID is the id of the peer which bridges with the non-P2P http server. However, I still need to make an actual application client to interact with the http server. The problem is the way of converting an original URL into a new URL with the augmented string of "p2p/$SERVER_ID/http/". Could you please provide some more helps? Thanks.

askquestions commented 3 years ago

I just noted a nice explanation which can possibly solve my problem.

# On the 'remote' IPFS host
> ipfs id -f "<id>\n"
QmSiXjrYwLmDhRvAb3vK2TUP8W2pTDd34MhgCwpanVjdNT

# Configure the p2p listener on the remote IPFS instance:
> ipfs p2p listen /x/kickass/1.0 /ip4/127.0.0.1/tcp/5001

# On the 'local' IPFS host
# Configure the p2p forwarder on the local host:
> ipfs p2p forward /x/kickass/1.0 /ip4/127.0.0.1/tcp/5551 /ipfs/QmSiXjrYwLmDhRvAb3vK2TUP8W2pTDd34MhgCwpanVjdNT

# Voila - point your browser at http://localhost:5551/webui to inspect your remote

However, I want to confirm the followings. a) "/x/kickass/1.0" is a self-defined label of a service. b) a non-P2P server listens at port 5001 at the remote peer (QmSiXjrYwLmDhRvAb3vK2TUP8W2pTDd34MhgCwpanVjdNT). c) a non-P2P application client feeds http requests to its local peer at port 5551.

Are these bullets correctly specified? Thanks for confirmation or corrections.

hsanjuan commented 3 years ago

p2p listen configures a p2p->tcp forwarder (in your case from libp2p-streams tagged with /x/kickass/1.0 to localhost:5001, which is the daemon's IPFS API but could be any other thing you launch somewhere. "Listen" means that the peer listens to p2p streams.

p2p forward configures a tcp->p2p forwarder (actually opens a tcp listener on 5551 and sends any data to QmSiXjr... via libp2p stream tagged with `/x/kickass/1.0).

So yes, I think your assumptions are mostly correct.