Skip to content

Commit 310943f

Browse files
committed
feat!: namesys refactor, ipns TTL bubbled up to gateway
1 parent 45c797e commit 310943f

40 files changed

+1570
-1614
lines changed

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ The following emojis are used to highlight certain changes:
1616

1717
### Added
1818

19+
* The gateway now sets a `Cache-Control` header for requests under the `/ipns/` namespace
20+
if the TTL for the corresponding IPNS Records or DNSLink entities is known.
21+
1922
### Changed
2023

2124
* `boxo/gateway`
@@ -35,6 +38,18 @@ The following emojis are used to highlight certain changes:
3538
- Eliminate `..` elements that begin a rooted path: that is, replace "`/..`" by "`/`" at the beginning of a path.
3639
* 🛠 The signature of `CoreAPI.ResolvePath` in `coreiface` has changed to now return
3740
the remainder segments as a second return value, matching the signature of `resolver.ResolveToLastNode`.
41+
* 🛠 The `namesys` package has been refactored. The following are the largest modifications:
42+
* The options in `coreiface/options/namesys` have been moved to `namesys` and their names
43+
have been made more consistent.
44+
* Many of the exported structs and functions have been renamed in order to be consistent with
45+
the remaining packages.
46+
* `namesys.Resolver.Resolve` now returns a TTL, in addition to the resolved path. If the
47+
TTL is unknown, 0 is returned. `IPNSResolver` is able to resolve a TTL, while `DNSResolver`
48+
is not.
49+
* `namesys/resolver.ResolveIPNS` has been moved to `namesys.ResolveIPNS` and now returns a TTL
50+
in addition to the resolved path.
51+
* 🛠 The `gateway`'s `IPFSBackend.ResolveMutable` is now expected to return a TTL in addition to
52+
the resolved path. If the TTL is unknown, 0 should be returned.
3853

3954
### Removed
4055

coreiface/options/name.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package options
33
import (
44
"time"
55

6-
ropts "github.com/ipfs/boxo/coreiface/options/namesys"
6+
"github.com/ipfs/boxo/namesys"
77
)
88

