master
sh 239 lines 12.6 KB
Raw
1 #!/usr/bin/env bash
2
3 test_description="Test HTTP Gateway _redirects support"
4
5 . lib/test-lib.sh
6
7 test_init_ipfs
8 test_launch_ipfs_daemon
9
10 ## ============================================================================
11 ## Test _redirects file support
12 ## ============================================================================
13
14 # Import test case
15 # Run `ipfs cat /ipfs/$REDIRECTS_DIR_CID/_redirects` to see sample _redirects file
16 test_expect_success "Add the _redirects file test directory" '
17 ipfs dag import --pin-roots ../t0109-gateway-web-_redirects-data/redirects.car
18 '
19 CAR_ROOT_CID=QmQyqMY5vUBSbSxyitJqthgwZunCQjDVtNd8ggVCxzuPQ4
20
21 REDIRECTS_DIR_CID=$(ipfs resolve -r /ipfs/$CAR_ROOT_CID/examples | cut -d "/" -f3)
22 REDIRECTS_DIR_HOSTNAME="${REDIRECTS_DIR_CID}.ipfs.localhost:$GWAY_PORT"
23
24 test_expect_success "request for $REDIRECTS_DIR_HOSTNAME/redirect-one redirects with default of 301, per _redirects file" '
25 curl -sD - --resolve $REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$REDIRECTS_DIR_HOSTNAME/redirect-one" > response &&
26 test_should_contain "301 Moved Permanently" response &&
27 test_should_contain "Location: /one.html" response
28 '
29
30 test_expect_success "request for $REDIRECTS_DIR_HOSTNAME/301-redirect-one redirects with 301, per _redirects file" '
31 curl -sD - --resolve $REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$REDIRECTS_DIR_HOSTNAME/301-redirect-one" > response &&
32 test_should_contain "301 Moved Permanently" response &&
33 test_should_contain "Location: /one.html" response
34 '
35
36 test_expect_success "request for $REDIRECTS_DIR_HOSTNAME/302-redirect-two redirects with 302, per _redirects file" '
37 curl -sD - --resolve $REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$REDIRECTS_DIR_HOSTNAME/302-redirect-two" > response &&
38 test_should_contain "302 Found" response &&
39 test_should_contain "Location: /two.html" response
40 '
41
42 test_expect_success "request for $REDIRECTS_DIR_HOSTNAME/200-index returns 200, per _redirects file" '
43 curl -sD - --resolve $REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$REDIRECTS_DIR_HOSTNAME/200-index" > response &&
44 test_should_contain "my index" response &&
45 test_should_contain "200 OK" response
46 '
47
48 test_expect_success "request for $REDIRECTS_DIR_HOSTNAME/posts/:year/:month/:day/:title redirects with 301 and placeholders, per _redirects file" '
49 curl -sD - --resolve $REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$REDIRECTS_DIR_HOSTNAME/posts/2022/01/01/hello-world" > response &&
50 test_should_contain "301 Moved Permanently" response &&
51 test_should_contain "Location: /articles/2022/01/01/hello-world" response
52 '
53
54 test_expect_success "request for $REDIRECTS_DIR_HOSTNAME/splat/one.html redirects with 301 and splat placeholder, per _redirects file" '
55 curl -sD - --resolve $REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$REDIRECTS_DIR_HOSTNAME/splat/one.html" > response &&
56 test_should_contain "301 Moved Permanently" response &&
57 test_should_contain "Location: /redirected-splat/one.html" response
58 '
59
60 # ensure custom 4xx works and has the same cache headers as regular /ipfs/ path
61 CUSTOM_4XX_CID=$(ipfs resolve -r /ipfs/$CAR_ROOT_CID/examples/404.html | cut -d "/" -f3)
62 test_expect_success "request for $REDIRECTS_DIR_HOSTNAME/not-found/has-no-redirects-entry returns custom 404, per _redirects file" '
63 curl -sD - --resolve $REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$REDIRECTS_DIR_HOSTNAME/not-found/has-no-redirects-entry" > response &&
64 test_should_contain "404 Not Found" response &&
65 test_should_contain "Cache-Control: public, max-age=29030400, immutable" response &&
66 test_should_contain "Etag: \"$CUSTOM_4XX_CID\"" response &&
67 test_should_contain "my 404" response
68 '
69
70 CUSTOM_4XX_CID=$(ipfs resolve -r /ipfs/$CAR_ROOT_CID/examples/410.html | cut -d "/" -f3)
71 test_expect_success "request for $REDIRECTS_DIR_HOSTNAME/gone/has-no-redirects-entry returns custom 410, per _redirects file" '
72 curl -sD - --resolve $REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$REDIRECTS_DIR_HOSTNAME/gone/has-no-redirects-entry" > response &&
73 test_should_contain "410 Gone" response &&
74 test_should_contain "Cache-Control: public, max-age=29030400, immutable" response &&
75 test_should_contain "Etag: \"$CUSTOM_4XX_CID\"" response &&
76 test_should_contain "my 410" response
77 '
78
79 CUSTOM_4XX_CID=$(ipfs resolve -r /ipfs/$CAR_ROOT_CID/examples/451.html | cut -d "/" -f3)
80 test_expect_success "request for $REDIRECTS_DIR_HOSTNAME/unavail/has-no-redirects-entry returns custom 451, per _redirects file" '
81 curl -sD - --resolve $REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$REDIRECTS_DIR_HOSTNAME/unavail/has-no-redirects-entry" > response &&
82 test_should_contain "451 Unavailable For Legal Reasons" response &&
83 test_should_contain "Cache-Control: public, max-age=29030400, immutable" response &&
84 test_should_contain "Etag: \"$CUSTOM_4XX_CID\"" response &&
85 test_should_contain "my 451" response
86 '
87
88 test_expect_success "request for $REDIRECTS_DIR_HOSTNAME/catch-all returns 200, per _redirects file" '
89 curl -sD - --resolve $REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$REDIRECTS_DIR_HOSTNAME/catch-all" > response &&
90 test_should_contain "200 OK" response &&
91 test_should_contain "my index" response
92 '
93
94 # This test ensures _redirects is supported only on Web Gateways that use Host header (DNSLink, Subdomain)
95 test_expect_success "request for http://127.0.0.1:$GWAY_PORT/ipfs/$REDIRECTS_DIR_CID/301-redirect-one returns generic 404 (no custom 404 from _redirects since no origin isolation)" '
96 curl -sD - "http://127.0.0.1:$GWAY_PORT/ipfs/$REDIRECTS_DIR_CID/301-redirect-one" > response &&
97 test_should_contain "404 Not Found" response &&
98 test_should_not_contain "my 404" response
99 '
100
101 # With CRLF line terminator
102 NEWLINE_REDIRECTS_DIR_CID=$(ipfs resolve -r /ipfs/$CAR_ROOT_CID/newlines | cut -d "/" -f3)
103 NEWLINE_REDIRECTS_DIR_HOSTNAME="${NEWLINE_REDIRECTS_DIR_CID}.ipfs.localhost:$GWAY_PORT"
104
105 test_expect_success "newline: _redirects has CRLF line terminators" '
106 ipfs cat /ipfs/$NEWLINE_REDIRECTS_DIR_CID/_redirects | file - > response &&
107 test_should_contain "with CRLF line terminators" response
108 '
109
110 test_expect_success "newline: request for $NEWLINE_REDIRECTS_DIR_HOSTNAME/redirect-one redirects with default of 301, per _redirects file" '
111 curl -sD - --resolve $NEWLINE_REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$NEWLINE_REDIRECTS_DIR_HOSTNAME/redirect-one" > response &&
112 test_should_contain "301 Moved Permanently" response &&
113 test_should_contain "Location: /one.html" response
114 '
115
116 # Good codes
117 GOOD_REDIRECTS_DIR_CID=$(ipfs resolve -r /ipfs/$CAR_ROOT_CID/good-codes | cut -d "/" -f3)
118 GOOD_REDIRECTS_DIR_HOSTNAME="${GOOD_REDIRECTS_DIR_CID}.ipfs.localhost:$GWAY_PORT"
119
120 test_expect_success "good codes: request for $GOOD_REDIRECTS_DIR_HOSTNAME/redirect-one redirects with default of 301, per _redirects file" '
121 curl -sD - --resolve $GOOD_REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$GOOD_REDIRECTS_DIR_HOSTNAME/a301" > response &&
122 test_should_contain "301 Moved Permanently" response &&
123 test_should_contain "Location: /b301" response
124 '
125
126 # Bad codes
127 BAD_REDIRECTS_DIR_CID=$(ipfs resolve -r /ipfs/$CAR_ROOT_CID/bad-codes | cut -d "/" -f3)
128 BAD_REDIRECTS_DIR_HOSTNAME="${BAD_REDIRECTS_DIR_CID}.ipfs.localhost:$GWAY_PORT"
129
130 # if accessing a path that doesn't exist, read _redirects and fail parsing, and return error
131 test_expect_success "bad codes: request for $BAD_REDIRECTS_DIR_HOSTNAME/not-found returns error about bad code" '
132 curl -sD - --resolve $BAD_REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$BAD_REDIRECTS_DIR_HOSTNAME/not-found" > response &&
133 test_should_contain "500" response &&
134 test_should_contain "status code 999 is not supported" response
135 '
136
137 # if accessing a path that does exist, don't read _redirects and therefore don't fail parsing
138 test_expect_success "bad codes: request for $BAD_REDIRECTS_DIR_HOSTNAME/found.html doesn't return error about bad code" '
139 curl -sD - --resolve $BAD_REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$BAD_REDIRECTS_DIR_HOSTNAME/found.html" > response &&
140 test_should_contain "200" response &&
141 test_should_contain "my found" response &&
142 test_should_not_contain "unsupported redirect status" response
143 '
144
145 # Invalid file, containing "hello"
146 INVALID_REDIRECTS_DIR_CID=$(ipfs resolve -r /ipfs/$CAR_ROOT_CID/invalid | cut -d "/" -f3)
147 INVALID_REDIRECTS_DIR_HOSTNAME="${INVALID_REDIRECTS_DIR_CID}.ipfs.localhost:$GWAY_PORT"
148
149 # if accessing a path that doesn't exist, read _redirects and fail parsing, and return error
150 test_expect_success "invalid file: request for $INVALID_REDIRECTS_DIR_HOSTNAME/not-found returns error about invalid redirects file" '
151 curl -sD - --resolve $INVALID_REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$INVALID_REDIRECTS_DIR_HOSTNAME/not-found" > response &&
152 test_should_contain "500" response &&
153 test_should_contain "could not parse _redirects:" response
154 '
155
156 # Invalid file, containing forced redirect
157 INVALID_REDIRECTS_DIR_CID=$(ipfs resolve -r /ipfs/$CAR_ROOT_CID/forced | cut -d "/" -f3)
158 INVALID_REDIRECTS_DIR_HOSTNAME="${INVALID_REDIRECTS_DIR_CID}.ipfs.localhost:$GWAY_PORT"
159
160 # if accessing a path that doesn't exist, read _redirects and fail parsing, and return error
161 test_expect_success "invalid file: request for $INVALID_REDIRECTS_DIR_HOSTNAME/not-found returns error about invalid redirects file" '
162 curl -sD - --resolve $INVALID_REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$INVALID_REDIRECTS_DIR_HOSTNAME/not-found" > response &&
163 test_should_contain "500" response &&
164 test_should_contain "could not parse _redirects:" response &&
165 test_should_contain "forced redirects (or \"shadowing\") are not supported" response
166 '
167
168 # if accessing a path that doesn't exist and _redirects file is too large, return error
169 TOO_LARGE_REDIRECTS_DIR_CID=$(ipfs resolve -r /ipfs/$CAR_ROOT_CID/too-large | cut -d "/" -f3)
170 TOO_LARGE_REDIRECTS_DIR_HOSTNAME="${TOO_LARGE_REDIRECTS_DIR_CID}.ipfs.localhost:$GWAY_PORT"
171 test_expect_success "invalid file: request for $TOO_LARGE_REDIRECTS_DIR_HOSTNAME/not-found returns error about too large redirects file" '
172 curl -sD - --resolve $TOO_LARGE_REDIRECTS_DIR_HOSTNAME:127.0.0.1 "http://$TOO_LARGE_REDIRECTS_DIR_HOSTNAME/not-found" > response &&
173 test_should_contain "500" response &&
174 test_should_contain "could not parse _redirects:" response &&
175 test_should_contain "redirects file size cannot exceed" response
176 '
177
178 test_kill_ipfs_daemon
179
180 # disable wildcard DNSLink gateway
181 # and enable it on specific DNSLink hostname
182 ipfs config --json Gateway.NoDNSLink true && \
183 ipfs config --json Gateway.PublicGateways '{
184 "dnslink-enabled-on-fqdn.example.org": {
185 "NoDNSLink": false,
186 "UseSubdomains": false,
187 "Paths": ["/ipfs"]
188 },
189 "dnslink-disabled-on-fqdn.example.com": {
190 "NoDNSLink": true,
191 "UseSubdomains": false,
192 "Paths": []
193 }
194 }' || exit 1
195
196 # DNSLink test requires a daemon in online mode with precached /ipns/ mapping
197 # REDIRECTS_DIR_CID=$(ipfs resolve -r /ipfs/$CAR_ROOT_CID/examples | cut -d "/" -f3)
198 DNSLINK_FQDN="dnslink-enabled-on-fqdn.example.org"
199 NO_DNSLINK_FQDN="dnslink-disabled-on-fqdn.example.com"
200 export IPFS_NS_MAP="$DNSLINK_FQDN:/ipfs/$REDIRECTS_DIR_CID"
201
202 # restart daemon to apply config changes
203 test_launch_ipfs_daemon
204
205 # make sure test setup is valid (fail if CoreAPI is unable to resolve)
206 test_expect_success "spoofed DNSLink record resolves in cli" "
207 ipfs resolve /ipns/$DNSLINK_FQDN > result &&
208 test_should_contain \"$REDIRECTS_DIR_CID\" result &&
209 ipfs cat /ipns/$DNSLINK_FQDN/_redirects > result &&
210 test_should_contain \"index.html\" result
211 "
212
213 test_expect_success "request for $DNSLINK_FQDN/redirect-one redirects with default of 301, per _redirects file" '
214 curl -sD - --resolve $DNSLINK_FQDN:$GWAY_PORT:127.0.0.1 "http://$DNSLINK_FQDN:$GWAY_PORT/redirect-one" > response &&
215 test_should_contain "301 Moved Permanently" response &&
216 test_should_contain "Location: /one.html" response
217 '
218
219 # ensure custom 404 works and has the same cache headers as regular /ipns/ paths
220 test_expect_success "request for $DNSLINK_FQDN/en/has-no-redirects-entry returns custom 404, per _redirects file" '
221 curl -sD - --resolve $DNSLINK_FQDN:$GWAY_PORT:127.0.0.1 "http://$DNSLINK_FQDN:$GWAY_PORT/not-found/has-no-redirects-entry" > response &&
222 test_should_contain "404 Not Found" response &&
223 test_should_contain "Etag: \"Qmd9GD7Bauh6N2ZLfNnYS3b7QVAijbud83b8GE8LPMNBBP\"" response &&
224 test_should_not_contain "Cache-Control: public, max-age=29030400, immutable" response &&
225 test_should_not_contain "immutable" response &&
226 test_should_contain "Date: " response &&
227 test_should_contain "my 404" response
228 '
229
230 test_expect_success "request for $NO_DNSLINK_FQDN/redirect-one does not redirect, since DNSLink is disabled" '
231 curl -sD - --resolve $NO_DNSLINK_FQDN:$GWAY_PORT:127.0.0.1 "http://$NO_DNSLINK_FQDN:$GWAY_PORT/redirect-one" > response &&
232 test_should_not_contain "one.html" response &&
233 test_should_not_contain "301 Moved Permanently" response &&
234 test_should_not_contain "Location:" response
235 '
236
237 test_kill_ipfs_daemon
238
239 test_done