@cryptotaxi247 / kubo / commits / f2c43d5bb

feat(config): Add gateway-over-libp2p experiment

Adin Schmahmann committed Aug 31, 2023 at 05:22 UTC f2c43d5bbfb4efec8e32573eff929feed472e734
5 files changed +64 -5
.github/workflows/gateway-conformance.yml
+1
@@ -60,6 +60,7 @@ jobs:
60 run: |
61 ./ipfs init --profile=test
62 ./ipfs config --json Gateway.PublicGateways "$GATEWAY_PUBLIC_GATEWAYS"
63 + ./ipfs config --json Experimental.GatewayOverLibp2p true
64 ./ipfs config Addresses.Gateway "/ip4/127.0.0.1/tcp/8080"
65 ./ipfs config Addresses.API "/ip4/127.0.0.1/tcp/5001"
66 working-directory: kubo-gateway/cmd/ipfs
cmd/ipfs/daemon.go
+15 -5
@@ -909,17 +909,27 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
909 const gatewayProtocolID protocol.ID = "/ipfs/gateway" // FIXME: specify https://github.com/ipfs/specs/issues/433
910
911 func serveTrustlessGatewayOverLibp2p(cctx *oldcmds.Context) (<-chan error, error) {
912 + node, err := cctx.ConstructNode()
913 + if err != nil {
914 + return nil, fmt.Errorf("serveHTTPGatewayOverLibp2p: ConstructNode() failed: %s", err)
915 + }
916 + cfg, err := node.Repo.Config()
917 + if err != nil {
918 + return nil, fmt.Errorf("could not read config: %w", err)
919 + }
920 +
921 + if !cfg.Experimental.GatewayOverLibp2p {
922 + errCh := make(chan error)
923 + close(errCh)
924 + return errCh, nil
925 + }
926 +
927 opts := []corehttp.ServeOption{
928 corehttp.MetricsCollectionOption("libp2p-gateway"),
929 corehttp.Libp2pGatewayOption(),
930 corehttp.VersionOption(),
931 }
932
918 - node, err := cctx.ConstructNode()
919 - if err != nil {
920 - return nil, fmt.Errorf("serveHTTPGateway: ConstructNode() failed: %s", err)
921 - }
922 -
933 handler, err := corehttp.MakeHandler(node, nil, opts...)
934 if err != nil {
935 return nil, err
config/experiments.go
+1
@@ -11,4 +11,5 @@ type Experiments struct {
11 AcceleratedDHTClient experimentalAcceleratedDHTClient `json:",omitempty"`
12 OptimisticProvide bool
13 OptimisticProvideJobsPoolSize int
14 + GatewayOverLibp2p bool `json:",omitempty"`
15 }
docs/experimental-features.md
+37
@@ -27,6 +27,7 @@ the above issue.
27 - [Graphsync](#graphsync)
28 - [Noise](#noise)
29 - [Optimistic Provide](#optimistic-provide)
30 +- [HTTP Gateway over Libp2p](#http-gateway-over-libp2p)
31
32 ---
33
@@ -617,3 +618,39 @@ ipfs config --json Experimental.OptimisticProvideJobsPoolSize 120
618
619 - [ ] Needs more people to use and report on how well it works
620 - [ ] Should prove at least equivalent availability of provider records as the classic approach
621 +
622 +## HTTP Gateway over Libp2p
623 +
624 +### In Version
625 +
626 +0.23.0
627 +
628 +### State
629 +
630 +Experimental, disabled by default.
631 +
632 +Enables serving the [IPFS HTTP Gateway](https://specs.ipfs.tech/http-gateways/) protocol over libp2p transports and
633 +as described in the [specification](https://github.com/ipfs/specs/pull/434).
634 +
635 +Notes:
636 +- This feature currently is only about serving the gateway requests over libp2p, not about fetching data this way using
637 +[Trustless Gateway Specification](https://specs.ipfs.tech/http-gateways/trustless-gateway/).
638 +- While kubo currently mounts the gateway API at the root (i.e. `/`) of the libp2p `/http/1.1` protocol that is subject to
639 +change. The way to reliably discover where a given HTTP protocol is mounted on a libp2p endpoint is via the `.well-known/libp2p`
640 +resource specified in the [http+libp2p specification](https://github.com/libp2p/specs/pull/508)
641 +- Kubo currently hard codes the gateway-over-libp2p behavior to:
642 + - Only operate on `/ipfs` resources
643 + - Only satisfy the Trustless Gateway API
644 + - Only serve data that is already local to the node (i.e. similar to a `NoFetch` gateway)
645 +
646 +### How to enable
647 +
648 +Modify your ipfs config:
649 +
650 +```
651 +ipfs config --json Experimental.GatewayOverLibp2p true
652 +```
653 +
654 +### Road to being a real feature
655 +
656 +- [ ] Needs more people to use and report on how well it works
\ No newline at end of file
test/cli/http_gateway_over_libp2p_test.go
+10
@@ -57,6 +57,16 @@ func TestGatewayOverLibp2p(t *testing.T) {
57 p2pProxyNodeHTTPListenAddr, err := manet.ToNetAddr(p2pProxyNodeHTTPListenMA)
58 require.NoError(t, err)
59
60 + t.Run("DoesNotWorkWithoutExperimentalConfig", func(t *testing.T) {
61 + _, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s?format=raw", p2pProxyNodeHTTPListenAddr, cidDataOnGatewayNode))
62 + require.Error(t, err)
63 + })
64 +
65 + // Enable the experimental feature and reconnect the nodes
66 + gwNode.IPFS("config", "--json", "Experimental.GatewayOverLibp2p", "true")
67 + gwNode.StopDaemon().StartDaemon()
68 + nodes.Connect()
69 +
70 // Note: the bare HTTP requests here assume that the gateway is mounted at `/`
71 t.Run("WillNotServeRemoteContent", func(t *testing.T) {
72 resp, err := http.Get(fmt.Sprintf("http://%s/ipfs/%s?format=raw", p2pProxyNodeHTTPListenAddr, cidDataNotOnGatewayNode))