diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go
index 12b3f4d9cccc..b96a10ad66e6 100644
--- a/cmd/ipfs/daemon.go
+++ b/cmd/ipfs/daemon.go
@@ -66,7 +66,6 @@ const (
routingOptionAutoKwd = "auto"
unencryptTransportKwd = "disable-transport-encryption"
unrestrictedAPIAccessKwd = "unrestricted-api"
- writableKwd = "writable"
enablePubSubKwd = "enable-pubsub-experiment"
enableIPNSPubSubKwd = "enable-namesys-pubsub"
enableMultiplexKwd = "enable-mplex-experiment"
@@ -162,7 +161,6 @@ Headers.
cmds.StringOption(initProfileOptionKwd, "Configuration profiles to apply for --init. See ipfs init --help for more"),
cmds.StringOption(routingOptionKwd, "Overrides the routing option").WithDefault(routingOptionDefaultKwd),
cmds.BoolOption(mountKwd, "Mounts IPFS to the filesystem using FUSE (experimental)"),
- cmds.BoolOption(writableKwd, "Enable writing objects (with POST, PUT and DELETE)"),
cmds.StringOption(ipfsMountKwd, "Path to the mountpoint for IPFS (if using --mount). Defaults to config setting."),
cmds.StringOption(ipnsMountKwd, "Path to the mountpoint for IPNS (if using --mount). Defaults to config setting."),
cmds.BoolOption(unrestrictedAPIAccessKwd, "Allow API access to unlisted hashes"),
@@ -683,9 +681,9 @@ func serveHTTPApi(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, error
// only the webui objects are allowed.
// if you know what you're doing, go ahead and pass --unrestricted-api.
unrestricted, _ := req.Options[unrestrictedAPIAccessKwd].(bool)
- gatewayOpt := corehttp.GatewayOption(false, corehttp.WebUIPaths...)
+ gatewayOpt := corehttp.GatewayOption(corehttp.WebUIPaths...)
if unrestricted {
- gatewayOpt = corehttp.GatewayOption(true, "/ipfs", "/ipns")
+ gatewayOpt = corehttp.GatewayOption("/ipfs", "/ipns")
}
var opts = []corehttp.ServeOption{
@@ -789,9 +787,8 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
return nil, fmt.Errorf("serveHTTPGateway: GetConfig() failed: %s", err)
}
- writable, writableOptionFound := req.Options[writableKwd].(bool)
- if !writableOptionFound {
- writable = cfg.Gateway.Writable
+ if cfg.Gateway.Writable {
+ return nil, fmt.Errorf("serveHTTPGateway: writable gateways are no longer supported, please remove .Gateway.Writable from your configuration file")
}
listeners, err := sockets.TakeListeners("io.ipfs.gateway")
@@ -824,13 +821,9 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
}
// we might have listened to /tcp/0 - let's see what we are listing on
- gwType := "readonly"
- if writable {
- gwType = "writable"
- }
for _, listener := range listeners {
- fmt.Printf("Gateway (%s) server listening on %s\n", gwType, listener.Multiaddr())
+ fmt.Printf("Gateway (readonly) server listening on %s\n", listener.Multiaddr())
}
cmdctx := *cctx
@@ -839,7 +832,7 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
var opts = []corehttp.ServeOption{
corehttp.MetricsCollectionOption("gateway"),
corehttp.HostnameOption(),
- corehttp.GatewayOption(writable, "/ipfs", "/ipns"),
+ corehttp.GatewayOption("/ipfs", "/ipns"),
corehttp.VersionOption(),
corehttp.CheckVersionOption(),
corehttp.CommandsROOption(cmdctx),
diff --git a/cmd/ipfswatch/main.go b/cmd/ipfswatch/main.go
index 06215687c05f..2c333fc2336a 100644
--- a/cmd/ipfswatch/main.go
+++ b/cmd/ipfswatch/main.go
@@ -94,7 +94,7 @@ func run(ipfsPath, watchPath string) error {
if *http {
addr := "/ip4/127.0.0.1/tcp/5001"
var opts = []corehttp.ServeOption{
- corehttp.GatewayOption(true, "/ipfs", "/ipns"),
+ corehttp.GatewayOption("/ipfs", "/ipns"),
corehttp.WebUIOption,
corehttp.CommandsOption(cmdCtx(node, ipfsPath)),
}
diff --git a/config/gateway.go b/config/gateway.go
index ad01b263b366..0e76bffdc018 100644
--- a/config/gateway.go
+++ b/config/gateway.go
@@ -38,8 +38,8 @@ type Gateway struct {
// should be redirected.
RootRedirect string
- // Writable enables PUT/POST request handling by this gateway. Usually,
- // writing is done through the API, not the gateway.
+ // REMOVED: Writable enables PUT/POST request handling by this gateway.
+ // Usually, writing is done through the API, not the gateway.
Writable bool
// PathPrefixes was removed: https://github.com/ipfs/go-ipfs/issues/7702
diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go
index d5eccf73c275..5f260978d672 100644
--- a/core/corehttp/gateway.go
+++ b/core/corehttp/gateway.go
@@ -1,12 +1,19 @@
package corehttp
import (
+ "context"
"fmt"
+ "io"
"net"
"net/http"
+ cid "github.com/ipfs/go-cid"
+ ipld "github.com/ipfs/go-ipld-format"
+ "github.com/ipfs/go-libipfs/files"
"github.com/ipfs/go-libipfs/gateway"
+ iface "github.com/ipfs/interface-go-ipfs-core"
options "github.com/ipfs/interface-go-ipfs-core/options"
+ "github.com/ipfs/interface-go-ipfs-core/path"
version "github.com/ipfs/kubo"
core "github.com/ipfs/kubo/core"
coreapi "github.com/ipfs/kubo/core/coreapi"
@@ -14,14 +21,14 @@ import (
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
)
-func GatewayOption(writable bool, paths ...string) ServeOption {
+func GatewayOption(paths ...string) ServeOption {
return func(n *core.IpfsNode, _ net.Listener, mux *http.ServeMux) (*http.ServeMux, error) {
cfg, err := n.Repo.Config()
if err != nil {
return nil, err
}
- api, err := coreapi.NewCoreAPI(n, options.Api.FetchBlocks(!cfg.Gateway.NoFetch))
+ nodeAPI, err := coreapi.NewCoreAPI(n, options.Api.FetchBlocks(!cfg.Gateway.NoFetch))
if err != nil {
return nil, err
}
@@ -33,16 +40,21 @@ func GatewayOption(writable bool, paths ...string) ServeOption {
gateway.AddAccessControlHeaders(headers)
- offlineAPI, err := api.WithOptions(options.Api.Offline(true))
+ offlineNodeAPI, err := nodeAPI.WithOptions(options.Api.Offline(true))
if err != nil {
return nil, err
}
- gateway := gateway.NewHandler(gateway.Config{
- Headers: headers,
- Writable: writable,
- }, api, offlineAPI)
+ gatewayCfg := gateway.Config{
+ Headers: headers,
+ }
+
+ gwAPI := &gatewayAPI{
+ node: nodeAPI,
+ offlineNode: offlineNodeAPI,
+ }
+ gateway := gateway.NewHandler(gatewayCfg, gwAPI)
gateway = otelhttp.NewHandler(gateway, "Gateway.Request")
for _, p := range paths {
@@ -62,3 +74,36 @@ func VersionOption() ServeOption {
return mux, nil
}
}
+
+type gatewayAPI struct {
+ node iface.CoreAPI
+ offlineNode iface.CoreAPI
+}
+
+func (gw *gatewayAPI) GetUnixFs(ctx context.Context, pth path.Path) (files.Node, error) {
+ return gw.node.Unixfs().Get(ctx, pth)
+}
+
+func (gw *gatewayAPI) LsUnixFs(ctx context.Context, pth path.Path, opts ...options.UnixfsLsOption) (<-chan iface.DirEntry, error) {
+ return gw.node.Unixfs().Ls(ctx, pth, opts...)
+}
+
+func (gw *gatewayAPI) GetBlock(ctx context.Context, pth path.Path) (io.Reader, error) {
+ return gw.node.Block().Get(ctx, pth)
+}
+
+func (gw *gatewayAPI) StatBlockOffline(ctx context.Context, pth path.Path) (iface.BlockStat, error) {
+ return gw.offlineNode.Block().Stat(ctx, pth)
+}
+
+func (gw *gatewayAPI) GetNode(ctx context.Context, cid cid.Cid) (ipld.Node, error) {
+ return gw.node.Dag().Get(ctx, cid)
+}
+
+func (gw *gatewayAPI) GetRouting(ctx context.Context, k string) ([]byte, error) {
+ return gw.node.Routing().Get(ctx, k)
+}
+
+func (gw *gatewayAPI) ResolvePath(ctx context.Context, pth path.Path) (path.Resolved, error) {
+ return gw.node.ResolvePath(ctx, pth)
+}
diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go
index 49fa519fb3d6..94eda2d778e4 100644
--- a/core/corehttp/gateway_test.go
+++ b/core/corehttp/gateway_test.go
@@ -130,7 +130,7 @@ func newTestServerAndNode(t *testing.T, ns mockNamesys) (*httptest.Server, iface
dh.Handler, err = makeHandler(n,
ts.Listener,
HostnameOption(),
- GatewayOption(false, "/ipfs", "/ipns"),
+ GatewayOption("/ipfs", "/ipns"),
VersionOption(),
)
if err != nil {
diff --git a/docs/config.md b/docs/config.md
index 995872c4f37f..98ca81b81506 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -682,11 +682,7 @@ Type: `string` (url)
### `Gateway.Writable`
-A boolean to configure whether the gateway is writeable or not.
-
-Default: `false`
-
-Type: `bool`
+**REMOVED**: Kubo no longer provides a Writable Gateway.
### `Gateway.PathPrefixes`
diff --git a/docs/examples/kubo-as-a-library/go.mod b/docs/examples/kubo-as-a-library/go.mod
index a74bfbf3e03d..8e4006156289 100644
--- a/docs/examples/kubo-as-a-library/go.mod
+++ b/docs/examples/kubo-as-a-library/go.mod
@@ -7,7 +7,7 @@ go 1.18
replace github.com/ipfs/kubo => ./../../..
require (
- github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496
+ github.com/ipfs/go-libipfs v0.4.1-0.20230131164115-b4a01af26d08
github.com/ipfs/interface-go-ipfs-core v0.10.0
github.com/ipfs/kubo v0.0.0-00010101000000-000000000000
github.com/libp2p/go-libp2p v0.24.2
diff --git a/docs/examples/kubo-as-a-library/go.sum b/docs/examples/kubo-as-a-library/go.sum
index eb37654f786e..bd1699b7b3aa 100644
--- a/docs/examples/kubo-as-a-library/go.sum
+++ b/docs/examples/kubo-as-a-library/go.sum
@@ -548,8 +548,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2
github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg=
github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A=
github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24=
-github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496 h1:RVI31GQCFODREpasIFyVFkS6PjJT2bMwr/Bgr9Ryql4=
-github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496/go.mod h1:AAPvZADZ80i+QhGCWNWCsx8IGY0t9C+IBEngLeYtySY=
+github.com/ipfs/go-libipfs v0.4.1-0.20230131164115-b4a01af26d08 h1:nOCkGmyfl4m77P+lWR83d3jsFS0ek+kYxmUuONGMEe8=
+github.com/ipfs/go-libipfs v0.4.1-0.20230131164115-b4a01af26d08/go.mod h1:P6YEhRwAljcifKAGL01RobOTfSfyFacr0F8wiJNz2uE=
github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM=
github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk=
github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A=
diff --git a/go.mod b/go.mod
index 5edf9f68a467..e0d1266393f9 100644
--- a/go.mod
+++ b/go.mod
@@ -45,7 +45,7 @@ require (
github.com/ipfs/go-ipld-git v0.1.1
github.com/ipfs/go-ipld-legacy v0.1.1
github.com/ipfs/go-ipns v0.3.0
- github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496
+ github.com/ipfs/go-libipfs v0.4.1-0.20230131164115-b4a01af26d08
github.com/ipfs/go-log v1.0.5
github.com/ipfs/go-log/v2 v2.5.1
github.com/ipfs/go-merkledag v0.9.0
diff --git a/go.sum b/go.sum
index fefe9bf71606..03d8bf754688 100644
--- a/go.sum
+++ b/go.sum
@@ -570,8 +570,8 @@ github.com/ipfs/go-ipld-legacy v0.1.1 h1:BvD8PEuqwBHLTKqlGFTHSwrwFOMkVESEvwIYwR2
github.com/ipfs/go-ipld-legacy v0.1.1/go.mod h1:8AyKFCjgRPsQFf15ZQgDB8Din4DML/fOmKZkkFkrIEg=
github.com/ipfs/go-ipns v0.3.0 h1:ai791nTgVo+zTuq2bLvEGmWP1M0A6kGTXUsgv/Yq67A=
github.com/ipfs/go-ipns v0.3.0/go.mod h1:3cLT2rbvgPZGkHJoPO1YMJeh6LtkxopCkKFcio/wE24=
-github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496 h1:RVI31GQCFODREpasIFyVFkS6PjJT2bMwr/Bgr9Ryql4=
-github.com/ipfs/go-libipfs v0.4.1-0.20230130233950-a005a5006496/go.mod h1:AAPvZADZ80i+QhGCWNWCsx8IGY0t9C+IBEngLeYtySY=
+github.com/ipfs/go-libipfs v0.4.1-0.20230131164115-b4a01af26d08 h1:nOCkGmyfl4m77P+lWR83d3jsFS0ek+kYxmUuONGMEe8=
+github.com/ipfs/go-libipfs v0.4.1-0.20230131164115-b4a01af26d08/go.mod h1:P6YEhRwAljcifKAGL01RobOTfSfyFacr0F8wiJNz2uE=
github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM=
github.com/ipfs/go-log v1.0.2/go.mod h1:1MNjMxe0u6xvJZgeqbJ8vdo2TKaGwZ1a0Bpza+sr2Sk=
github.com/ipfs/go-log v1.0.3/go.mod h1:OsLySYkwIbiSUR/yBTdv1qPtcE4FW3WPWk/ewz9Ru+A=
diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh
index 3aecaec994b7..8b57fb1a1bdc 100644
--- a/test/sharness/lib/test-lib.sh
+++ b/test/sharness/lib/test-lib.sh
@@ -214,13 +214,6 @@ test_init_ipfs() {
}
-test_config_ipfs_gateway_writable() {
- test_expect_success "prepare config -- gateway writable" '
- test_config_set --bool Gateway.Writable true ||
- test_fsh cat "\"$IPFS_PATH/config\""
- '
-}
-
test_wait_for_file() {
loops=$1
delay=$2
diff --git a/test/sharness/t0111-gateway-writeable.sh b/test/sharness/t0111-gateway-writeable.sh
deleted file mode 100755
index 53d4fc1aa408..000000000000
--- a/test/sharness/t0111-gateway-writeable.sh
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/env bash
-#
-# Copyright (c) 2014 Christian Couder
-# MIT Licensed; see the LICENSE file in this repository.
-#
-
-test_description="Test HTTP Gateway (Writable)"
-
-. lib/test-lib.sh
-
-test_init_ipfs
-
-test_launch_ipfs_daemon --writable
-test_expect_success "ipfs daemon --writable overrides config" '
- curl -v -X POST http://$GWAY_ADDR/ipfs/ 2> outfile &&
- grep "HTTP/1.1 201 Created" outfile &&
- grep "Location: /ipfs/QmbFMke1KXqnYyBBWxB74N4c5SBnJMVAiMNRcGu6x1AwQH" outfile
-'
-test_kill_ipfs_daemon
-
-test_config_ipfs_gateway_writable
-test_launch_ipfs_daemon --writable=false
-test_expect_success "ipfs daemon --writable=false overrides Writable=true config" '
- curl -v -X POST http://$GWAY_ADDR/ipfs/ 2> outfile &&
- grep "HTTP/1.1 405 Method Not Allowed" outfile
-'
-test_kill_ipfs_daemon
-test_launch_ipfs_daemon
-
-port=$GWAY_PORT
-
-test_expect_success "ipfs daemon up" '
- pollEndpoint -host $GWAY_MADDR -v -tout=1s -tries=60 2>poll_apierr > poll_apiout ||
- test_fsh cat poll_apierr || test_fsh cat poll_apiout
-'
-
-test_expect_success "HTTP gateway gives access to sample file" '
- curl -s -o welcome "http://$GWAY_ADDR/ipfs/$HASH_WELCOME_DOCS/readme" &&
- grep "Hello and Welcome to IPFS!" welcome
-'
-
-test_expect_success "HTTP POST file gives Hash" '
- echo "$RANDOM" >infile &&
- URL="http://127.0.0.1:$port/ipfs/" &&
- curl -svX POST --data-binary @infile "$URL" 2>curl_post.out &&
- grep "HTTP/1.1 201 Created" curl_post.out &&
- LOCATION=$(grep Location curl_post.out) &&
- HASH=$(echo $LOCATION | cut -d":" -f2- |tr -d " \n\r")
-'
-
-test_expect_success "We can HTTP GET file just created" '
- URL="http://127.0.0.1:${port}${HASH}" &&
- curl -so outfile "$URL" &&
- test_cmp infile outfile
-'
-
-test_expect_success "We got the correct hash" '
- ADD_HASH="/ipfs/$(ipfs add -q infile)" &&
- test "x$ADD_HASH" = "x$HASH" || test_fsh echo "$ADD_HASH != $HASH"
-'
-
-test_expect_success "HTTP GET empty directory" '
- URL="http://127.0.0.1:$port/ipfs/$HASH_EMPTY_DIR/" &&
- echo "GET $URL" &&
- curl -so outfile "$URL" 2>curl_getEmpty.out &&
- cat outfile | tr -s "\n" " " | grep "Index of /ipfs/$HASH_EMPTY_DIR"
-'
-
-test_expect_success "HTTP PUT file to construct a hierarchy" '
- echo "$RANDOM" >infile &&
- URL="http://127.0.0.1:$port/ipfs/$HASH_EMPTY_DIR/test.txt" &&
- echo "PUT $URL" &&
- curl -svX PUT --data-binary @infile "$URL" 2>curl_put.out &&
- grep "HTTP/1.1 201 Created" curl_put.out &&
- LOCATION=$(grep Location curl_put.out) &&
- HASH=$(expr "$LOCATION" : "< Location: /ipfs/\(.*\)/test.txt")
-'
-
-test_expect_success "We can HTTP GET file just created" '
- URL="http://127.0.0.1:$port/ipfs/$HASH/test.txt" &&
- echo "GET $URL" &&
- curl -so outfile "$URL" &&
- test_cmp infile outfile
-'
-
-test_expect_success "HTTP PUT file to append to existing hierarchy" '
- echo "$RANDOM" >infile2 &&
- URL="http://127.0.0.1:$port/ipfs/$HASH/test/test.txt" &&
- echo "PUT $URL" &&
- curl -svX PUT --data-binary @infile2 "$URL" 2>curl_putAgain.out &&
- grep "HTTP/1.1 201 Created" curl_putAgain.out &&
- LOCATION=$(grep Location curl_putAgain.out) &&
- HASH=$(expr "$LOCATION" : "< Location: /ipfs/\(.*\)/test/test.txt")
-'
-
-
-test_expect_success "We can HTTP GET file just updated" '
- URL="http://127.0.0.1:$port/ipfs/$HASH/test/test.txt" &&
- echo "GET $URL" &&
- curl -svo outfile2 "$URL" 2>curl_getAgain.out &&
- test_cmp infile2 outfile2
-'
-
-test_expect_success "HTTP PUT to replace a directory" '
- echo "$RANDOM" >infile3 &&
- URL="http://127.0.0.1:$port/ipfs/$HASH/test" &&
- echo "PUT $URL" &&
- curl -svX PUT --data-binary @infile3 "$URL" 2>curl_putOverDirectory.out &&
- grep "HTTP/1.1 201 Created" curl_putOverDirectory.out &&
- LOCATION=$(grep Location curl_putOverDirectory.out) &&
- HASH=$(expr "$LOCATION" : "< Location: /ipfs/\(.*\)/test")
-'
-
-test_expect_success "We can HTTP GET file just put over a directory" '
- URL="http://127.0.0.1:$port/ipfs/$HASH/test" &&
- echo "GET $URL" &&
- curl -svo outfile3 "$URL" 2>curl_getOverDirectory.out &&
- test_cmp infile3 outfile3
-'
-
-test_expect_success "HTTP PUT to /ipns fails" '
- PEERID=`ipfs id --format=""` &&
- URL="http://127.0.0.1:$port/ipns/$PEERID/test.txt" &&
- echo "PUT $URL" &&
- curl -svX PUT --data-binary @infile1 "$URL" 2>curl_putIpns.out &&
- grep "HTTP/1.1 400 Bad Request" curl_putIpns.out
-'
-
-
-test_kill_ipfs_daemon
-
-test_done