From 72f5fb8553b24eaef37b489ce8b535f39426279b Mon Sep 17 00:00:00 2001 From: "Jakub (Kubuxu) Sztandera" Date: Sat, 2 Jan 2016 00:24:54 +0100 Subject: [PATCH] namesys: Make paths with multiple segemnts work. Fixes #2059 Also fixes non-recursive resolve erring instead showing one step. The patch of core/commands/resolve.go could be done better but I don't know how to get access to ErrResolveRecursion. It allows for dnslinks into sub-segments. So for example hosting multiple blogs on just domains from one pubkey. Fixes #2059 Add tests and fix case when dnslinks references dnslink License: MIT Signed-off-by: Jakub (Kubuxu) Sztandera --- namesys/dns.go | 11 ++++++++--- namesys/dns_test.go | 9 +++++++++ namesys/namesys.go | 10 +++++++--- namesys/routing.go | 2 +- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/namesys/dns.go b/namesys/dns.go index 3703bd8d01de..d74213e93523 100644 --- a/namesys/dns.go +++ b/namesys/dns.go @@ -45,12 +45,14 @@ func (r *DNSResolver) ResolveN(ctx context.Context, name string, depth int) (pat // TXT records for a given domain name should contain a b58 // encoded multihash. func (r *DNSResolver) resolveOnce(ctx context.Context, name string) (path.Path, error) { - if !isd.IsDomain(name) { + segments := strings.SplitN(name, "/", 2) + + if !isd.IsDomain(segments[0]) { return "", errors.New("not a valid domain name") } - log.Infof("DNSResolver resolving %s", name) - txt, err := r.lookupTXT(name) + log.Infof("DNSResolver resolving %s", segments[0]) + txt, err := r.lookupTXT(segments[0]) if err != nil { return "", err } @@ -58,6 +60,9 @@ func (r *DNSResolver) resolveOnce(ctx context.Context, name string) (path.Path, for _, t := range txt { p, err := parseEntry(t) if err == nil { + if len(segments) > 1 { + return path.FromSegments(p.String() + "/", segments[1]) + } return p, nil } } diff --git a/namesys/dns_test.go b/namesys/dns_test.go index 40bf702c35c2..a1e4ce4420a5 100644 --- a/namesys/dns_test.go +++ b/namesys/dns_test.go @@ -18,6 +18,7 @@ func (m *mockDNS) lookupTXT(name string) (txt []string, err error) { } func TestDnsEntryParsing(t *testing.T) { + goodEntries := []string{ "QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD", @@ -86,6 +87,12 @@ func newMockDNS() *mockDNS { "bad.example.com": []string{ "dnslink=", }, + "withsegment.example.com": []string{ + "dnslink=/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment", + }, + "withrecsegment.example.com": []string{ + "dnslink=/ipns/withsegment.example.com/subsub", + }, }, } } @@ -109,4 +116,6 @@ func TestDNSResolution(t *testing.T) { testResolution(t, r, "loop1.example.com", 3, "/ipns/loop2.example.com", ErrResolveRecursion) testResolution(t, r, "loop1.example.com", DefaultDepthLimit, "/ipns/loop1.example.com", ErrResolveRecursion) testResolution(t, r, "bad.example.com", DefaultDepthLimit, "", ErrResolveFailed) + testResolution(t, r, "withsegment.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment", nil) + testResolution(t, r, "withrecsegment.example.com", DefaultDepthLimit, "/ipfs/QmY3hE8xgFCjGcz6PHgnvJz5HZi1BaKRfPkn1ghZUcYMjD/sub/segment/subsub", nil) } diff --git a/namesys/namesys.go b/namesys/namesys.go index c61d3496bde1..b375a5c04e88 100644 --- a/namesys/namesys.go +++ b/namesys/namesys.go @@ -64,17 +64,21 @@ func (ns *mpns) resolveOnce(ctx context.Context, name string) (path.Path, error) if !strings.HasPrefix(name, "/ipns/") { name = "/ipns/" + name } - segments := strings.SplitN(name, "/", 3) + segments := strings.SplitN(name, "/", 4) if len(segments) < 3 || segments[0] != "" { log.Warningf("Invalid name syntax for %s", name) return "", ErrResolveFailed } for protocol, resolver := range ns.resolvers { - log.Debugf("Attempting to resolve %s with %s", name, protocol) + log.Debugf("Attempting to resolve %s with %s", segments[2], protocol) p, err := resolver.resolveOnce(ctx, segments[2]) if err == nil { - return p, err + if len(segments) > 3 { + return path.FromSegments(p.String() + "/", segments[3]) + } else { + return p, err + } } } log.Warningf("No resolver found for %s", name) diff --git a/namesys/routing.go b/namesys/routing.go index 85ef498e7496..5f9e3bc87e9b 100644 --- a/namesys/routing.go +++ b/namesys/routing.go @@ -123,7 +123,7 @@ func (r *routingResolver) resolveOnce(ctx context.Context, name string) (path.Pa hash, err := mh.FromB58String(name) if err != nil { - log.Warning("RoutingResolve: bad input hash: [%s]\n", name) + log.Warningf("RoutingResolve: bad input hash: [%s]\n", name) return "", err } // name should be a multihash. if it isn't, error out here.