1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-05-20 08:27:29 +08:00

refactor: namesys cleanup, gateway /ipns/ ttl (#10115)

This commit is contained in:
Henrique Dias
2023-10-18 10:23:50 +02:00
committed by GitHub
parent 170686b420
commit 4695fd9fed
20 changed files with 167 additions and 75 deletions

View File

@ -8,8 +8,8 @@ import (
iface "github.com/ipfs/boxo/coreiface"
caopts "github.com/ipfs/boxo/coreiface/options"
nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
"github.com/ipfs/boxo/ipns"
"github.com/ipfs/boxo/namesys"
"github.com/ipfs/boxo/path"
)
@ -49,9 +49,9 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name
return nil, err
}
ropts := nsopts.ProcessOpts(options.ResolveOpts)
if ropts.Depth != nsopts.DefaultDepthLimit && ropts.Depth != 1 {
return nil, fmt.Errorf("Name.Resolve: depth other than 1 or %d not supported", nsopts.DefaultDepthLimit)
ropts := namesys.ProcessResolveOptions(options.ResolveOpts)
if ropts.Depth != namesys.DefaultDepthLimit && ropts.Depth != 1 {
return nil, fmt.Errorf("Name.Resolve: depth other than 1 or %d not supported", namesys.DefaultDepthLimit)
}
req := api.core().Request("name/resolve", name).
@ -110,9 +110,9 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam
return nil, err
}
ropts := nsopts.ProcessOpts(options.ResolveOpts)
if ropts.Depth != nsopts.DefaultDepthLimit && ropts.Depth != 1 {
return nil, fmt.Errorf("Name.Resolve: depth other than 1 or %d not supported", nsopts.DefaultDepthLimit)
ropts := namesys.ProcessResolveOptions(options.ResolveOpts)
if ropts.Depth != namesys.DefaultDepthLimit && ropts.Depth != 1 {
return nil, fmt.Errorf("Name.Resolve: depth other than 1 or %d not supported", namesys.DefaultDepthLimit)
}
req := api.core().Request("name/resolve", name).

View File

@ -11,7 +11,7 @@ import (
func TestKeyTranslation(t *testing.T) {
pid := test.RandPeerIDFatal(t)
pkname := namesys.PkKeyForID(pid)
pkname := namesys.PkRoutingKey(pid)
ipnsname := ipns.NameFromPeer(pid).RoutingKey()
pkk, err := escapeDhtKey("/pk/" + pid.String())

View File

@ -4,8 +4,8 @@ import (
"fmt"
"io"
nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
namesys "github.com/ipfs/boxo/namesys"
"github.com/ipfs/boxo/path"
cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
ncmd "github.com/ipfs/kubo/core/commands/name"
@ -47,16 +47,21 @@ It will work across multiple DNSLinks and IPNS keys.
name := req.Arguments[0]
resolver := namesys.NewDNSResolver(node.DNSResolver.LookupTXT)
var routing []nsopts.ResolveOpt
var routing []namesys.ResolveOption
if !recursive {
routing = append(routing, nsopts.Depth(1))
routing = append(routing, namesys.ResolveWithDepth(1))
}
output, err := resolver.Resolve(req.Context, name, routing...)
p, err := path.NewPath(name)
if err != nil {
return err
}
val, err := resolver.Resolve(req.Context, p, routing...)
if err != nil && (recursive || err != namesys.ErrResolveRecursion) {
return err
}
return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: output.String()})
return cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: val.Path.String()})
},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *ncmd.ResolvedPath) error {

View File

@ -7,14 +7,12 @@ import (
"strings"
"time"
namesys "github.com/ipfs/boxo/namesys"
cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
options "github.com/ipfs/boxo/coreiface/options"
nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
"github.com/ipfs/boxo/namesys"
"github.com/ipfs/boxo/path"
cmds "github.com/ipfs/go-ipfs-cmds"
logging "github.com/ipfs/go-log"
cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
)
var log = logging.Logger("core/commands/ipns")
@ -75,8 +73,8 @@ Resolve the value of a dnslink:
Options: []cmds.Option{
cmds.BoolOption(recursiveOptionName, "r", "Resolve until the result is not an IPNS name.").WithDefault(true),
cmds.BoolOption(nocacheOptionName, "n", "Do not use cached entries."),
cmds.UintOption(dhtRecordCountOptionName, "dhtrc", "Number of records to request for DHT resolution."),
cmds.StringOption(dhtTimeoutOptionName, "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout."),
cmds.UintOption(dhtRecordCountOptionName, "dhtrc", "Number of records to request for DHT resolution.").WithDefault(uint(namesys.DefaultResolverDhtRecordCount)),
cmds.StringOption(dhtTimeoutOptionName, "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout.").WithDefault(namesys.DefaultResolverDhtTimeout.String()),
cmds.BoolOption(streamOptionName, "s", "Stream entries as they are found."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
@ -108,10 +106,10 @@ Resolve the value of a dnslink:
}
if !recursive {
opts = append(opts, options.Name.ResolveOption(nsopts.Depth(1)))
opts = append(opts, options.Name.ResolveOption(namesys.ResolveWithDepth(1)))
}
if rcok {
opts = append(opts, options.Name.ResolveOption(nsopts.DhtRecordCount(rc)))
opts = append(opts, options.Name.ResolveOption(namesys.ResolveWithDhtRecordCount(rc)))
}
if dhttok {
d, err := time.ParseDuration(dhtt)
@ -121,7 +119,7 @@ Resolve the value of a dnslink:
if d < 0 {
return errors.New("DHT timeout value must be >= 0")
}
opts = append(opts, options.Name.ResolveOption(nsopts.DhtTimeout(d)))
opts = append(opts, options.Name.ResolveOption(namesys.ResolveWithDhtTimeout(d)))
}
if !strings.HasPrefix(name, "/ipns/") {

View File

@ -11,6 +11,7 @@ import (
iface "github.com/ipfs/boxo/coreiface"
options "github.com/ipfs/boxo/coreiface/options"
ipns "github.com/ipfs/boxo/ipns"
cmds "github.com/ipfs/go-ipfs-cmds"
ke "github.com/ipfs/kubo/core/commands/keyencode"
)
@ -72,16 +73,13 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
cmds.StringArg(ipfsPathOptionName, true, false, "ipfs path of the object to be published.").EnableStdin(),
},
Options: []cmds.Option{
cmds.BoolOption(resolveOptionName, "Check if the given path can be resolved before publishing.").WithDefault(true),
cmds.StringOption(lifeTimeOptionName, "t",
`Time duration that the record will be valid for. <<default>>
This accepts durations such as "300s", "1.5h" or "2h45m". Valid time units are
"ns", "us" (or "µs"), "ms", "s", "m", "h".`).WithDefault("24h"),
cmds.BoolOption(allowOfflineOptionName, "When offline, save the IPNS record to the the local datastore without broadcasting to the network instead of simply failing."),
cmds.StringOption(ttlOptionName, "Time duration this record should be cached for. Uses the same syntax as the lifetime option. (caution: experimental)"),
cmds.StringOption(keyOptionName, "k", "Name of the key to be used or a valid PeerID, as listed by 'ipfs key list -l'.").WithDefault("self"),
cmds.BoolOption(quieterOptionName, "Q", "Write only final hash."),
cmds.BoolOption(resolveOptionName, "Check if the given path can be resolved before publishing.").WithDefault(true),
cmds.StringOption(lifeTimeOptionName, "t", `Time duration the signed record will be valid for. Accepts durations such as "300s", "1.5h" or "7d2h45m"`).WithDefault(ipns.DefaultRecordLifetime.String()),
cmds.StringOption(ttlOptionName, "Time duration hint, akin to --lifetime, indicating how long to cache this record before checking for updates.").WithDefault(ipns.DefaultRecordTTL.String()),
cmds.BoolOption(quieterOptionName, "Q", "Write only final IPNS Name encoded as CIDv1 (for use in /ipns content paths)."),
cmds.BoolOption(v1compatOptionName, "Produce a backward-compatible IPNS Record by including fields for both V1 and V2 signatures.").WithDefault(true),
cmds.BoolOption(allowOfflineOptionName, "When --offline, save the IPNS record to the the local datastore without broadcasting to the network (instead of failing)."),
ke.OptionIPNSBase,
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {

View File

@ -8,14 +8,13 @@ import (
"time"
ns "github.com/ipfs/boxo/namesys"
"github.com/ipfs/boxo/path"
cidenc "github.com/ipfs/go-cidutil/cidenc"
cmdenv "github.com/ipfs/kubo/core/commands/cmdenv"
"github.com/ipfs/kubo/core/commands/cmdutils"
ncmd "github.com/ipfs/kubo/core/commands/name"
options "github.com/ipfs/boxo/coreiface/options"
nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
"github.com/ipfs/boxo/path"
cmds "github.com/ipfs/go-ipfs-cmds"
)
@ -87,11 +86,11 @@ Resolve the value of an IPFS DAG path:
rc, rcok := req.Options[resolveDhtRecordCountOptionName].(uint)
dhtt, dhttok := req.Options[resolveDhtTimeoutOptionName].(string)
ropts := []options.NameResolveOption{
options.Name.ResolveOption(nsopts.Depth(1)),
options.Name.ResolveOption(ns.ResolveWithDepth(1)),
}
if rcok {
ropts = append(ropts, options.Name.ResolveOption(nsopts.DhtRecordCount(rc)))
ropts = append(ropts, options.Name.ResolveOption(ns.ResolveWithDhtRecordCount(rc)))
}
if dhttok {
d, err := time.ParseDuration(dhtt)
@ -101,7 +100,7 @@ Resolve the value of an IPFS DAG path:
if d < 0 {
return errors.New("DHT timeout value must be >= 0")
}
ropts = append(ropts, options.Name.ResolveOption(nsopts.DhtTimeout(d)))
ropts = append(ropts, options.Name.ResolveOption(ns.ResolveWithDhtTimeout(d)))
}
p, err := api.Name().Resolve(req.Context, name, ropts...)
// ErrResolveRecursion is fine

View File

@ -15,7 +15,6 @@ import (
coreiface "github.com/ipfs/boxo/coreiface"
caopts "github.com/ipfs/boxo/coreiface/options"
nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
"github.com/ipfs/boxo/path"
ci "github.com/libp2p/go-libp2p/core/crypto"
peer "github.com/libp2p/go-libp2p/core/peer"
@ -57,13 +56,13 @@ func (api *NameAPI) Publish(ctx context.Context, p path.Path, opts ...caopts.Nam
eol := time.Now().Add(options.ValidTime)
publishOptions := []nsopts.PublishOption{
nsopts.PublishWithEOL(eol),
nsopts.PublishCompatibleWithV1(options.CompatibleWithV1),
publishOptions := []namesys.PublishOption{
namesys.PublishWithEOL(eol),
namesys.PublishWithIPNSOption(ipns.WithV1Compatibility(options.CompatibleWithV1)),
}
if options.TTL != nil {
publishOptions = append(publishOptions, nsopts.PublishWithTTL(*options.TTL))
publishOptions = append(publishOptions, namesys.PublishWithTTL(*options.TTL))
}
err = api.namesys.Publish(ctx, k, p, publishOptions...)
@ -109,10 +108,15 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name
name = "/ipns/" + name
}
p, err := path.NewPath(name)
if err != nil {
return nil, err
}
out := make(chan coreiface.IpnsResult)
go func() {
defer close(out)
for res := range resolver.ResolveAsync(ctx, name, options.ResolveOpts...) {
for res := range resolver.ResolveAsync(ctx, p, options.ResolveOpts...) {
select {
case out <- coreiface.IpnsResult{Path: res.Path, Err: res.Err}:
case <-ctx.Done():

View File

@ -2,9 +2,10 @@ package coreapi
import (
"context"
"errors"
"fmt"
"github.com/ipfs/boxo/namesys/resolve"
"github.com/ipfs/boxo/namesys"
"github.com/ipfs/kubo/tracing"
"go.opentelemetry.io/otel/attribute"
@ -40,12 +41,13 @@ func (api *CoreAPI) ResolvePath(ctx context.Context, p path.Path) (path.Immutabl
ctx, span := tracing.Span(ctx, "CoreAPI", "ResolvePath", trace.WithAttributes(attribute.String("path", p.String())))
defer span.End()
p, err := resolve.ResolveIPNS(ctx, api.namesys, p)
if err == resolve.ErrNoNamesys {
res, err := namesys.Resolve(ctx, api.namesys, p)
if errors.Is(err, namesys.ErrNoNamesys) {
return path.ImmutablePath{}, nil, coreiface.ErrOffline
} else if err != nil {
return path.ImmutablePath{}, nil, err
}
p = res.Path
var resolver ipfspathresolver.Resolver
switch p.Namespace() {

View File

@ -7,6 +7,7 @@ import (
"io"
"net"
"net/http"
"time"
"github.com/ipfs/boxo/blockservice"
iface "github.com/ipfs/boxo/coreiface"
@ -195,10 +196,10 @@ func (o *offlineGatewayErrWrapper) GetIPNSRecord(ctx context.Context, c cid.Cid)
return rec, err
}
func (o *offlineGatewayErrWrapper) ResolveMutable(ctx context.Context, path path.Path) (path.ImmutablePath, error) {
imPath, err := o.gwimpl.ResolveMutable(ctx, path)
func (o *offlineGatewayErrWrapper) ResolveMutable(ctx context.Context, path path.Path) (path.ImmutablePath, time.Duration, time.Time, error) {
imPath, ttl, lastMod, err := o.gwimpl.ResolveMutable(ctx, path)
err = offlineErrWrap(err)
return imPath, err
return imPath, ttl, lastMod, err
}
func (o *offlineGatewayErrWrapper) GetDNSLinkRecord(ctx context.Context, s string) (path.Path, error) {

View File

@ -17,7 +17,6 @@ import (
"github.com/stretchr/testify/assert"
iface "github.com/ipfs/boxo/coreiface"
nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
"github.com/ipfs/boxo/path"
"github.com/ipfs/go-datastore"
syncds "github.com/ipfs/go-datastore/sync"
@ -27,41 +26,47 @@ import (
type mockNamesys map[string]path.Path
func (m mockNamesys) Resolve(ctx context.Context, name string, opts ...nsopts.ResolveOpt) (value path.Path, err error) {
cfg := nsopts.DefaultResolveOpts()
func (m mockNamesys) Resolve(ctx context.Context, p path.Path, opts ...namesys.ResolveOption) (namesys.Result, error) {
cfg := namesys.DefaultResolveOptions()
for _, o := range opts {
o(&cfg)
}
depth := cfg.Depth
if depth == nsopts.UnlimitedDepth {
if depth == namesys.UnlimitedDepth {
// max uint
depth = ^uint(0)
}
var (
value path.Path
)
name := path.SegmentsToString(p.Segments()[:2]...)
for strings.HasPrefix(name, "/ipns/") {
if depth == 0 {
return value, namesys.ErrResolveRecursion
return namesys.Result{Path: value}, namesys.ErrResolveRecursion
}
depth--
var ok bool
value, ok = m[name]
v, ok := m[name]
if !ok {
return nil, namesys.ErrResolveFailed
return namesys.Result{}, namesys.ErrResolveFailed
}
value = v
name = value.String()
}
return value, nil
value, err := path.Join(value, p.Segments()[2:]...)
return namesys.Result{Path: value}, err
}
func (m mockNamesys) ResolveAsync(ctx context.Context, name string, opts ...nsopts.ResolveOpt) <-chan namesys.Result {
out := make(chan namesys.Result, 1)
v, err := m.Resolve(ctx, name, opts...)
out <- namesys.Result{Path: v, Err: err}
func (m mockNamesys) ResolveAsync(ctx context.Context, p path.Path, opts ...namesys.ResolveOption) <-chan namesys.AsyncResult {
out := make(chan namesys.AsyncResult, 1)
res, err := m.Resolve(ctx, p, opts...)
out <- namesys.AsyncResult{Path: res.Path, TTL: res.TTL, LastMod: res.LastMod, Err: err}
close(out)
return out
}
func (m mockNamesys) Publish(ctx context.Context, name ci.PrivKey, value path.Path, opts ...nsopts.PublishOption) error {
func (m mockNamesys) Publish(ctx context.Context, name ci.PrivKey, value path.Path, opts ...namesys.PublishOption) error {
return errors.New("not implemented for mockNamesys")
}

View File

@ -7,6 +7,8 @@
- [Overview](#overview)
- [🔦 Highlights](#-highlights)
- [Gateway: the root of the CARs are no longer meaningful](#gateway-the-root-of-the-cars-are-no-longer-meaningful)
- [IPNS: improved publishing defaults](#ipns-improved-publishing-defaults)
- [IPNS: record TTL is used for caching](#ipns-record-ttl-is-used-for-caching)
- [📝 Changelog](#-changelog)
- [👨‍👩‍👧‍👦 Contributors](#-contributors)
@ -22,6 +24,41 @@ path. However, in situations where the path cannot be resolved, such as when
the path does not exist, a CAR will be sent with a root of `bafkqaaa` (empty CID).
This CAR will contain all blocks necessary to validate that the path does not exist.
#### IPNS: improved publishing defaults
This release changes the default values used when publishing IPNS record
via `ipfs name publish` command:
- Default `--lifetime` increased from `24h` to `48h` to take full advantage of
the increased expiration window of Amino DHT
([go-libp2p-kad-dht#793](https://github.com/libp2p/go-libp2p-kad-dht/pull/793))
- Default `--ttl` increased from `1m` to `1h` to improve website caching and follow
saner defaults present in similar systems like DNS
([specs#371](https://github.com/ipfs/specs/pull/371))
This change only impacts the implicit defaults, when mentioned parameters are omitted
during publishing. Users are free to override the default if different value
makes more sense for their use case.
#### IPNS: record TTL is used for caching
In this release, we've made significant improvements to IPNS caching.
Previously, the TTL value in IPNS records was not utilized, and the
`boxo/namesys` library maintained a static one-minute resolution cache.
With this update, IPNS publishers gain more control over how long a valid IPNS
record remains cached before checking an upstream routing system, such as Amino
DHT, for updates. The TTL value in the IPNS record now serves as a hint for:
- `boxo/namesys`: the internal cache, determining how long the IPNS resolution
result is cached before asking upsteam routing systems for updates.
- `boxo/gateway`: the `Cache-Control` HTTP header in responses to requests made
for `/ipns/name` content paths.
These changes make it easier for rarely updated IPNS-hosted websites to be
cached more efficiently and load faster in browser contexts.
### 📝 Changelog
### 👨‍👩‍👧‍👦 Contributors

View File

@ -7,7 +7,7 @@ go 1.20
replace github.com/ipfs/kubo => ./../../..
require (
github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f
github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd
github.com/ipfs/kubo v0.0.0-00010101000000-000000000000
github.com/libp2p/go-libp2p v0.31.0
github.com/multiformats/go-multiaddr v0.11.0

View File

@ -300,8 +300,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f h1:iSo5r2GcXv5lX+UwVmarbSB9OjtvfnqQ4nwiiWWib8I=
github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd h1:CWz2mhz+cmkLRlKgQYlKXkDtx4oWYkCorSSF4ZWkH3o=
github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY=

View File

@ -4,7 +4,7 @@ import (
"context"
ft "github.com/ipfs/boxo/ipld/unixfs"
nsys "github.com/ipfs/boxo/namesys"
"github.com/ipfs/boxo/namesys"
"github.com/ipfs/boxo/path"
"github.com/ipfs/kubo/core"
ci "github.com/libp2p/go-libp2p/core/crypto"
@ -28,7 +28,7 @@ func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error {
return err
}
pub := nsys.NewIpnsPublisher(n.Routing, n.Repo.Datastore())
pub := namesys.NewIPNSPublisher(n.Routing, n.Repo.Datastore())
return pub.Publish(ctx, key, path.FromCid(emptyDir.Cid()))
}

2
go.mod
View File

@ -15,7 +15,7 @@ require (
github.com/fsnotify/fsnotify v1.6.0
github.com/google/uuid v1.3.1
github.com/hashicorp/go-multierror v1.1.1
github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f
github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd
github.com/ipfs/go-block-format v0.2.0
github.com/ipfs/go-cid v0.4.1
github.com/ipfs/go-cidutil v0.1.0

4
go.sum
View File

@ -335,8 +335,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f h1:iSo5r2GcXv5lX+UwVmarbSB9OjtvfnqQ4nwiiWWib8I=
github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd h1:CWz2mhz+cmkLRlKgQYlKXkDtx4oWYkCorSSF4ZWkH3o=
github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ=

View File

@ -8,6 +8,8 @@ import (
"os"
"path/filepath"
"regexp"
"strconv"
"strings"
"testing"
"github.com/ipfs/kubo/config"
@ -169,7 +171,7 @@ func TestGateway(t *testing.T) {
t.Run("IPNS", func(t *testing.T) {
t.Parallel()
node.IPFS("name", "publish", "--allow-offline", cid)
node.IPFS("name", "publish", "--allow-offline", "--ttl", "42h", cid)
t.Run("GET invalid IPNS root returns 500 (Internal Server Error)", func(t *testing.T) {
t.Parallel()
@ -184,6 +186,17 @@ func TestGateway(t *testing.T) {
assert.Equal(t, "Hello Worlds!", resp.Body)
})
t.Run("GET IPNS path has correct Cache-Control", func(t *testing.T) {
t.Parallel()
resp := client.Get("/ipns/{{.PeerID}}")
assert.Equal(t, 200, resp.StatusCode)
cacheControl := resp.Headers.Get("Cache-Control")
assert.True(t, strings.HasPrefix(cacheControl, "public, max-age="))
maxAge, err := strconv.Atoi(strings.TrimPrefix(cacheControl, "public, max-age="))
assert.NoError(t, err)
assert.True(t, maxAge-151200 < 60) // MaxAge within 42h and 42h-1m
})
t.Run("GET /ipfs/ipns/{peerid} returns redirect to the valid path", func(t *testing.T) {
t.Parallel()
resp := client.Get("/ipfs/ipns/{{.PeerID}}?query=to-remember")

View File

@ -7,7 +7,7 @@ replace github.com/ipfs/kubo => ../../
require (
github.com/Kubuxu/gocovmerge v0.0.0-20161216165753-7ecaa51963cd
github.com/golangci/golangci-lint v1.54.1
github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f
github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd
github.com/ipfs/go-cid v0.4.1
github.com/ipfs/go-cidutil v0.1.0
github.com/ipfs/go-datastore v0.6.0
@ -165,6 +165,10 @@ require (
github.com/libp2p/go-cidranger v1.1.0 // indirect
github.com/libp2p/go-flow-metrics v0.1.0 // indirect
github.com/libp2p/go-libp2p-asn-util v0.3.0 // indirect
github.com/libp2p/go-libp2p-kad-dht v0.24.4 // indirect
github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect
github.com/libp2p/go-libp2p-record v0.2.0 // indirect
github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect
github.com/libp2p/go-msgio v0.3.0 // indirect
github.com/libp2p/go-nat v0.2.0 // indirect
github.com/libp2p/go-netroute v0.2.1 // indirect
@ -264,11 +268,14 @@ require (
github.com/ultraware/whitespace v0.0.5 // indirect
github.com/urfave/cli v1.22.10 // indirect
github.com/uudashr/gocognit v1.0.7 // indirect
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect
github.com/xen0n/gosmopolitan v1.2.1 // indirect
github.com/yagipy/maintidx v1.0.0 // indirect
github.com/yeya24/promlinter v0.2.0 // indirect
github.com/ykadowak/zerologlint v0.1.3 // indirect
gitlab.com/bosi/decorder v0.4.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel v1.19.0 // indirect
go.opentelemetry.io/otel/metric v1.19.0 // indirect
go.opentelemetry.io/otel/trace v1.19.0 // indirect
@ -288,6 +295,7 @@ require (
golang.org/x/term v0.13.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.13.0 // indirect
gonum.org/v1/gonum v0.13.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect

View File

@ -252,6 +252,7 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
@ -310,6 +311,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
@ -396,8 +398,8 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0=
github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f h1:iSo5r2GcXv5lX+UwVmarbSB9OjtvfnqQ4nwiiWWib8I=
github.com/ipfs/boxo v0.13.2-0.20231017164040-0a566c9ee75f/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd h1:CWz2mhz+cmkLRlKgQYlKXkDtx4oWYkCorSSF4ZWkH3o=
github.com/ipfs/boxo v0.13.2-0.20231018081237-a50f784985dd/go.mod h1:btrtHy0lmO1ODMECbbEY1pxNtrLilvKSYLoGQt1yYCk=
github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA=
github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU=
github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs=
@ -546,7 +548,14 @@ github.com/libp2p/go-libp2p v0.31.0 h1:LFShhP8F6xthWiBBq3euxbKjZsoRajVEyBS9snfHx
github.com/libp2p/go-libp2p v0.31.0/go.mod h1:W/FEK1c/t04PbRH3fA9i5oucu5YcgrG0JVoBWT1B7Eg=
github.com/libp2p/go-libp2p-asn-util v0.3.0 h1:gMDcMyYiZKkocGXDQ5nsUQyquC9+H+iLEQHwOCZ7s8s=
github.com/libp2p/go-libp2p-asn-util v0.3.0/go.mod h1:B1mcOrKUE35Xq/ASTmQ4tN3LNzVVaMNmq2NACuqyB9w=
github.com/libp2p/go-libp2p-kad-dht v0.24.4 h1:ktNiJe7ffsJ1wX3ULpMCwXts99mPqGFSE/Qn1i8pErQ=
github.com/libp2p/go-libp2p-kad-dht v0.24.4/go.mod h1:ybWBJ5Fbvz9sSLkNtXt+2+bK0JB8+tRPvhBbRGHegRU=
github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0=
github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0=
github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0=
github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk=
github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY=
github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8=
github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA=
github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0=
github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM=
@ -848,6 +857,7 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
@ -887,9 +897,13 @@ github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMI
github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s=
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSDJfjId/PEGEShv6ugrt4kYsC5UIDaQ=
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboadS0DvysUuJXZ4lWVv5Bh5i7+tbIyi+ck4=
github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM=
github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0=
github.com/whyrusleeping/cbor-gen v0.0.0-20230126041949-52956bd4c9aa h1:EyA027ZAkuaCLoxVX4r1TZMPy1d31fM6hbfQ4OU4I5o=
github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k=
github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc=
github.com/xen0n/gosmopolitan v1.2.1 h1:3pttnTuFumELBRSh+KQs1zcz4fN6Zy7aB0xlnQSn1Iw=
github.com/xen0n/gosmopolitan v1.2.1/go.mod h1:JsHq/Brs1o050OOdmzHeOr0N7OtlnKRAGAsElF8xBQA=
github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM=
@ -915,6 +929,8 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs=
go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY=
go.opentelemetry.io/otel/metric v1.19.0 h1:aTzpGtV0ar9wlV4Sna9sdJyII5jTVJEvKETPiOKwvpE=
@ -1045,6 +1061,7 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
@ -1266,6 +1283,8 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
gonum.org/v1/gonum v0.13.0 h1:a0T3bh+7fhRyqeNbiC3qVHYmkiQgit3wnNan/2c0HMM=
gonum.org/v1/gonum v0.13.0/go.mod h1:/WPYRckkfWrhWefxyYTfrTtQR0KH4iyHNuzxqXAKyAU=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.1.0/go.mod h1:UGEZY7KEX120AnNLIHFMKIo4obdJhkp2tPbaPlQx13Y=

View File

@ -30,8 +30,11 @@ test_resolve_setup_name() {
local key="$1"
local ref="$2"
# we pass here --ttl=0s to ensure that it does not get cached by namesys.
# the alternative would be to wait between tests to ensure that the namesys
# cache gets purged in time, but that adds runtime time for the tests.
test_expect_success "resolve: prepare $key" '
ipfs name publish --key="$key" --allow-offline "$ref"
ipfs name publish --key="$key" --ttl=0s --allow-offline "$ref"
'
}