13 eval q{use Test::More skip_all => "IPC::Run not available"};
16 eval q{use Test::More};
23 # Black-box (ish) test for relative linking between CGI and static content
26 my ($content, $in, %bits);
28 sub parse_cgi_content {
30 if ($content =~ qr{<base href="([^"]+)" */>}) {
33 if ($content =~ qr{href="([^"]+/style.css)"}) {
34 $bits{stylehref} = $1;
36 if ($content =~ qr{class="parentlinks">\s+<a href="([^"]+)">this is the name of my wiki</a>/}s) {
39 if ($content =~ qr{<a[^>]+href="([^"]+)\?do=prefs"}) {
45 ok(! system("make -s ikiwiki.out"));
46 ok(! system("rm -rf t/tmp"));
47 ok(! system("mkdir t/tmp"));
53 writefile($name, "t/tmp/in", $content);
54 ok(utime(333333333, 333333333, "t/tmp/in/$name"));
57 write_old_file("a.mdwn", "A");
58 write_old_file("a/b.mdwn", "B");
59 write_old_file("a/b/c.mdwn",
63 write_old_file("a/d.mdwn", "D");
64 write_old_file("a/d/e.mdwn", "E");
66 #######################################################################
67 # site 1: a perfectly ordinary ikiwiki
69 writefile("test.setup", "t/tmp", <<EOF
70 # IkiWiki::Setup::Yaml - YAML formatted setup file
71 wikiname: this is the name of my wiki
74 templatedir: templates
75 url: "http://example.com/wiki/"
76 cgiurl: "http://example.com/cgi-bin/ikiwiki.cgi"
77 cgi_wrapper: t/tmp/ikiwiki.cgi
79 # make it easier to test previewing
86 ok(unlink("t/tmp/ikiwiki.cgi") || $!{ENOENT});
87 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
89 # CGI wrapper should be exactly the requested mode
90 my (undef, undef, $mode, undef, undef,
91 undef, undef, undef, undef, undef,
92 undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
93 is($mode & 07777, 0754);
95 ok(-e "t/tmp/out/a/b/c/index.html");
96 $content = readfile("t/tmp/out/a/b/c/index.html");
97 # no <base> on static HTML
98 unlike($content, qr{<base\W});
99 # url and cgiurl are on the same host so the cgiurl is host-relative
100 like($content, qr{<a[^>]+href="/cgi-bin/ikiwiki.cgi\?do=prefs"});
101 # cross-links between static pages are relative
102 like($content, qr{<li>A: <a href="../../">a</a></li>});
103 like($content, qr{<li>B: <a href="../">b</a></li>});
104 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
106 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
107 $ENV{REQUEST_METHOD} = 'GET';
108 $ENV{SERVER_PORT} = '80';
109 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
110 $ENV{QUERY_STRING} = 'do=prefs';
111 $ENV{HTTP_HOST} = 'example.com';
113 %bits = parse_cgi_content($content);
114 is($bits{basehref}, "http://example.com/wiki/");
115 like($bits{stylehref}, qr{^(?:(?:http:)?//example.com)?/wiki/style.css$});
116 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
117 like($bits{cgihref}, qr{^(?:(?:http:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
119 # when accessed via HTTPS, links are secure
120 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
121 $ENV{REQUEST_METHOD} = 'GET';
122 $ENV{SERVER_PORT} = '443';
123 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
124 $ENV{QUERY_STRING} = 'do=prefs';
125 $ENV{HTTP_HOST} = 'example.com';
128 %bits = parse_cgi_content($content);
129 is($bits{basehref}, "https://example.com/wiki/");
130 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
131 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
132 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
134 # when accessed via a different hostname, links stay on that host
135 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
136 $ENV{REQUEST_METHOD} = 'GET';
137 $ENV{SERVER_PORT} = '80';
138 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
139 $ENV{QUERY_STRING} = 'do=prefs';
140 $ENV{HTTP_HOST} = 'staging.example.net';
142 %bits = parse_cgi_content($content);
143 is($bits{basehref}, "http://staging.example.net/wiki/");
144 like($bits{stylehref}, qr{^(?:(?:http:)?//staging.example.net)?/wiki/style.css$});
145 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
146 like($bits{cgihref}, qr{^(?:(?:http:)?//staging.example.net)?/cgi-bin/ikiwiki.cgi$});
149 $in = 'do=edit&page=a/b/c&Preview';
150 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
151 $ENV{REQUEST_METHOD} = 'POST';
152 $ENV{SERVER_PORT} = '80';
153 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
154 $ENV{HTTP_HOST} = 'example.com';
155 $ENV{CONTENT_LENGTH} = length $in;
157 %bits = parse_cgi_content($content);
158 is($bits{basehref}, "http://example.com/wiki/a/b/c/");
159 like($bits{stylehref}, qr{^(?:(?:http:)?//example.com)?/wiki/style.css$});
160 like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
161 like($bits{cgihref}, qr{^(?:(?:http:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
163 #######################################################################
164 # site 2: static content and CGI are on different servers
166 writefile("test.setup", "t/tmp", <<EOF
167 # IkiWiki::Setup::Yaml - YAML formatted setup file
168 wikiname: this is the name of my wiki
171 templatedir: templates
172 url: "http://static.example.com/"
173 cgiurl: "http://cgi.example.com/ikiwiki.cgi"
174 cgi_wrapper: t/tmp/ikiwiki.cgi
175 cgi_wrappermode: 0754
176 # make it easier to test previewing
183 ok(unlink("t/tmp/ikiwiki.cgi"));
184 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
186 # CGI wrapper should be exactly the requested mode
187 (undef, undef, $mode, undef, undef,
188 undef, undef, undef, undef, undef,
189 undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
190 is($mode & 07777, 0754);
192 ok(-e "t/tmp/out/a/b/c/index.html");
193 $content = readfile("t/tmp/out/a/b/c/index.html");
194 # no <base> on static HTML
195 unlike($content, qr{<base\W});
196 # url and cgiurl are not on the same host so the cgiurl has to be
197 # protocol-relative or absolute
198 like($content, qr{<a[^>]+href="(?:http:)?//cgi.example.com/ikiwiki.cgi\?do=prefs"});
199 # cross-links between static pages are still relative
200 like($content, qr{<li>A: <a href="../../">a</a></li>});
201 like($content, qr{<li>B: <a href="../">b</a></li>});
202 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
204 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
205 $ENV{REQUEST_METHOD} = 'GET';
206 $ENV{SERVER_PORT} = '80';
207 $ENV{SCRIPT_NAME} = '/ikiwiki.cgi';
208 $ENV{QUERY_STRING} = 'do=prefs';
209 $ENV{HTTP_HOST} = 'cgi.example.com';
211 %bits = parse_cgi_content($content);
212 like($bits{basehref}, qr{^http://static.example.com/$});
213 like($bits{stylehref}, qr{^(?:(?:http:)?//static.example.com)?/style.css$});
214 like($bits{tophref}, qr{^(?:http:)?//static.example.com/$});
215 like($bits{cgihref}, qr{^(?:(?:http:)?//cgi.example.com)?/ikiwiki.cgi$});
217 # when accessed via HTTPS, links are secure
218 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
219 $ENV{REQUEST_METHOD} = 'GET';
220 $ENV{SERVER_PORT} = '443';
221 $ENV{SCRIPT_NAME} = '/ikiwiki.cgi';
222 $ENV{QUERY_STRING} = 'do=prefs';
223 $ENV{HTTP_HOST} = 'cgi.example.com';
226 %bits = parse_cgi_content($content);
228 local $TODO = "avoid mixed content";
229 like($bits{basehref}, qr{^https://static.example.com/$});
230 like($bits{stylehref}, qr{^(?:(?:https:)?//static.example.com)?/style.css$});
231 like($bits{tophref}, qr{^(?:https:)?//static.example.com/$});
232 like($bits{cgihref}, qr{^(?:(?:https:)?//cgi.example.com)?/ikiwiki.cgi$});
235 # when accessed via a different hostname, links to the CGI (only) should
237 $in = 'do=edit&page=a/b/c&Preview';
238 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
239 $ENV{REQUEST_METHOD} = 'POST';
240 $ENV{SERVER_PORT} = '80';
241 $ENV{SCRIPT_NAME} = '/ikiwiki.cgi';
242 $ENV{HTTP_HOST} = 'staging.example.net';
244 $ENV{CONTENT_LENGTH} = length $in;
246 like($bits{basehref}, qr{^http://static.example.com/$});
247 like($bits{stylehref}, qr{^(?:(?:http:)?//static.example.com)?/style.css$});
248 like($bits{tophref}, qr{^(?:http:)?//static.example.com/$});
250 local $TODO = "use self-referential CGI URL?";
251 like($bits{cgihref}, qr{^(?:(?:http:)?//staging.example.net)?/ikiwiki.cgi$});
254 #######################################################################
255 # site 3: we specifically want everything to be secure
257 writefile("test.setup", "t/tmp", <<EOF
258 # IkiWiki::Setup::Yaml - YAML formatted setup file
259 wikiname: this is the name of my wiki
262 templatedir: templates
263 url: "https://example.com/wiki/"
264 cgiurl: "https://example.com/cgi-bin/ikiwiki.cgi"
265 cgi_wrapper: t/tmp/ikiwiki.cgi
266 cgi_wrappermode: 0754
267 # make it easier to test previewing
274 ok(unlink("t/tmp/ikiwiki.cgi"));
275 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
277 # CGI wrapper should be exactly the requested mode
278 (undef, undef, $mode, undef, undef,
279 undef, undef, undef, undef, undef,
280 undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
281 is($mode & 07777, 0754);
283 ok(-e "t/tmp/out/a/b/c/index.html");
284 $content = readfile("t/tmp/out/a/b/c/index.html");
285 # no <base> on static HTML
286 unlike($content, qr{<base\W});
287 # url and cgiurl are on the same host so the cgiurl is host-relative
288 like($content, qr{<a[^>]+href="/cgi-bin/ikiwiki.cgi\?do=prefs"});
289 # cross-links between static pages are relative
290 like($content, qr{<li>A: <a href="../../">a</a></li>});
291 like($content, qr{<li>B: <a href="../">b</a></li>});
292 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
294 # when accessed via HTTPS, links are secure
295 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
296 $ENV{REQUEST_METHOD} = 'GET';
297 $ENV{SERVER_PORT} = '443';
298 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
299 $ENV{QUERY_STRING} = 'do=prefs';
300 $ENV{HTTP_HOST} = 'example.com';
303 %bits = parse_cgi_content($content);
304 is($bits{basehref}, "https://example.com/wiki/");
305 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
306 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
307 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
309 # when not accessed via HTTPS, links should still be secure
310 # (but if this happens, that's a sign of web server misconfiguration)
311 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
312 $ENV{REQUEST_METHOD} = 'GET';
313 $ENV{SERVER_PORT} = '80';
314 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
315 $ENV{QUERY_STRING} = 'do=prefs';
316 $ENV{HTTP_HOST} = 'example.com';
318 %bits = parse_cgi_content($content);
319 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
321 local $TODO = "treat https in configured url, cgiurl as required?";
322 is($bits{basehref}, "https://example.com/wiki/");
323 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
325 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
327 # when accessed via a different hostname, links stay on that host
328 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
329 $ENV{REQUEST_METHOD} = 'GET';
330 $ENV{SERVER_PORT} = '443';
331 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
332 $ENV{QUERY_STRING} = 'do=prefs';
333 $ENV{HTTP_HOST} = 'staging.example.net';
336 %bits = parse_cgi_content($content);
337 is($bits{basehref}, "https://staging.example.net/wiki/");
338 like($bits{stylehref}, qr{^(?:(?:https:)?//staging.example.net)?/wiki/style.css$});
339 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
340 like($bits{cgihref}, qr{^(?:(?:https:)?//staging.example.net)?/cgi-bin/ikiwiki.cgi$});
343 $in = 'do=edit&page=a/b/c&Preview';
344 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
345 $ENV{REQUEST_METHOD} = 'POST';
346 $ENV{SERVER_PORT} = '443';
347 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
348 $ENV{HTTP_HOST} = 'example.com';
349 $ENV{CONTENT_LENGTH} = length $in;
352 %bits = parse_cgi_content($content);
353 is($bits{basehref}, "https://example.com/wiki/a/b/c/");
354 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
355 like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
356 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
358 #######################################################################
359 # site 4 (NetBSD wiki): CGI is secure, static content doesn't have to be
361 writefile("test.setup", "t/tmp", <<EOF
362 # IkiWiki::Setup::Yaml - YAML formatted setup file
363 wikiname: this is the name of my wiki
366 templatedir: templates
367 url: "http://example.com/wiki/"
368 cgiurl: "https://example.com/cgi-bin/ikiwiki.cgi"
369 cgi_wrapper: t/tmp/ikiwiki.cgi
370 cgi_wrappermode: 0754
371 # make it easier to test previewing
378 ok(unlink("t/tmp/ikiwiki.cgi"));
379 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
381 # CGI wrapper should be exactly the requested mode
382 (undef, undef, $mode, undef, undef,
383 undef, undef, undef, undef, undef,
384 undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
385 is($mode & 07777, 0754);
387 ok(-e "t/tmp/out/a/b/c/index.html");
388 $content = readfile("t/tmp/out/a/b/c/index.html");
389 # no <base> on static HTML
390 unlike($content, qr{<base\W});
391 # url and cgiurl are on the same host but different schemes
392 like($content, qr{<a[^>]+href="https://example.com/cgi-bin/ikiwiki.cgi\?do=prefs"});
393 # cross-links between static pages are relative
394 like($content, qr{<li>A: <a href="../../">a</a></li>});
395 like($content, qr{<li>B: <a href="../">b</a></li>});
396 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
398 # when accessed via HTTPS, links are secure (to avoid mixed-content)
399 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
400 $ENV{REQUEST_METHOD} = 'GET';
401 $ENV{SERVER_PORT} = '443';
402 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
403 $ENV{QUERY_STRING} = 'do=prefs';
404 $ENV{HTTP_HOST} = 'example.com';
407 %bits = parse_cgi_content($content);
409 local $TODO = "avoid mixed content";
410 is($bits{basehref}, "https://example.com/wiki/");
411 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
412 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
414 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
416 # when not accessed via HTTPS, ???
417 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
418 $ENV{REQUEST_METHOD} = 'GET';
419 $ENV{SERVER_PORT} = '80';
420 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
421 $ENV{QUERY_STRING} = 'do=prefs';
422 $ENV{HTTP_HOST} = 'example.com';
424 %bits = parse_cgi_content($content);
425 like($bits{basehref}, qr{^https?://example.com/wiki/$});
426 like($bits{stylehref}, qr{^(?:(?:https?:)?//example.com)?/wiki/style.css$});
427 like($bits{tophref}, qr{^(?:(?:https?://example.com)?/wiki|\.)/$});
428 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
430 # when accessed via a different hostname, links stay on that host
431 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
432 $ENV{REQUEST_METHOD} = 'GET';
433 $ENV{SERVER_PORT} = '443';
434 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
435 $ENV{QUERY_STRING} = 'do=prefs';
436 $ENV{HTTP_HOST} = 'staging.example.net';
439 %bits = parse_cgi_content($content);
441 local $TODO = "avoid mixed content";
442 like($bits{basehref}, qr{^https://example.com/wiki/$});
443 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
444 like($bits{tophref}, qr{^(?:(?:(?:https:)?//example.com)?/wiki|\.)/$});
445 like($bits{cgihref}, qr{^(?:(?:https:)?//staging.example.net)?/cgi-bin/ikiwiki.cgi$});
449 $in = 'do=edit&page=a/b/c&Preview';
450 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
451 $ENV{REQUEST_METHOD} = 'POST';
452 $ENV{SERVER_PORT} = '443';
453 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
454 $ENV{HTTP_HOST} = 'example.com';
455 $ENV{CONTENT_LENGTH} = length $in;
458 %bits = parse_cgi_content($content);
460 local $TODO = "avoid mixed content";
461 is($bits{basehref}, "https://example.com/wiki/a/b/c/");
462 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
464 like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
465 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
467 # Deliberately not testing https static content with http cgiurl,
468 # because that makes remarkably little sense.
470 #######################################################################
471 # site 5: w3mmode, as documented in [[w3mmode]]
473 writefile("test.setup", "t/tmp", <<EOF
474 # IkiWiki::Setup::Yaml - YAML formatted setup file
475 wikiname: this is the name of my wiki
478 templatedir: templates
481 cgi_wrapper: t/tmp/ikiwiki.cgi
482 cgi_wrappermode: 0754
489 ok(unlink("t/tmp/ikiwiki.cgi"));
490 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
492 # CGI wrapper should be exactly the requested mode
493 (undef, undef, $mode, undef, undef,
494 undef, undef, undef, undef, undef,
495 undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
496 is($mode & 07777, 0754);
498 ok(-e "t/tmp/out/a/b/c/index.html");
499 $content = readfile("t/tmp/out/a/b/c/index.html");
500 # no <base> on static HTML
501 unlike($content, qr{<base\W});
502 # FIXME: does /$LIB/ikiwiki-w3m.cgi work under w3m?
503 like($content, qr{<a[^>]+href="(?:file://)?/\$LIB/ikiwiki-w3m.cgi/ikiwiki.cgi\?do=prefs"});
504 # cross-links between static pages are still relative
505 like($content, qr{<li>A: <a href="../../">a</a></li>});
506 like($content, qr{<li>B: <a href="../">b</a></li>});
507 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
509 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
510 $ENV{REQUEST_METHOD} = 'GET';
511 $ENV{PATH_INFO} = '/ikiwiki.cgi';
512 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki-w3m.cgi';
513 $ENV{QUERY_STRING} = 'do=prefs';
515 %bits = parse_cgi_content($content);
516 like($bits{tophref}, qr{^(?:\Q$pwd\E/t/tmp/out|\.)/$});
517 like($bits{cgihref}, qr{^(?:file://)?/\$LIB/ikiwiki-w3m.cgi/ikiwiki.cgi$});
519 local $TODO = "should be file:///";
520 like($bits{basehref}, qr{^(?:(?:file:)?//)?\Q$pwd\E/t/tmp/out/$});
521 like($bits{stylehref}, qr{^(?:(?:(?:file:)?//)?\Q$pwd\E/t/tmp/out|\.)/style.css$});
524 #######################################################################
525 # site 6: we're behind a reverse-proxy
527 writefile("test.setup", "t/tmp", <<EOF
528 # IkiWiki::Setup::Yaml - YAML formatted setup file
529 wikiname: this is the name of my wiki
532 templatedir: templates
533 url: "https://example.com/wiki/"
534 cgiurl: "https://example.com/cgi-bin/ikiwiki.cgi"
535 cgi_wrapper: t/tmp/ikiwiki.cgi
536 cgi_wrappermode: 0754
537 # make it easier to test previewing
545 ok(unlink("t/tmp/ikiwiki.cgi"));
546 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
548 # CGI wrapper should be exactly the requested mode
549 (undef, undef, $mode, undef, undef,
550 undef, undef, undef, undef, undef,
551 undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
552 is($mode & 07777, 0754);
554 ok(-e "t/tmp/out/a/b/c/index.html");
555 $content = readfile("t/tmp/out/a/b/c/index.html");
556 # no <base> on static HTML
557 unlike($content, qr{<base\W});
558 # url and cgiurl are on the same host so the cgiurl is host-relative
559 like($content, qr{<a[^>]+href="/cgi-bin/ikiwiki.cgi\?do=prefs"});
560 # cross-links between static pages are relative
561 like($content, qr{<li>A: <a href="../../">a</a></li>});
562 like($content, qr{<li>B: <a href="../">b</a></li>});
563 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
565 # because we are behind a reverse-proxy we must assume that
566 # we're being accessed by the configured cgiurl
567 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
568 $ENV{REQUEST_METHOD} = 'GET';
569 $ENV{SERVER_PORT} = '80';
570 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
571 $ENV{QUERY_STRING} = 'do=prefs';
572 $ENV{HTTP_HOST} = 'localhost';
574 %bits = parse_cgi_content($content);
575 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
576 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
578 local $TODO = "reverse-proxy support needed";
579 is($bits{basehref}, "https://example.com/wiki/");
580 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
584 $in = 'do=edit&page=a/b/c&Preview';
585 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
586 $ENV{REQUEST_METHOD} = 'POST';
587 $ENV{SERVER_PORT} = '80';
588 $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
589 $ENV{HTTP_HOST} = 'localhost';
590 $ENV{CONTENT_LENGTH} = length $in;
592 %bits = parse_cgi_content($content);
593 like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
594 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
596 local $TODO = "reverse-proxy support needed";
597 is($bits{basehref}, "https://example.com/wiki/a/b/c/");
598 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});