@cryptotaxi247 / kubo / commits / 3ed46d995

test(gw): add t0115-gateway-dir-listing.sh to sharness

This adds proper end-to-end tests for directory listing on Gateway port that protects us against regressions oni each gw type: - path gateway - subdomain gateway - dnslink website gateway Tests cover: - etag/unicode support - breadcrumbs - file name column - hash column

Marcin Rataj committed Sep 29, 2020 at 02:27 UTC 3ed46d995fee555f924b9163e491e37845ad8818
5 files changed +161 -8
core/corehttp/gateway_handler.go
-4
@@ -405,10 +405,6 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
405 Hash: hash,
406 }
407
408 - // TODO: remove logging below
409 - // tplDataJSON, _ := json.MarshalIndent(tplData, "", " ")
410 - // fmt.Println(string(tplDataJSON))
411 -
408 err = listingTemplate.Execute(w, tplData)
409 if err != nil {
410 internalWebError(w, err)
core/corehttp/gateway_indexPage.go
+2 -2
@@ -82,8 +82,8 @@ func shortHash(hash string) string {
82 // (when hostname from gwURL is matching /ipns/<fqdn> in path)
83 func hasDNSLinkOrigin(gwURL string, path string) bool {
84 if gwURL != "" {
85 - dnslinkRoot := strings.Replace(gwURL, "//", "/ipns/", 1)
86 - return strings.HasPrefix(path, dnslinkRoot)
85 + fqdn := stripPort(strings.TrimPrefix(gwURL, "//"))
86 + return strings.HasPrefix(path, "/ipns/"+fqdn)
87 }
88 return false
89 }
core/corehttp/gateway_test.go
+11 -1
@@ -393,6 +393,8 @@ func TestIPNSHostnameRedirect(t *testing.T) {
393
394 // Test directory listing on DNSLink website
395 // (scenario when Host header is the same as URL hostname)
396 +// This is basic regression test: additional end-to-end tests
397 +// can be found in test/sharness/t0115-gateway-dir-listing.sh
398 func TestIPNSHostnameBacklinks(t *testing.T) {
399 ns := mockNamesys{}
400 ts, api, ctx := newTestServerAndNode(t, ns)
@@ -439,7 +441,7 @@ func TestIPNSHostnameBacklinks(t *testing.T) {
441 t.Fatal(err)
442 }
443
442 - // expect correct backlinks
444 + // expect correct links
445 body, err := ioutil.ReadAll(res.Body)
446 if err != nil {
447 t.Fatalf("error reading response: %s", err)
@@ -456,6 +458,10 @@ func TestIPNSHostnameBacklinks(t *testing.T) {
458 if !strings.Contains(s, "<a href=\"/foo%3F%20%23%3C%27/file.txt\">") {
459 t.Fatalf("expected file in directory listing")
460 }
461 + if !strings.Contains(s, "<a class=\"ipfs-hash\" href=\"https://cid.ipfs.io/#") {
462 + // https://github.com/ipfs/dir-index-html/issues/42
463 + t.Fatalf("expected links to cid.ipfs.io in CID column when on DNSLink website")
464 + }
465 if !strings.Contains(s, k2.Cid().String()) {
466 t.Fatalf("expected hash in directory listing")
467 }
@@ -489,6 +495,10 @@ func TestIPNSHostnameBacklinks(t *testing.T) {
495 if !strings.Contains(s, "<a href=\"/file.txt\">") {
496 t.Fatalf("expected file in directory listing")
497 }
498 + if !strings.Contains(s, "<a class=\"ipfs-hash\" href=\"https://cid.ipfs.io/#") {
499 + // https://github.com/ipfs/dir-index-html/issues/42
500 + t.Fatalf("expected links to cid.ipfs.io in CID column when on DNSLink website")
501 + }
502 if !strings.Contains(s, k.Cid().String()) {
503 t.Fatalf("expected hash in directory listing")
504 }
test/sharness/t0114-gateway-subdomains.sh
+2 -1
@@ -432,7 +432,8 @@ test_expect_success "valid parent directory path in directory listing at {cid}.i
432 test_should_contain "<a href=\"/ipfs/ipns/bar\">bar</a>" list_response
433 '
434
435 -# Note we test for sneaky subdir names {cid}.ipfs.example.com/ipfs/ipns/ :^)
435 +# Note 1: we test for sneaky subdir names {cid}.ipfs.example.com/ipfs/ipns/ :^)
436 +# Note 2: example.com/ipfs/.. present in HTML will be redirected to subdomain, so this is expected behavior
437 test_expect_success "valid breadcrumb links in the header of directory listing at {cid}.ipfs.example.com/sub/dir" '
438 curl -s -H "Host: $DIR_FQDN" http://127.0.0.1:$GWAY_PORT/ipfs/ipns/ > list_response &&
439 test_should_contain "Index of" list_response &&
test/sharness/t0115-gateway-dir-listing.sh new
+146
@@ -0,0 +1,146 @@
1 +#!/usr/bin/env bash
2 +#
3 +# Copyright (c) Protocol Labs
4 +
5 +test_description="Test directory listing (dir-index-html) on the HTTP gateway"
6 +
7 +
8 +. lib/test-lib.sh
9 +
10 +## ============================================================================
11 +## Start IPFS Node and prepare test CIDs
12 +## ============================================================================
13 +
14 +test_expect_success "ipfs init" '
15 + export IPFS_PATH="$(pwd)/.ipfs" &&
16 + ipfs init --profile=test > /dev/null
17 +'
18 +
19 +test_launch_ipfs_daemon --offline
20 +
21 +test_expect_success "Add the test directory" '
22 + mkdir -p rootDir/ipfs &&
23 + mkdir -p rootDir/ipns &&
24 + mkdir -p rootDir/api &&
25 + mkdir -p rootDir/ą/ę &&
26 + echo "I am a txt file on path with utf8" > rootDir/ą/ę/file-źł.txt &&
27 + echo "I am a txt file in confusing /api dir" > rootDir/api/file.txt &&
28 + echo "I am a txt file in confusing /ipfs dir" > rootDir/ipfs/file.txt &&
29 + echo "I am a txt file in confusing /ipns dir" > rootDir/ipns/file.txt &&
30 + DIR_CID=$(ipfs add -Qr --cid-version 1 rootDir) &&
31 + FILE_CID=$(ipfs files stat /ipfs/$DIR_CID/ą/ę/file-źł.txt | head -1)
32 +'
33 +
34 +## ============================================================================
35 +## Test dir listing on path gateway (eg. 127.0.0.1:8080/ipfs/)
36 +## ============================================================================
37 +
38 +test_expect_success "path gw: backlink on root CID should point at self" '
39 + curl -sD - http://127.0.0.1:$GWAY_PORT/ipfs/${DIR_CID}/ > list_response &&
40 + test_should_contain "Index of" list_response &&
41 + test_should_contain "<a href=\"/ipfs/$DIR_CID/\">..</a>" list_response
42 +'
43 +
44 +test_expect_success "path gw: Etag should be present" '
45 + curl -sD - http://127.0.0.1:$GWAY_PORT/ipfs/${DIR_CID}/ą/ę > list_response &&
46 + test_should_contain "Index of" list_response &&
47 + test_should_contain "Etag: \"DirIndex-" list_response
48 +'
49 +
50 +test_expect_success "path gw: breadcrumbs should point at /ipfs namespace mounted at Origin root" '
51 + test_should_contain "/ipfs/<a href=\"/ipfs/$DIR_CID\">$DIR_CID</a>/<a href=\"/ipfs/$DIR_CID/%C4%85\">ą</a>/<a href=\"/ipfs/$DIR_CID/%C4%85/%C4%99\">ę</a>" list_response
52 +'
53 +
54 +test_expect_success "path gw: backlink should point at parent directory" '
55 + test_should_contain "<a href=\"/ipfs/$DIR_CID/%C4%85/%C4%99/..\">..</a>" list_response
56 +'
57 +
58 +test_expect_success "path gw: name column should be a link to its content path" '
59 + test_should_contain "<a href=\"/ipfs/$DIR_CID/%C4%85/%C4%99/file-%C5%BA%C5%82.txt\">file-źł.txt</a>" list_response
60 +'
61 +
62 +test_expect_success "path gw: hash column should be a CID link with filename param" '
63 + test_should_contain "<a class=\"ipfs-hash\" href=\"/ipfs/$FILE_CID?filename=file-%25C5%25BA%25C5%2582.txt\">" list_response
64 +'
65 +
66 +## ============================================================================
67 +## Test dir listing on subdomain gateway (eg. <cid>.ipfs.localhost:8080)
68 +## ============================================================================
69 +
70 +DIR_HOSTNAME="${DIR_CID}.ipfs.localhost"
71 +# note: we skip DNS lookup by running curl with --resolve $DIR_HOSTNAME:127.0.0.1
72 +
73 +test_expect_success "path gw: backlink on root CID should point origin root" '
74 + curl -sD - --resolve $DIR_HOSTNAME:127.0.0.1 http://$DIR_HOSTNAME:$GWAY_PORT/ > list_response &&
75 + test_should_contain "Index of" list_response &&
76 + test_should_contain "<a href=\"/\">..</a>" list_response
77 +'
78 +
79 +test_expect_success "path gw: Etag should be present" '
80 + curl -sD - --resolve $DIR_HOSTNAME:127.0.0.1 http://$DIR_HOSTNAME:$GWAY_PORT/ą/ę > list_response &&
81 + test_should_contain "Index of" list_response &&
82 + test_should_contain "Etag: \"DirIndex-" list_response
83 +'
84 +
85 +test_expect_success "subdomain gw: breadcrumbs should leverage path-based router mounted on the parent domain" '
86 + test_should_contain "/ipfs/<a href=\"//localhost:$GWAY_PORT/ipfs/$DIR_CID\">$DIR_CID</a>/<a href=\"//localhost:$GWAY_PORT/ipfs/$DIR_CID/%C4%85\">ą</a>/<a href=\"//localhost:$GWAY_PORT/ipfs/$DIR_CID/%C4%85/%C4%99\">ę</a>" list_response
87 +'
88 +
89 +test_expect_success "path gw: name column should be a link to content root mounted at subdomain origin" '
90 + test_should_contain "<a href=\"/%C4%85/%C4%99/file-%C5%BA%C5%82.txt\">file-źł.txt</a>" list_response
91 +'
92 +
93 +test_expect_success "path gw: hash column should be a CID link to path router with filename param" '
94 + test_should_contain "<a class=\"ipfs-hash\" href=\"//localhost:$GWAY_PORT/ipfs/$FILE_CID?filename=file-%25C5%25BA%25C5%2582.txt\">" list_response
95 +'
96 +
97 +## ============================================================================
98 +## Test dir listing on DNSLink gateway (eg. example.com)
99 +## ============================================================================
100 +
101 +# DNSLink test requires a daemon in online mode with precached /ipns/ mapping
102 +test_kill_ipfs_daemon
103 +DNSLINK_HOSTNAME="website.example.com"
104 +export IPFS_NS_MAP="$DNSLINK_HOSTNAME:/ipfs/$DIR_CID"
105 +test_launch_ipfs_daemon
106 +
107 +# Note that:
108 +# - this type of gateway is also tested in gateway_test.go#TestIPNSHostnameBacklinks
109 +# (go tests and sharness tests should be kept in sync)
110 +# - we skip DNS lookup by running curl with --resolve $DNSLINK_HOSTNAME:127.0.0.1
111 +
112 +test_expect_success "dnslink gw: backlink on root CID should point origin root" '
113 + curl -v -sD - --resolve $DNSLINK_HOSTNAME:$GWAY_PORT:127.0.0.1 http://$DNSLINK_HOSTNAME:$GWAY_PORT/ > list_response &&
114 + test_should_contain "Index of" list_response &&
115 + test_should_contain "<a href=\"/\">..</a>" list_response
116 +'
117 +
118 +test_expect_success "dnslink gw: Etag should be present" '
119 + curl -sD - --resolve $DNSLINK_HOSTNAME:$GWAY_PORT:127.0.0.1 http://$DNSLINK_HOSTNAME:$GWAY_PORT/ą/ę > list_response &&
120 + test_should_contain "Index of" list_response &&
121 + test_should_contain "Etag: \"DirIndex-" list_response
122 +'
123 +
124 +test_expect_success "dnslink gw: breadcrumbs should point at content root mounted at dnslink origin" '
125 + test_should_contain "/ipns/<a href=\"//$DNSLINK_HOSTNAME:$GWAY_PORT/\">website.example.com</a>/<a href=\"//$DNSLINK_HOSTNAME:$GWAY_PORT/%C4%85\">ą</a>/<a href=\"//$DNSLINK_HOSTNAME:$GWAY_PORT/%C4%85/%C4%99\">ę</a>" list_response
126 +'
127 +
128 +test_expect_success "dnslink gw: name column should be a link to content root mounted at dnslink origin" '
129 + test_should_contain "<a href=\"/%C4%85/%C4%99/file-%C5%BA%C5%82.txt\">file-źł.txt</a>" list_response
130 +'
131 +
132 +# DNSLink websites don't have public gateway mounted by default
133 +# See: https://github.com/ipfs/dir-index-html/issues/42
134 +test_expect_success "dnslink gw: hash column should be a CID link to cid.ipfs.io" '
135 + test_should_contain "<a class=\"ipfs-hash\" href=\"https://cid.ipfs.io/#$FILE_CID\" target=\"_blank\" rel=\"noreferrer noopener\">" list_response
136 +'
137 +
138 +## ============================================================================
139 +## End of tests, cleanup
140 +## ============================================================================
141 +
142 +test_kill_ipfs_daemon
143 +test_expect_success "clean up ipfs dir" '
144 + rm -rf "$IPFS_PATH"
145 +'
146 +test_done