mirror of
https://source.quilibrium.com/quilibrium/ceremonyclient.git
synced 2024-11-14 12:15:18 +00:00
360 lines
9.0 KiB
Go
360 lines
9.0 KiB
Go
|
package libp2phttp_test
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"log"
|
||
|
"net"
|
||
|
"net/http"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/libp2p/go-libp2p"
|
||
|
"github.com/libp2p/go-libp2p/core/peer"
|
||
|
libp2phttp "github.com/libp2p/go-libp2p/p2p/http"
|
||
|
ma "github.com/multiformats/go-multiaddr"
|
||
|
)
|
||
|
|
||
|
func ExampleHost_withAStockGoHTTPClient() {
|
||
|
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")},
|
||
|
}
|
||
|
|
||
|
// A server with a simple echo protocol
|
||
|
server.SetHTTPHandler("/echo/1.0.0", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
w.Header().Add("Content-Type", "application/octet-stream")
|
||
|
io.Copy(w, r.Body)
|
||
|
}))
|
||
|
go server.Serve()
|
||
|
defer server.Close()
|
||
|
|
||
|
var serverHTTPPort string
|
||
|
var err error
|
||
|
for _, a := range server.Addrs() {
|
||
|
serverHTTPPort, err = a.ValueForProtocol(ma.P_TCP)
|
||
|
if err == nil {
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// Make an HTTP request using the Go standard library.
|
||
|
resp, err := http.Post("http://127.0.0.1:"+serverHTTPPort+"/echo/1.0.0/", "application/octet-stream", strings.NewReader("Hello HTTP"))
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
|
||
|
body, err := io.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
fmt.Println(string(body))
|
||
|
|
||
|
// Output: Hello HTTP
|
||
|
}
|
||
|
|
||
|
func ExampleHost_listenOnHTTPTransportAndStreams() {
|
||
|
serverStreamHost, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/127.0.0.1/udp/0/quic-v1"))
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
defer serverStreamHost.Close()
|
||
|
|
||
|
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")},
|
||
|
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
|
||
|
}
|
||
|
|
||
|
func ExampleHost_overLibp2pStreams() {
|
||
|
serverStreamHost, err := libp2p.New(libp2p.ListenAddrStrings("/ip4/127.0.0.1/udp/0/quic-v1"))
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
server := libp2phttp.Host{
|
||
|
StreamHost: serverStreamHost,
|
||
|
}
|
||
|
|
||
|
// A server with a simple echo protocol
|
||
|
server.SetHTTPHandler("/echo/1.0.0", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
w.Header().Add("Content-Type", "application/octet-stream")
|
||
|
io.Copy(w, r.Body)
|
||
|
}))
|
||
|
go server.Serve()
|
||
|
defer server.Close()
|
||
|
|
||
|
clientStreamHost, err := libp2p.New(libp2p.NoListenAddrs)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
client := libp2phttp.Host{StreamHost: clientStreamHost}
|
||
|
|
||
|
// Make an HTTP request using the Go standard library, but over libp2p
|
||
|
// streams. If the server were listening on an HTTP transport, this could
|
||
|
// also make the request over the HTTP transport.
|
||
|
httpClient, err := client.NamespacedClient("/echo/1.0.0", peer.AddrInfo{ID: server.PeerID(), Addrs: server.Addrs()})
|
||
|
|
||
|
// Only need to Post to "/" because this client is namespaced to the "/echo/1.0.0" protocol.
|
||
|
resp, err := httpClient.Post("/", "application/octet-stream", strings.NewReader("Hello HTTP"))
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
|
||
|
body, err := io.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
fmt.Println(string(body))
|
||
|
|
||
|
// Output: Hello HTTP
|
||
|
}
|
||
|
|
||
|
func ExampleHost_Serve() {
|
||
|
server := libp2phttp.Host{
|
||
|
InsecureAllowHTTP: true, // For our example, we'll allow insecure HTTP
|
||
|
ListenAddrs: []ma.Multiaddr{ma.StringCast("/ip4/127.0.0.1/tcp/50221/http")},
|
||
|
}
|
||
|
|
||
|
go server.Serve()
|
||
|
defer server.Close()
|
||
|
|
||
|
fmt.Println(server.Addrs())
|
||
|
|
||
|
// Output: [/ip4/127.0.0.1/tcp/50221/http]
|
||
|
}
|
||
|
|
||
|
func ExampleHost_SetHTTPHandler() {
|
||
|
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")},
|
||
|
}
|
||
|
|
||
|
server.SetHTTPHandler("/hello/1", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
w.Header().Add("Content-Type", "text/plain")
|
||
|
w.Write([]byte("Hello World"))
|
||
|
}))
|
||
|
|
||
|
go server.Serve()
|
||
|
defer server.Close()
|
||
|
|
||
|
port, err := server.Addrs()[0].ValueForProtocol(ma.P_TCP)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
resp, err := http.Get("http://127.0.0.1:" + port + "/hello/1/")
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
respBody, err := io.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
fmt.Println(string(respBody))
|
||
|
|
||
|
// Output: Hello World
|
||
|
}
|
||
|
|
||
|
func ExampleHost_SetHTTPHandlerAtPath() {
|
||
|
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")},
|
||
|
}
|
||
|
|
||
|
server.SetHTTPHandlerAtPath("/hello/1", "/other-place/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
w.Header().Add("Content-Type", "text/plain")
|
||
|
w.Write([]byte("Hello World"))
|
||
|
}))
|
||
|
|
||
|
go server.Serve()
|
||
|
defer server.Close()
|
||
|
|
||
|
port, err := server.Addrs()[0].ValueForProtocol(ma.P_TCP)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
resp, err := http.Get("http://127.0.0.1:" + port + "/other-place/")
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
respBody, err := io.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
fmt.Println(string(respBody))
|
||
|
|
||
|
// Output: Hello World
|
||
|
}
|
||
|
|
||
|
func ExampleHost_NamespacedClient() {
|
||
|
var client libp2phttp.Host
|
||
|
|
||
|
// Create the server
|
||
|
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")},
|
||
|
}
|
||
|
|
||
|
server.SetHTTPHandlerAtPath("/hello/1", "/other-place/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
w.Header().Add("Content-Type", "text/plain")
|
||
|
w.Write([]byte("Hello World"))
|
||
|
}))
|
||
|
|
||
|
go server.Serve()
|
||
|
defer server.Close()
|
||
|
|
||
|
// Create an http.Client that is namespaced to this protocol.
|
||
|
httpClient, err := client.NamespacedClient("/hello/1", peer.AddrInfo{ID: server.PeerID(), Addrs: server.Addrs()})
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
resp, err := httpClient.Get("/")
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
respBody, err := io.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
fmt.Println(string(respBody))
|
||
|
|
||
|
// Output: Hello World
|
||
|
}
|
||
|
|
||
|
func ExampleHost_NamespaceRoundTripper() {
|
||
|
var client libp2phttp.Host
|
||
|
|
||
|
// Create the server
|
||
|
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")},
|
||
|
}
|
||
|
|
||
|
server.SetHTTPHandler("/hello/1", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
w.Header().Add("Content-Type", "text/plain")
|
||
|
w.Write([]byte("Hello World"))
|
||
|
}))
|
||
|
|
||
|
go server.Serve()
|
||
|
defer server.Close()
|
||
|
|
||
|
// Create an http.Roundtripper for the server
|
||
|
rt, err := client.NewConstrainedRoundTripper(peer.AddrInfo{ID: server.PeerID(), Addrs: server.Addrs()})
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// Namespace this roundtripper to a specific protocol
|
||
|
rt, err = client.NamespaceRoundTripper(rt, "/hello/1", server.PeerID())
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
resp, err := (&http.Client{Transport: rt}).Get("/")
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
respBody, err := io.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
fmt.Println(string(respBody))
|
||
|
|
||
|
// Output: Hello World
|
||
|
}
|
||
|
|
||
|
func ExampleHost_NewConstrainedRoundTripper() {
|
||
|
var client libp2phttp.Host
|
||
|
|
||
|
// Create the server
|
||
|
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")},
|
||
|
}
|
||
|
|
||
|
server.SetHTTPHandler("/hello/1", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
w.Header().Add("Content-Type", "text/plain")
|
||
|
w.Write([]byte("Hello World"))
|
||
|
}))
|
||
|
|
||
|
go server.Serve()
|
||
|
defer server.Close()
|
||
|
|
||
|
// Create an http.Roundtripper for the server
|
||
|
rt, err := client.NewConstrainedRoundTripper(peer.AddrInfo{ID: server.PeerID(), Addrs: server.Addrs()})
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
resp, err := (&http.Client{Transport: rt}).Get("/hello/1")
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
respBody, err := io.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
fmt.Println(string(respBody))
|
||
|
|
||
|
// Output: Hello World
|
||
|
}
|
||
|
|
||
|
func ExampleWellKnownHandler() {
|
||
|
var h libp2phttp.WellKnownHandler
|
||
|
h.AddProtocolMeta("/hello/1", libp2phttp.ProtocolMeta{
|
||
|
Path: "/hello-path/",
|
||
|
})
|
||
|
|
||
|
listener, err := net.Listen("tcp", "127.0.0.1:0")
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
defer listener.Close()
|
||
|
// 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 resource
|
||
|
resp, err := http.Get("http://" + listener.Addr().String() + libp2phttp.WellKnownProtocols)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
defer resp.Body.Close()
|
||
|
respBody, err := io.ReadAll(resp.Body)
|
||
|
if err != nil {
|
||
|
log.Fatal(err)
|
||
|
}
|
||
|
|
||
|
fmt.Println(string(respBody))
|
||
|
// Output: {"/hello/1":{"path":"/hello-path/"}}
|
||
|
|
||
|
}
|