mirror of
https://github.com/ipfs/kubo.git
synced 2025-05-17 23:16:11 +08:00
core/corehttp!: remove /api/v0 from gateway port
This commit is contained in:
@ -850,8 +850,6 @@ func serveHTTPGateway(req *cmds.Request, cctx *oldcmds.Context) (<-chan error, e
|
||||
corehttp.GatewayOption("/ipfs", "/ipns"),
|
||||
corehttp.VersionOption(),
|
||||
corehttp.CheckVersionOption(),
|
||||
// TODO[api-on-gw]: remove for 0.28.0: https://github.com/ipfs/kubo/issues/10312
|
||||
corehttp.CommandsROOption(cmdctx),
|
||||
}
|
||||
|
||||
if cfg.Experimental.P2pHttpProxy {
|
||||
|
@ -9,7 +9,7 @@ const (
|
||||
|
||||
type GatewaySpec struct {
|
||||
// Paths is explicit list of path prefixes that should be handled by
|
||||
// this gateway. Example: `["/ipfs", "/ipns", "/api"]`
|
||||
// this gateway. Example: `["/ipfs", "/ipns"]`
|
||||
Paths []string
|
||||
|
||||
// UseSubdomains indicates whether or not this gateway uses subdomains
|
||||
|
@ -15,63 +15,6 @@ func collectPaths(prefix string, cmd *cmds.Command, out map[string]struct{}) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestROCommands(t *testing.T) {
|
||||
list := []string{
|
||||
"/block",
|
||||
"/block/get",
|
||||
"/block/stat",
|
||||
"/cat",
|
||||
"/commands",
|
||||
"/commands/completion",
|
||||
"/commands/completion/bash",
|
||||
"/commands/completion/fish",
|
||||
"/commands/completion/zsh",
|
||||
"/dag",
|
||||
"/dag/get",
|
||||
"/dag/resolve",
|
||||
"/dag/stat",
|
||||
"/dag/export",
|
||||
"/get",
|
||||
"/ls",
|
||||
"/name",
|
||||
"/name/resolve",
|
||||
"/object",
|
||||
"/object/data",
|
||||
"/object/get",
|
||||
"/object/links",
|
||||
"/object/stat",
|
||||
"/refs",
|
||||
"/resolve",
|
||||
"/version",
|
||||
}
|
||||
|
||||
cmdSet := make(map[string]struct{})
|
||||
collectPaths("", RootRO, cmdSet)
|
||||
|
||||
for _, path := range list {
|
||||
if _, ok := cmdSet[path]; !ok {
|
||||
t.Errorf("%q not in result", path)
|
||||
} else {
|
||||
delete(cmdSet, path)
|
||||
}
|
||||
}
|
||||
|
||||
for path := range cmdSet {
|
||||
t.Errorf("%q in result but shouldn't be", path)
|
||||
}
|
||||
|
||||
for _, path := range list {
|
||||
path = path[1:] // remove leading slash
|
||||
split := strings.Split(path, "/")
|
||||
sub, err := RootRO.Get(split)
|
||||
if err != nil {
|
||||
t.Errorf("error getting subcommand %q: %v", path, err)
|
||||
} else if sub == nil {
|
||||
t.Errorf("subcommand %q is nil even though there was no error", path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCommands(t *testing.T) {
|
||||
list := []string{
|
||||
"/add",
|
||||
|
@ -162,72 +162,9 @@ var rootSubcommands = map[string]*cmds.Command{
|
||||
"multibase": MbaseCmd,
|
||||
}
|
||||
|
||||
// RootRO is the readonly version of Root
|
||||
var RootRO = &cmds.Command{}
|
||||
|
||||
var CommandsDaemonROCmd = CommandsCmd(RootRO)
|
||||
|
||||
// RefsROCmd is `ipfs refs` command
|
||||
var RefsROCmd = &cmds.Command{}
|
||||
|
||||
// VersionROCmd is `ipfs version` command (without deps).
|
||||
var VersionROCmd = &cmds.Command{}
|
||||
|
||||
var rootROSubcommands = map[string]*cmds.Command{
|
||||
"commands": CommandsDaemonROCmd,
|
||||
"cat": CatCmd,
|
||||
"block": {
|
||||
Subcommands: map[string]*cmds.Command{
|
||||
"stat": blockStatCmd,
|
||||
"get": blockGetCmd,
|
||||
},
|
||||
},
|
||||
"get": GetCmd,
|
||||
"ls": LsCmd,
|
||||
"name": {
|
||||
Subcommands: map[string]*cmds.Command{
|
||||
"resolve": name.IpnsCmd,
|
||||
},
|
||||
},
|
||||
"object": {
|
||||
Subcommands: map[string]*cmds.Command{
|
||||
"data": ocmd.ObjectDataCmd,
|
||||
"links": ocmd.ObjectLinksCmd,
|
||||
"get": ocmd.ObjectGetCmd,
|
||||
"stat": ocmd.ObjectStatCmd,
|
||||
},
|
||||
},
|
||||
"dag": {
|
||||
Subcommands: map[string]*cmds.Command{
|
||||
"get": dag.DagGetCmd,
|
||||
"resolve": dag.DagResolveCmd,
|
||||
"stat": dag.DagStatCmd,
|
||||
"export": dag.DagExportCmd,
|
||||
},
|
||||
},
|
||||
"resolve": ResolveCmd,
|
||||
}
|
||||
|
||||
func init() {
|
||||
Root.ProcessHelp()
|
||||
*RootRO = *Root
|
||||
|
||||
// this was in the big map definition above before,
|
||||
// but if we leave it there lgc.NewCommand will be executed
|
||||
// before the value is updated (:/sanitize readonly refs command/)
|
||||
|
||||
// sanitize readonly refs command
|
||||
*RefsROCmd = *RefsCmd
|
||||
RefsROCmd.Subcommands = map[string]*cmds.Command{}
|
||||
rootROSubcommands["refs"] = RefsROCmd
|
||||
|
||||
// sanitize readonly version command (no need to expose precise deps)
|
||||
*VersionROCmd = *VersionCmd
|
||||
VersionROCmd.Subcommands = map[string]*cmds.Command{}
|
||||
rootROSubcommands["version"] = VersionROCmd
|
||||
|
||||
Root.Subcommands = rootSubcommands
|
||||
RootRO.Subcommands = rootROSubcommands
|
||||
}
|
||||
|
||||
type MessageOutput struct {
|
||||
|
@ -18,5 +18,4 @@ func TestCommandTree(t *testing.T) {
|
||||
}
|
||||
}
|
||||
printErrors(Root.DebugValidate())
|
||||
printErrors(RootRO.DebugValidate())
|
||||
}
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/ipfs/boxo/gateway"
|
||||
cmds "github.com/ipfs/go-ipfs-cmds"
|
||||
cmdsHttp "github.com/ipfs/go-ipfs-cmds/http"
|
||||
version "github.com/ipfs/kubo"
|
||||
@ -122,14 +121,10 @@ func patchCORSVars(c *cmdsHttp.ServerConfig, addr net.Addr) {
|
||||
c.SetAllowedOrigins(newOrigins...)
|
||||
}
|
||||
|
||||
func commandsOption(cctx oldcmds.Context, command *cmds.Command, allowGet bool) ServeOption {
|
||||
func commandsOption(cctx oldcmds.Context, command *cmds.Command) ServeOption {
|
||||
return func(n *core.IpfsNode, l net.Listener, mux *http.ServeMux) (*http.ServeMux, error) {
|
||||
cfg := cmdsHttp.NewServerConfig()
|
||||
cfg.AllowGet = allowGet
|
||||
corsAllowedMethods := []string{http.MethodPost}
|
||||
if allowGet {
|
||||
corsAllowedMethods = append(corsAllowedMethods, http.MethodGet)
|
||||
}
|
||||
|
||||
cfg.SetAllowedMethods(corsAllowedMethods...)
|
||||
cfg.APIPath = APIPath
|
||||
@ -150,13 +145,6 @@ func commandsOption(cctx oldcmds.Context, command *cmds.Command, allowGet bool)
|
||||
cmdHandler = withAuthSecrets(authorizations, cmdHandler)
|
||||
}
|
||||
|
||||
// TODO[api-on-gw]: remove for Kubo 0.28
|
||||
if command == corecommands.RootRO && allowGet {
|
||||
cmdHandler = gateway.NewHeaders(map[string][]string{
|
||||
"Link": {`<https://github.com/ipfs/kubo/issues/10312>; rel="deprecation"; type="text/html"`},
|
||||
}).Wrap(cmdHandler)
|
||||
}
|
||||
|
||||
cmdHandler = otelhttp.NewHandler(cmdHandler, "corehttp.cmdsHandler")
|
||||
mux.Handle(APIPath+"/", cmdHandler)
|
||||
return mux, nil
|
||||
@ -211,13 +199,7 @@ func withAuthSecrets(authorizations map[string]rpcAuthScopeWithUser, next http.H
|
||||
// CommandsOption constructs a ServerOption for hooking the commands into the
|
||||
// HTTP server. It will NOT allow GET requests.
|
||||
func CommandsOption(cctx oldcmds.Context) ServeOption {
|
||||
return commandsOption(cctx, corecommands.Root, false)
|
||||
}
|
||||
|
||||
// CommandsROOption constructs a ServerOption for hooking the read-only commands
|
||||
// into the HTTP server. It will allow GET requests.
|
||||
func CommandsROOption(cctx oldcmds.Context) ServeOption {
|
||||
return commandsOption(cctx, corecommands.RootRO, true)
|
||||
return commandsOption(cctx, corecommands.Root)
|
||||
}
|
||||
|
||||
// CheckVersionOption returns a ServeOption that checks whether the client ipfs version matches. Does nothing when the user agent string does not contain `/kubo/` or `/go-ipfs/`
|
||||
|
@ -235,7 +235,7 @@ func (o *offlineGatewayErrWrapper) GetDNSLinkRecord(ctx context.Context, s strin
|
||||
|
||||
var _ gateway.IPFSBackend = (*offlineGatewayErrWrapper)(nil)
|
||||
|
||||
var defaultPaths = []string{"/ipfs/", "/ipns/", "/api/", "/p2p/"}
|
||||
var defaultPaths = []string{"/ipfs/", "/ipns/", "/p2p/"}
|
||||
|
||||
var subdomainGatewaySpec = &gateway.PublicGateway{
|
||||
Paths: defaultPaths,
|
||||
|
@ -7,17 +7,22 @@
|
||||
- [Overview](#overview)
|
||||
- [🔦 Highlights](#-highlights)
|
||||
- [RPC client: removed deprecated DHT API](#rpc-client-removed-deprecated-dht-api)
|
||||
- [Gateway: `/api/v0` is removed](#gateway-apiv0-is-removed)
|
||||
- [📝 Changelog](#-changelog)
|
||||
- [👨👩👧👦 Contributors](#-contributors)
|
||||
|
||||
### Overview
|
||||
|
||||
### 🔦 Highlights
|
||||
|
||||
#### RPC client: removed deprecated DHT API
|
||||
|
||||
The deprecated DHT API commands in the RPC client have been removed. Instead, use the Routing API.
|
||||
|
||||
#### Gateway: `/api/v0` is removed
|
||||
|
||||
The legacy subset of the Kubo RPC that was available via the Gateway port and was deprecated is now completely removed. You can read more in <https://github.com/ipfs/kubo/issues/10312>.
|
||||
|
||||
If you have a legacy software that relies on this behavior, and want to expose parts of `/api/v0` next to `/ipfs`, use reverse-proxy in front of Kubo to mount both Gateway and RPC on the same port. NOTE: exposing RPC to the internet comes with security risk: make sure to specify access control via [API.Authorizations](https://github.com/ipfs/kubo/blob/master/docs/config.md#apiauthorizations).
|
||||
|
||||
### 📝 Changelog
|
||||
|
||||
### 👨👩👧👦 Contributors
|
||||
|
@ -106,12 +106,3 @@ Right now only 'full DAG' implicit selector is implemented.
|
||||
Support for user-provided IPLD selectors is tracked in https://github.com/ipfs/kubo/issues/8769.
|
||||
|
||||
This is a rough equivalent of `ipfs dag export`.
|
||||
|
||||
## Deprecated Subset of RPC API
|
||||
|
||||
For legacy reasons, some gateways may expose a small subset of RPC API under `/api/v0/`.
|
||||
While this read-only API exposes a read-only, "safe" subset of the normal API,
|
||||
it is deprecated and should not be used for greenfield projects.
|
||||
|
||||
Where possible, leverage `/ipfs/` and `/ipns/` endpoints.
|
||||
along with `application/vnd.ipld.*` Content-Types instead.
|
||||
|
@ -14,7 +14,6 @@ import (
|
||||
|
||||
"github.com/ipfs/kubo/config"
|
||||
"github.com/ipfs/kubo/test/cli/harness"
|
||||
. "github.com/ipfs/kubo/test/cli/testutils"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"github.com/multiformats/go-multiaddr"
|
||||
manet "github.com/multiformats/go-multiaddr/net"
|
||||
@ -344,76 +343,6 @@ func TestGateway(t *testing.T) {
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("readonly API", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
client := node.GatewayClient()
|
||||
|
||||
fileContents := "12345"
|
||||
h.WriteFile("readonly/dir/test", fileContents)
|
||||
cids := node.IPFS("add", "-r", "-q", filepath.Join(h.Dir, "readonly/dir")).Stdout.Lines()
|
||||
|
||||
rootCID := cids[len(cids)-1]
|
||||
client.TemplateData = map[string]string{"RootCID": rootCID}
|
||||
|
||||
t.Run("Get IPFS directory file through readonly API succeeds", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
resp := client.Get("/api/v0/cat?arg={{.RootCID}}/test")
|
||||
assert.Equal(t, 200, resp.StatusCode)
|
||||
assert.Equal(t, fileContents, resp.Body)
|
||||
})
|
||||
|
||||
t.Run("refs IPFS directory file through readonly API succeeds", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
resp := client.Get("/api/v0/refs?arg={{.RootCID}}/test")
|
||||
assert.Equal(t, 200, resp.StatusCode)
|
||||
})
|
||||
|
||||
t.Run("test gateway API is sanitized", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
for _, cmd := range []string{
|
||||
"add",
|
||||
"block/put",
|
||||
"bootstrap",
|
||||
"config",
|
||||
"dag/put",
|
||||
"dag/import",
|
||||
"dht",
|
||||
"diag",
|
||||
"id",
|
||||
"mount",
|
||||
"name/publish",
|
||||
"object/put",
|
||||
"object/new",
|
||||
"object/patch",
|
||||
"pin",
|
||||
"ping",
|
||||
"repo",
|
||||
"stats",
|
||||
"swarm",
|
||||
"file",
|
||||
"update",
|
||||
"bitswap",
|
||||
} {
|
||||
t.Run(cmd, func(t *testing.T) {
|
||||
cmd := cmd
|
||||
t.Parallel()
|
||||
assert.Equal(t, 404, client.Get("/api/v0/"+cmd).StatusCode)
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("refs/local", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
gatewayAddr := URLStrToMultiaddr(node.GatewayURL())
|
||||
res := node.RunIPFS("--api", gatewayAddr.String(), "refs", "local")
|
||||
assert.Contains(t,
|
||||
res.Stderr.Trimmed(),
|
||||
`Error: invalid path "local":`,
|
||||
)
|
||||
})
|
||||
|
||||
t.Run("raw leaves node", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
contents := "This is RAW!"
|
||||
|
@ -50,7 +50,7 @@ test_expect_success "docker image runs" '
|
||||
'
|
||||
|
||||
test_expect_success "docker container gateway is up" '
|
||||
pollEndpoint -host=/ip4/127.0.0.1/tcp/8080 -http-url http://localhost:8080/api/v0/version -v -tries 30 -tout 1s
|
||||
pollEndpoint -host=/ip4/127.0.0.1/tcp/8080 -http-url http://localhost:8080/ipfs/bafkqaddimvwgy3zao5xxe3debi -v -tries 30 -tout 1s
|
||||
'
|
||||
|
||||
test_expect_success "docker container API is up" '
|
||||
|
@ -127,70 +127,6 @@ test_expect_success "Access-Control-Allow-Origin replaces the implicit list" '
|
||||
test_should_contain "< Access-Control-Allow-Origin: localhost" curl_output
|
||||
'
|
||||
|
||||
# Read-Only /api/v0 RPC API (legacy subset, exposed on the Gateway Port)
|
||||
# TODO: we want to remove it, but for now this guards the legacy behavior to not go any further
|
||||
|
||||
# also check this, as due to legacy reasons Kubo exposes small subset of /api/v0 on GW port
|
||||
test_expect_success "Assert the default API.HTTPHeaders config is empty" '
|
||||
echo "{}" > expected &&
|
||||
ipfs config --json API.HTTPHeaders > actual &&
|
||||
test_cmp expected actual
|
||||
'
|
||||
|
||||
# HTTP GET Request
|
||||
test_expect_success "Default CORS GET to {gw}/api/v0" '
|
||||
curl -svX GET -H "Origin: https://example.com" "http://127.0.0.1:$GWAY_PORT/api/v0/cat?arg=$thash" >/dev/null 2>curl_output
|
||||
'
|
||||
# HTTP 403 is returned because Kubo has additional protections on top of regular CORS,
|
||||
# namely it only allows browser requests with localhost Origin header.
|
||||
test_expect_success "Default CORS GET response from {gw}/api/v0 is 403 Forbidden and has regular CORS headers" '
|
||||
test_should_contain "HTTP/1.1 403 Forbidden" curl_output &&
|
||||
test_should_contain "< Access-Control-" curl_output
|
||||
'
|
||||
|
||||
# HTTP OPTIONS Request
|
||||
test_expect_success "Default OPTIONS to {gw}/api/v0" '
|
||||
curl -svX OPTIONS -H "Origin: https://example.com" "http://127.0.0.1:$GWAY_PORT/api/v0/cat?arg=$thash" 2>curl_output
|
||||
'
|
||||
# OPTIONS Response from the API should NOT contain CORS headers
|
||||
test_expect_success "OPTIONS response from {gw}/api/v0 has CORS headers" '
|
||||
test_should_contain "< Access-Control-" curl_output
|
||||
'
|
||||
|
||||
test_kill_ipfs_daemon
|
||||
|
||||
# TODO: /api/v0 with CORS headers set in API.HTTPHeaders does not really work,
|
||||
# as not all headers are correctly set. Below is only a basic regression test that documents
|
||||
# current state. Fixing CORS on /api/v0 (RPC and Gateway port) is tracked in https://github.com/ipfs/kubo/issues/7667
|
||||
|
||||
test_expect_success "Manually set API.HTTPHeaders config to be as relaxed as Gateway.HTTPHeaders" "
|
||||
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '[\"https://example.com\"]'
|
||||
"
|
||||
# TODO: ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '[\"GET\",\"POST\"]' &&
|
||||
# TODO: ipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '[\"X-Requested-With\", \"Range\", \"User-Agent\"]'
|
||||
|
||||
test_launch_ipfs_daemon
|
||||
|
||||
# HTTP GET Request
|
||||
test_expect_success "Manually relaxed CORS GET to {gw}/api/v0" '
|
||||
curl -svX GET -H "Origin: https://example.com" "http://127.0.0.1:$GWAY_PORT/api/v0/cat?arg=$thash" >/dev/null 2>curl_output
|
||||
'
|
||||
test_expect_success "Manually relaxed CORS GET response from {gw}/api/v0 is the same as Gateway" '
|
||||
test_should_contain "HTTP/1.1 200 OK" curl_output &&
|
||||
test_should_contain "< Access-Control-Allow-Origin: https://example.com" curl_output
|
||||
'
|
||||
# TODO: test_should_contain "< Access-Control-Allow-Methods: GET" curl_output
|
||||
|
||||
# HTTP OPTIONS Request
|
||||
test_expect_success "Manually relaxed OPTIONS to {gw}/api/v0" '
|
||||
curl -svX OPTIONS -H "Origin: https://example.com" "http://127.0.0.1:$GWAY_PORT/api/v0/cat?arg=$thash" 2>curl_output
|
||||
'
|
||||
# OPTIONS Response from the API should NOT contain CORS headers
|
||||
test_expect_success "Manually relaxed OPTIONS response from {gw}/api/v0 is the same as Gateway" '
|
||||
test_should_contain "< Access-Control-Allow-Origin: https://example.com" curl_output
|
||||
'
|
||||
# TODO: test_should_contain "< Access-Control-Allow-Methods: GET" curl_output
|
||||
|
||||
test_kill_ipfs_daemon
|
||||
|
||||
test_done
|
||||
|
@ -203,25 +203,6 @@ test_localhost_gateway_response_should_contain \
|
||||
|
||||
# end Kubo specific end-to-end test
|
||||
|
||||
# API on localhost subdomain gateway
|
||||
|
||||
# /api/v0 present on the root hostname
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for localhost/api" \
|
||||
"http://localhost:$GWAY_PORT/api/v0/refs?arg=${DIR_CID}&r=true" \
|
||||
"Ref"
|
||||
|
||||
# /api/v0 not mounted on content root subdomains
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for {cid}.ipfs.localhost/api returns data if present on the content root" \
|
||||
"http://${DIR_CID}.ipfs.localhost:$GWAY_PORT/api/file.txt" \
|
||||
"I am a txt file"
|
||||
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for {cid}.ipfs.localhost/api/v0/refs returns 404" \
|
||||
"http://${DIR_CID}.ipfs.localhost:$GWAY_PORT/api/v0/refs?arg=${DIR_CID}&r=true" \
|
||||
"404 Not Found"
|
||||
|
||||
## ============================================================================
|
||||
## Test subdomain-based requests to a local gateway with default config
|
||||
## (origin per content root at http://*.localhost)
|
||||
@ -308,14 +289,6 @@ test_localhost_gateway_response_should_contain \
|
||||
"http://$DNSLINK_FQDN.ipns.localhost:$GWAY_PORT" \
|
||||
"$CID_VAL"
|
||||
|
||||
# api.localhost/api
|
||||
|
||||
# Note: we use DIR_CID so refs -r returns some CIDs for child nodes
|
||||
test_localhost_gateway_response_should_contain \
|
||||
"request for api.localhost returns API response" \
|
||||
"http://api.localhost:$GWAY_PORT/api/v0/refs?arg=$DIR_CID&r=true" \
|
||||
"Ref"
|
||||
|
||||
## ============================================================================
|
||||
## Test DNSLink inlining on HTTP gateways
|
||||
## ============================================================================
|
||||
@ -518,54 +491,6 @@ test_hostname_gateway_response_should_contain \
|
||||
"http://127.0.0.1:$GWAY_PORT" \
|
||||
"Location: http://${ED25519_IPNS_IDv1}.ipns.example.com/"
|
||||
|
||||
# API on subdomain gateway example.com
|
||||
# ============================================================================
|
||||
|
||||
# present at the root domain
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for example.com/api/v0/refs returns expected payload when /api is on Paths whitelist" \
|
||||
"example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/api/v0/refs?arg=${DIR_CID}&r=true" \
|
||||
"Ref"
|
||||
|
||||
# not mounted on content root subdomains
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for {cid}.ipfs.example.com/api returns data if present on the content root" \
|
||||
"$DIR_CID.ipfs.example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/api/file.txt" \
|
||||
"I am a txt file"
|
||||
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for {cid}.ipfs.example.com/api/v0/refs returns 404" \
|
||||
"$CIDv1.ipfs.example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/api/v0/refs?arg=${DIR_CID}&r=true" \
|
||||
"404 Not Found"
|
||||
|
||||
# disable /api on example.com
|
||||
ipfs config --json Gateway.PublicGateways '{
|
||||
"example.com": {
|
||||
"UseSubdomains": true,
|
||||
"Paths": ["/ipfs", "/ipns"]
|
||||
}
|
||||
}' || exit 1
|
||||
# restart daemon to apply config changes
|
||||
test_kill_ipfs_daemon
|
||||
test_launch_ipfs_daemon_without_network
|
||||
|
||||
# not mounted at the root domain
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for example.com/api/v0/refs returns 404 if /api not on Paths whitelist" \
|
||||
"example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/api/v0/refs?arg=${DIR_CID}&r=true" \
|
||||
"404 Not Found"
|
||||
|
||||
# not mounted on content root subdomains
|
||||
test_hostname_gateway_response_should_contain \
|
||||
"request for {cid}.ipfs.example.com/api returns data if present on the content root" \
|
||||
"$DIR_CID.ipfs.example.com" \
|
||||
"http://127.0.0.1:$GWAY_PORT/api/file.txt" \
|
||||
"I am a txt file"
|
||||
|
||||
# DNSLink: <dnslink-fqdn>.ipns.example.com
|
||||
# (not really useful outside of localhost, as setting TLS for more than one
|
||||
# level of wildcard is a pain, but we support it if someone really wants it)
|
||||
|
Reference in New Issue
Block a user