99
const (
@@ -21,7 +21,7 @@ type NamePublishSettings struct {
2121
type NameResolveSettings struct {
2222
Cache bool
2323

24-
ResolveOpts []ropts.ResolveOpt
24+
ResolveOpts []namesys.ResolveOption
2525
}
2626

2727
type (
@@ -123,7 +123,7 @@ func (nameOpts) Cache(cache bool) NameResolveOption {
123123
}
124124
}
125125

126-
func (nameOpts) ResolveOption(opt ropts.ResolveOpt) NameResolveOption {
126+
func (nameOpts) ResolveOption(opt namesys.ResolveOption) NameResolveOption {
127127
return func(settings *NameResolveSettings) error {
128128
settings.ResolveOpts = append(settings.ResolveOpts, opt)
129129
return nil

coreiface/options/namesys/opts.go

Lines changed: 0 additions & 131 deletions
This file was deleted.

gateway/blocks_backend.go

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@ import (
88
"io"
99
"net/http"
1010
"strings"
11+
"time"
1112

1213
"github.com/ipfs/boxo/blockservice"
1314
blockstore "github.com/ipfs/boxo/blockstore"
14-
nsopts "github.com/ipfs/boxo/coreiface/options/namesys"
1515
"github.com/ipfs/boxo/fetcher"
1616
bsfetcher "github.com/ipfs/boxo/fetcher/impl/blockservice"
1717
"github.com/ipfs/boxo/files"
1818
"github.com/ipfs/boxo/ipld/merkledag"
1919
ufile "github.com/ipfs/boxo/ipld/unixfs/file"
2020
uio "github.com/ipfs/boxo/ipld/unixfs/io"
21+
"github.com/ipfs/boxo/ipns"
2122
"github.com/ipfs/boxo/namesys"
22-
"github.com/ipfs/boxo/namesys/resolve"
2323
"github.com/ipfs/boxo/path"
2424
"github.com/ipfs/boxo/path/resolver"
2525
blocks "github.com/ipfs/go-block-format"
@@ -39,7 +39,6 @@ import (
3939
"github.com/ipld/go-ipld-prime/traversal/selector"
4040
selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse"
4141
routinghelpers "github.com/libp2p/go-libp2p-routing-helpers"
42-
"github.com/libp2p/go-libp2p/core/peer"
4342
"github.com/libp2p/go-libp2p/core/routing"
4443
mc "github.com/multiformats/go-multicodec"
4544

@@ -615,18 +614,23 @@ func (bb *BlocksBackend) getPathRoots(ctx context.Context, contentPath path.Immu
615614
return pathRoots, lastPath, remainder, nil
616615
}
617616

618-
func (bb *BlocksBackend) ResolveMutable(ctx context.Context, p path.Path) (path.ImmutablePath, error) {
617+
func (bb *BlocksBackend) ResolveMutable(ctx context.Context, p path.Path) (path.ImmutablePath, time.Duration, time.Time, error) {
619618
switch p.Namespace() {
620619
case path.IPNSNamespace:
621-
p, err := resolve.ResolveIPNS(ctx, bb.namesys, p)
620+
res, err := namesys.Resolve(ctx, bb.namesys, p)
622621
if err != nil {
623-
return path.ImmutablePath{}, err
622+
return path.ImmutablePath{}, 0, time.Time{}, err
624623
}
625-
return path.NewImmutablePath(p)
624+
ip, err := path.NewImmutablePath(res.Path)
625+
if err != nil {
626+
return path.ImmutablePath{}, 0, time.Time{}, err
627+
}
628+
return ip, res.TTL, res.LastMod, nil
626629
case path.IPFSNamespace:
627-
return path.NewImmutablePath(p)
630+
ip, err := path.NewImmutablePath(p)
631+
return ip, 0, time.Time{}, err
628632
default:
629-
return path.ImmutablePath{}, NewErrorStatusCode(fmt.Errorf("unsupported path namespace: %s", p.Namespace()), http.StatusNotImplemented)
633+
return path.ImmutablePath{}, 0, time.Time{}, NewErrorStatusCode(fmt.Errorf("unsupported path namespace: %s", p.Namespace()), http.StatusNotImplemented)
630634
}
631635
}
632636

@@ -635,28 +639,25 @@ func (bb *BlocksBackend) GetIPNSRecord(ctx context.Context, c cid.Cid) ([]byte,
635639
return nil, NewErrorStatusCode(errors.New("IPNS Record responses are not supported by this gateway"), http.StatusNotImplemented)
636640
}
637641

638-
// Fails fast if the CID is not an encoded Libp2p Key, avoids wasteful
639-
// round trips to the remote routing provider.
640-
if mc.Code(c.Type()) != mc.Libp2pKey {
641-
return nil, NewErrorStatusCode(errors.New("cid codec must be libp2p-key"), http.StatusBadRequest)
642-
}
643-
644-
// The value store expects the key itself to be encoded as a multihash.
645-
id, err := peer.FromCid(c)
642+
name, err := ipns.NameFromCid(c)
646643
if err != nil {
647-
return nil, err
644+
return nil, NewErrorStatusCode(err, http.StatusBadRequest)
648645
}
649646

650-
return bb.routing.GetValue(ctx, "/ipns/"+string(id))
647+
return bb.routing.GetValue(ctx, string(name.RoutingKey()))
651648
}
652649

653650
func (bb *BlocksBackend) GetDNSLinkRecord(ctx context.Context, hostname string) (path.Path, error) {
654651
if bb.namesys != nil {
655-
p, err := bb.namesys.Resolve(ctx, "/ipns/"+hostname, nsopts.Depth(1))
652+
p, err := path.NewPath("/ipns/" + hostname)
653+
if err != nil {
654+
return nil, err
655+
}
656+
res, err := bb.namesys.Resolve(ctx, p, namesys.ResolveWithDepth(1))
656657
if err == namesys.ErrResolveRecursion {
657658
err = nil
658659
}
659-
return p, err
660+
return res.Path, err
660661
}
661662

662663
return nil, NewErrorStatusCode(errors.New("not implemented"), http.StatusNotImplemented)
@@ -688,10 +689,11 @@ func (bb *BlocksBackend) ResolvePath(ctx context.Context, path path.ImmutablePat
688689
func (bb *BlocksBackend) resolvePath(ctx context.Context, p path.Path) (path.ImmutablePath, []string, error) {
689690
var err error
690691
if p.Namespace() == path.IPNSNamespace {
691-
p, err = resolve.ResolveIPNS(ctx, bb.namesys, p)
692+
res, err := namesys.Resolve(ctx, bb.namesys, p)
692693
if err != nil {
693694
return path.ImmutablePath{}, nil, err
694695
}
696+
p = res.Path
695697
}
696698

697699
if p.Namespace() != path.IPFSNamespace {

gateway/gateway.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"sort"
99
"strconv"
1010
"strings"
11+
"time"
1112

1213
"github.com/ipfs/boxo/files"
1314
"github.com/ipfs/boxo/gateway/assets"
@@ -369,11 +370,11 @@ type IPFSBackend interface {
369370
GetIPNSRecord(context.Context, cid.Cid) ([]byte, error)
370371

371372
// ResolveMutable takes a mutable path and resolves it into an immutable one. This means recursively resolving any
372-
// DNSLink or IPNS records.
373+
// DNSLink or IPNS records. It should also return a TTL. If the TTL is unknown, 0 should be returned.
373374
//
374375
// For example, given a mapping from `/ipns/dnslink.tld -> /ipns/ipns-id/mydirectory` and `/ipns/ipns-id` to
375376
// `/ipfs/some-cid`, the result of passing `/ipns/dnslink.tld/myfile` would be `/ipfs/some-cid/mydirectory/myfile`.
376-
ResolveMutable(context.Context, path.Path) (path.ImmutablePath, error)
377+
ResolveMutable(context.Context, path.Path) (path.ImmutablePath, time.Duration, time.Time, error)
377378

378379
// GetDNSLinkRecord returns the DNSLink TXT record for the provided FQDN.
379380
// Unlike ResolvePath, it does not perform recursive resolution. It only

0 commit comments

Comments
 (0)