diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go
index 52addcc072c..7f1c3d44e46 100644
--- a/cmd/ipfs/daemon.go
+++ b/cmd/ipfs/daemon.go
@@ -67,7 +67,6 @@ const (
routingOptionAutoClientKwd = "autoclient"
unencryptTransportKwd = "disable-transport-encryption"
unrestrictedAPIAccessKwd = "unrestricted-api"
- writableKwd = "writable"
enablePubSubKwd = "enable-pubsub-experiment"
enableIPNSPubSubKwd = "enable-namesys-pubsub"
enableMultiplexKwd = "enable-mplex-experiment"
@@ -163,7 +162,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 legacy Gateway.Writable (deprecated)"),
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"),
@@ -692,9 +690,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{
@@ -798,15 +796,6 @@ 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.WithDefault(false)
- }
-
- if writable {
- log.Error("serveHTTPGateway: legacy Gateway.Writable is DEPRECATED and will be removed or changed in future versions. If you are still using this, provide feedback in https://github.com/ipfs/specs/issues/375")
- }
-
listeners, err := sockets.TakeListeners("io.ipfs.gateway")
if err != nil {
return nil, fmt.Errorf("serveHTTPGateway: socket activation failed: %s", err)
@@ -837,13 +826,8 @@ 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
@@ -852,7 +836,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 06215687c05..2c333fc2336 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 de43dd39e11..5fce4be6724 100644
--- a/config/gateway.go
+++ b/config/gateway.go
@@ -38,10 +38,6 @@ type Gateway struct {
// should be redirected.
RootRedirect string
- // DEPRECATED: Enables legacy PUT/POST request handling.
- // Modern replacement tracked in https://github.com/ipfs/specs/issues/375
- Writable Flag `json:",omitempty"`
-
// PathPrefixes was removed: https://github.com/ipfs/go-ipfs/issues/7702
PathPrefixes []string
diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go
index c20ab6e4a4f..f77e941d9ee 100644
--- a/core/corehttp/gateway.go
+++ b/core/corehttp/gateway.go
@@ -24,18 +24,13 @@ 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))
- if err != nil {
- return nil, err
- }
-
headers := make(map[string][]string, len(cfg.Gateway.HTTPHeaders))
for h, v := range cfg.Gateway.HTTPHeaders {
headers[http.CanonicalHeaderKey(h)] = v
@@ -58,28 +53,6 @@ func GatewayOption(writable bool, paths ...string) ServeOption {
// By default, our HTTP handler is the gateway handler.
handler := gw.ServeHTTP
- // If we have the writable gateway enabled, we have to replace our
- // http handler by a handler that takes care of the different methods.
- if writable {
- writableGw := &writableGatewayHandler{
- config: &gwConfig,
- api: api,
- }
-
- handler = func(w http.ResponseWriter, r *http.Request) {
- switch r.Method {
- case http.MethodPost:
- writableGw.postHandler(w, r)
- case http.MethodDelete:
- writableGw.deleteHandler(w, r)
- case http.MethodPut:
- writableGw.putHandler(w, r)
- default:
- gw.ServeHTTP(w, r)
- }
- }
- }
-
for _, p := range paths {
mux.HandleFunc(p+"/", handler)
}
diff --git a/core/corehttp/gateway_test.go b/core/corehttp/gateway_test.go
index d4e357740bd..03b04350dbd 100644
--- a/core/corehttp/gateway_test.go
+++ b/core/corehttp/gateway_test.go
@@ -124,7 +124,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/core/corehttp/gateway_writable.go b/core/corehttp/gateway_writable.go
deleted file mode 100644
index 34cd8438ea7..00000000000
--- a/core/corehttp/gateway_writable.go
+++ /dev/null
@@ -1,265 +0,0 @@
-package corehttp
-
-import (
- "context"
- "fmt"
- "net/http"
- "os"
- gopath "path"
-
- 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"
- dag "github.com/ipfs/go-merkledag"
- "github.com/ipfs/go-mfs"
- path "github.com/ipfs/go-path"
- "github.com/ipfs/go-path/resolver"
- iface "github.com/ipfs/interface-go-ipfs-core"
- routing "github.com/libp2p/go-libp2p/core/routing"
-)
-
-const (
- ipfsPathPrefix = "/ipfs/"
-)
-
-type writableGatewayHandler struct {
- api iface.CoreAPI
- config *gateway.Config
-}
-
-func (i *writableGatewayHandler) addUserHeaders(w http.ResponseWriter) {
- for k, v := range i.config.Headers {
- w.Header()[http.CanonicalHeaderKey(k)] = v
- }
-}
-
-func (i *writableGatewayHandler) postHandler(w http.ResponseWriter, r *http.Request) {
- p, err := i.api.Unixfs().Add(r.Context(), files.NewReaderFile(r.Body))
- if err != nil {
- internalWebError(w, err)
- return
- }
-
- i.addUserHeaders(w) // ok, _now_ write user's headers.
- w.Header().Set("IPFS-Hash", p.Cid().String())
- log.Debugw("CID created, http redirect", "from", r.URL, "to", p, "status", http.StatusCreated)
- http.Redirect(w, r, p.String(), http.StatusCreated)
-}
-
-func (i *writableGatewayHandler) putHandler(w http.ResponseWriter, r *http.Request) {
- ctx := r.Context()
- ds := i.api.Dag()
-
- // Parse the path
- rootCid, newPath, err := parseIpfsPath(r.URL.Path)
- if err != nil {
- webError(w, "WritableGateway: failed to parse the path", err, http.StatusBadRequest)
- return
- }
- if newPath == "" || newPath == "/" {
- http.Error(w, "WritableGateway: empty path", http.StatusBadRequest)
- return
- }
- newDirectory, newFileName := gopath.Split(newPath)
-
- // Resolve the old root.
-
- rnode, err := ds.Get(ctx, rootCid)
- if err != nil {
- webError(w, "WritableGateway: Could not create DAG from request", err, http.StatusInternalServerError)
- return
- }
-
- pbnd, ok := rnode.(*dag.ProtoNode)
- if !ok {
- webError(w, "Cannot read non protobuf nodes through gateway", dag.ErrNotProtobuf, http.StatusBadRequest)
- return
- }
-
- // Create the new file.
- newFilePath, err := i.api.Unixfs().Add(ctx, files.NewReaderFile(r.Body))
- if err != nil {
- webError(w, "WritableGateway: could not create DAG from request", err, http.StatusInternalServerError)
- return
- }
-
- newFile, err := ds.Get(ctx, newFilePath.Cid())
- if err != nil {
- webError(w, "WritableGateway: failed to resolve new file", err, http.StatusInternalServerError)
- return
- }
-
- // Patch the new file into the old root.
-
- root, err := mfs.NewRoot(ctx, ds, pbnd, nil)
- if err != nil {
- webError(w, "WritableGateway: failed to create MFS root", err, http.StatusBadRequest)
- return
- }
-
- if newDirectory != "" {
- err := mfs.Mkdir(root, newDirectory, mfs.MkdirOpts{Mkparents: true, Flush: false})
- if err != nil {
- webError(w, "WritableGateway: failed to create MFS directory", err, http.StatusInternalServerError)
- return
- }
- }
- dirNode, err := mfs.Lookup(root, newDirectory)
- if err != nil {
- webError(w, "WritableGateway: failed to lookup directory", err, http.StatusInternalServerError)
- return
- }
- dir, ok := dirNode.(*mfs.Directory)
- if !ok {
- http.Error(w, "WritableGateway: target directory is not a directory", http.StatusBadRequest)
- return
- }
- err = dir.Unlink(newFileName)
- switch err {
- case os.ErrNotExist, nil:
- default:
- webError(w, "WritableGateway: failed to replace existing file", err, http.StatusBadRequest)
- return
- }
- err = dir.AddChild(newFileName, newFile)
- if err != nil {
- webError(w, "WritableGateway: failed to link file into directory", err, http.StatusInternalServerError)
- return
- }
- nnode, err := root.GetDirectory().GetNode()
- if err != nil {
- webError(w, "WritableGateway: failed to finalize", err, http.StatusInternalServerError)
- return
- }
- newcid := nnode.Cid()
-
- i.addUserHeaders(w) // ok, _now_ write user's headers.
- w.Header().Set("IPFS-Hash", newcid.String())
-
- redirectURL := gopath.Join(ipfsPathPrefix, newcid.String(), newPath)
- log.Debugw("CID replaced, redirect", "from", r.URL, "to", redirectURL, "status", http.StatusCreated)
- http.Redirect(w, r, redirectURL, http.StatusCreated)
-}
-
-func (i *writableGatewayHandler) deleteHandler(w http.ResponseWriter, r *http.Request) {
- ctx := r.Context()
-
- // parse the path
-
- rootCid, newPath, err := parseIpfsPath(r.URL.Path)
- if err != nil {
- webError(w, "WritableGateway: failed to parse the path", err, http.StatusBadRequest)
- return
- }
- if newPath == "" || newPath == "/" {
- http.Error(w, "WritableGateway: empty path", http.StatusBadRequest)
- return
- }
- directory, filename := gopath.Split(newPath)
-
- // lookup the root
-
- rootNodeIPLD, err := i.api.Dag().Get(ctx, rootCid)
- if err != nil {
- webError(w, "WritableGateway: failed to resolve root CID", err, http.StatusInternalServerError)
- return
- }
- rootNode, ok := rootNodeIPLD.(*dag.ProtoNode)
- if !ok {
- http.Error(w, "WritableGateway: empty path", http.StatusInternalServerError)
- return
- }
-
- // construct the mfs root
-
- root, err := mfs.NewRoot(ctx, i.api.Dag(), rootNode, nil)
- if err != nil {
- webError(w, "WritableGateway: failed to construct the MFS root", err, http.StatusBadRequest)
- return
- }
-
- // lookup the parent directory
-
- parentNode, err := mfs.Lookup(root, directory)
- if err != nil {
- webError(w, "WritableGateway: failed to look up parent", err, http.StatusInternalServerError)
- return
- }
-
- parent, ok := parentNode.(*mfs.Directory)
- if !ok {
- http.Error(w, "WritableGateway: parent is not a directory", http.StatusInternalServerError)
- return
- }
-
- // delete the file
-
- switch parent.Unlink(filename) {
- case nil, os.ErrNotExist:
- default:
- webError(w, "WritableGateway: failed to remove file", err, http.StatusInternalServerError)
- return
- }
-
- nnode, err := root.GetDirectory().GetNode()
- if err != nil {
- webError(w, "WritableGateway: failed to finalize", err, http.StatusInternalServerError)
- return
- }
- ncid := nnode.Cid()
-
- i.addUserHeaders(w) // ok, _now_ write user's headers.
- w.Header().Set("IPFS-Hash", ncid.String())
-
- redirectURL := gopath.Join(ipfsPathPrefix+ncid.String(), directory)
- // note: StatusCreated is technically correct here as we created a new resource.
- log.Debugw("CID deleted, redirect", "from", r.RequestURI, "to", redirectURL, "status", http.StatusCreated)
- http.Redirect(w, r, redirectURL, http.StatusCreated)
-}
-
-func parseIpfsPath(p string) (cid.Cid, string, error) {
- rootPath, err := path.ParsePath(p)
- if err != nil {
- return cid.Cid{}, "", err
- }
-
- // Check the path.
- rsegs := rootPath.Segments()
- if rsegs[0] != "ipfs" {
- return cid.Cid{}, "", fmt.Errorf("WritableGateway: only ipfs paths supported")
- }
-
- rootCid, err := cid.Decode(rsegs[1])
- if err != nil {
- return cid.Cid{}, "", err
- }
-
- return rootCid, path.Join(rsegs[2:]), nil
-}
-
-func webError(w http.ResponseWriter, message string, err error, defaultCode int) {
- if _, ok := err.(resolver.ErrNoLink); ok {
- webErrorWithCode(w, message, err, http.StatusNotFound)
- } else if err == routing.ErrNotFound {
- webErrorWithCode(w, message, err, http.StatusNotFound)
- } else if ipld.IsNotFound(err) {
- webErrorWithCode(w, message, err, http.StatusNotFound)
- } else if err == context.DeadlineExceeded {
- webErrorWithCode(w, message, err, http.StatusRequestTimeout)
- } else {
- webErrorWithCode(w, message, err, defaultCode)
- }
-}
-
-func webErrorWithCode(w http.ResponseWriter, message string, err error, code int) {
- http.Error(w, fmt.Sprintf("%s: %s", message, err), code)
- if code >= 500 {
- log.Warnf("server error: %s: %s", message, err)
- }
-}
-
-// return a 500 error and log
-func internalWebError(w http.ResponseWriter, err error) {
- webErrorWithCode(w, "internalWebError", err, http.StatusInternalServerError)
-}
diff --git a/docs/config.md b/docs/config.md
index 2e9fff51265..74d3600b962 100644
--- a/docs/config.md
+++ b/docs/config.md
@@ -681,14 +681,7 @@ Type: `string` (url)
### `Gateway.Writable`
-**DEPRECATED**: Enables legacy PUT/POST request handling.
-
-This API is not standardized, and should not be used for new projects.
-We are working on a modern replacement. IPIP can be tracked in [ipfs/specs#375](https://github.com/ipfs/specs/issues/375).
-
-Default: `false`
-
-Type: `bool`
+**REMOVED**: this option has been removed. We are working on a modern replacement. IPIP can be tracked in [ipfs/specs#375](https://github.com/ipfs/specs/issues/375).
### `Gateway.PathPrefixes`
diff --git a/test/sharness/lib/test-lib.sh b/test/sharness/lib/test-lib.sh
index 3aecaec994b..8b57fb1a1bd 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 115114c890a..00000000000
--- a/test/sharness/t0111-gateway-writeable.sh
+++ /dev/null
@@ -1,136 +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 "deprecation notice is printed when Gateway.Writable=true" '
- test_should_contain "legacy Gateway.Writable is DEPRECATED and will be removed or changed in future versions. If you are still using this, provide feedback in https://github.com/ipfs/specs/issues/375" daemon_err
-'
-
-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