Skip to content

Commit e688ad9

Browse files
committed
refactor: do not assume namespaces
1 parent 0e88cb9 commit e688ad9

5 files changed

Lines changed: 27 additions & 43 deletions

File tree

namesys/dns.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
opts "github.com/ipfs/boxo/coreiface/options/namesys"
1212
path "github.com/ipfs/boxo/path"
13+
"github.com/ipfs/go-cid"
1314
dns "github.com/miekg/dns"
1415
"go.opentelemetry.io/otel/attribute"
1516
"go.opentelemetry.io/otel/trace"
@@ -177,6 +178,11 @@ func workDomain(ctx context.Context, r *DNSResolver, name string, res chan looku
177178
}
178179

179180
func parseEntry(txt string) (path.Path, error) {
181+
if cid, err := cid.Decode(txt); err == nil {
182+
// Support legacy DNSLink records that do not start with dnslink=
183+
return path.NewIPFSPath(cid), nil
184+
}
185+
180186
p, err := path.NewPath(txt) // bare IPFS multihashes
181187
if err == nil {
182188
return p, nil
@@ -188,6 +194,12 @@ func parseEntry(txt string) (path.Path, error) {
188194
func tryParseDNSLink(txt string) (path.Path, error) {
189195
parts := strings.SplitN(txt, "=", 2)
190196
if len(parts) == 2 && parts[0] == "dnslink" {
197+
if cid, err := cid.Decode(parts[1]); err == nil {
198+
// Support legacy DNSLink records that do not contain a namespace
199+
// at the beginning of the path.
200+
return path.NewIPFSPath(cid), nil
201+
}
202+
191203
return path.NewPath(parts[1])
192204
}
193205

namesys/namesys_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func TestPublishWithCache0(t *testing.T) {
119119
}
120120

121121
// CID is arbitrary.
122-
p, err := path.NewPath("QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn")
122+
p, err := path.NewPath("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn")
123123
if err != nil {
124124
t.Fatal(err)
125125
}
@@ -159,7 +159,7 @@ func TestPublishWithTTL(t *testing.T) {
159159
}
160160

161161
// CID is arbitrary.
162-
p, err := path.NewPath("QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn")
162+
p, err := path.NewPath("/ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn")
163163
if err != nil {
164164
t.Fatal(err)
165165
}

path/path.go

Lines changed: 9 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ func (ip ImmutablePath) Segments() []string {
103103
return ip.path.Segments()
104104
}
105105

106+
var _ Path = path{}
107+
106108
type path struct {
107109
str string
108110
root cid.Cid
@@ -133,6 +135,8 @@ func (p path) Segments() []string {
133135
return strings.Split(str, "/")
134136
}
135137

138+
var _ ResolvedPath = resolvedPath{}
139+
136140
type resolvedPath struct {
137141
path
138142
cid cid.Cid
@@ -174,6 +178,9 @@ func NewIPLDPath(cid cid.Cid) ResolvedPath {
174178
}
175179

176180
// NewIPNSPath returns a new "/ipns" path with the provided CID.
181+
// TODO: it is better to use [ipns.Name], but that leads to import cycle. Maybe
182+
// this specific function could be moved to the iPNS package? It'sn an IPNS path
183+
// after all.
177184
func NewIPNSPath(cid cid.Cid) Path {
178185
return &path{
179186
str: fmt.Sprintf("/%s/%s", IPNSNamespace, cid.String()),
@@ -191,16 +198,8 @@ func NewDNSLinkPath(domain string) Path {
191198
}
192199

193200
// NewPath returns a well-formed [Path]. The returned path will always be prefixed
194-
// with a valid namespace (/ipfs, /ipld, or /ipns). The prefix will be added if not
195-
// present in the given string. The rules are:
196-
//
197-
// 1. If the path has a single component (no slashes) ans it is a valid CID,
198-
// an /ipfs path is returned. If the CID is encoded with the Libp2pKey codec,
199-
// then a /ipns path is returned.
200-
// 2. If the path has a valid CID root but does not have a namespace, the /ipfs
201-
// namespace is automatically added.
202-
//
203-
// This function returns an error when the given string is not a valid path.
201+
// with a valid namespace (/ipfs, /ipld, or /ipns). This function returns an error
202+
// when the given string is not a valid path.
204203
func NewPath(str string) (Path, error) {
205204
cleaned := gopath.Clean(str)
206205
components := strings.Split(cleaned, "/")
@@ -210,33 +209,6 @@ func NewPath(str string) (Path, error) {
210209
cleaned += "/"
211210
}
212211

213-
// If there's only one component, check if it's a CID, or Peer ID.
214-
if len(components) == 1 {
215-
c, err := cid.Decode(components[0])
216-
if err == nil {
217-
if c.Prefix().GetCodec() == cid.Libp2pKey {
218-
return NewIPNSPath(c), nil
219-
} else {
220-
return NewIPFSPath(c), nil
221-
}
222-
}
223-
}
224-
225-
// If the path doesn't begin with a "/", we expect it to start with a CID and
226-
// be an IPFS Path.
227-
if components[0] != "" {
228-
root, err := cid.Decode(components[0])
229-
if err != nil {
230-
return nil, &ErrInvalidPath{error: err, path: str}
231-
}
232-
233-
return &path{
234-
str: cleaned,
235-
root: root,
236-
namespace: IPFSNamespace,
237-
}, nil
238-
}
239-
240212
if len(components) < 3 {
241213
return nil, &ErrInvalidPath{error: fmt.Errorf("not enough path components"), path: str}
242214
}

path/path_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ func TestPathParsing(t *testing.T) {
1616
"/ipld/QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n/a/b/c/d/e/f": true,
1717
"/ipns/QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n/a/b/c/d/e/f": true,
1818
"/ipns/QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n": true,
19-
"QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n/a/b/c/d/e/f": true,
20-
"QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n": true,
19+
"QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n/a/b/c/d/e/f": false,
20+
"QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n": false,
2121
"/QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n": false,
2222
"/QmdfTbBqBPQ7VNxZEYEj14VmRuZBkqFbiwReogJgS1zR1n/a": false,
2323
"/ipfs/foo": false,

path/resolver/resolver_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ func TestPathRemainder(t *testing.T) {
247247
fetcherFactory := bsfetcher.NewFetcherConfig(bsrv)
248248
resolver := resolver.NewBasicResolver(fetcherFactory)
249249

250-
newPath, err := path.NewPath(lnk.String() + "/foo/bar")
250+
newPath, err := path.Join(path.NewIPFSPath(lnk), "foo", "bar")
251251
require.NoError(t, err)
252252

253253
rp1, remainder, err := resolver.ResolveToLastNode(ctx, newPath)
@@ -288,7 +288,7 @@ func TestResolveToLastNode_MixedSegmentTypes(t *testing.T) {
288288
fetcherFactory := bsfetcher.NewFetcherConfig(bsrv)
289289
resolver := resolver.NewBasicResolver(fetcherFactory)
290290

291-
newPath, err := path.NewPath(lnk.String() + "/foo/bar/1/boom/3")
291+
newPath, err := path.Join(path.NewIPFSPath(lnk), "foo", "bar", "1", "boom", "3")
292292
require.NoError(t, err)
293293

294294
cid, remainder, err := resolver.ResolveToLastNode(ctx, newPath)

0 commit comments

Comments
 (0)