]> git.vanrenterghem.biz Git - git.ikiwiki.info.git/blob - t/relativity.t
Release 3.20141016.4
[git.ikiwiki.info.git] / t / relativity.t
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
5 use Test::More;
6 plan(skip_all => "IPC::Run not available")
7         unless eval q{
8                 use IPC::Run qw(run);
9                 1;
10         };
12 use IkiWiki;
14 use Cwd qw(getcwd);
15 use Errno qw(ENOENT);
17 # Black-box (ish) test for relative linking between CGI and static content
19 my $installed = $ENV{INSTALLED_TESTS};
21 my @command;
22 if ($installed) {
23         @command = qw(ikiwiki);
24 }
25 else {
26         ok(! system("make -s ikiwiki.out"));
27         @command = qw(perl -I. ./ikiwiki.out
28                 --underlaydir=underlays/basewiki
29                 --set underlaydirbase=underlays
30                 --templatedir=templates);
31 }
33 sub parse_cgi_content {
34         my $content = shift;
35         my %bits;
36         if ($content =~ qr{<base href="([^"]+)" */>}) {
37                 $bits{basehref} = $1;
38         }
39         if ($content =~ qr{href="([^"]+/style.css)"}) {
40                 $bits{stylehref} = $1;
41         }
42         if ($content =~ qr{class="parentlinks">\s+<a href="([^"]+)">this is the name of my wiki</a>/}s) {
43                 $bits{tophref} = $1;
44         }
45         if ($content =~ qr{<a[^>]+href="([^"]+)\?do=prefs"}) {
46                 $bits{cgihref} = $1;
47         }
48         return %bits;
49 }
51 sub write_old_file {
52         my $name = shift;
53         my $content = shift;
55         writefile($name, "t/tmp/in", $content);
56         ok(utime(333333333, 333333333, "t/tmp/in/$name"));
57 }
59 sub write_setup_file {
60         my (%args) = @_;
61         my $urlline = defined $args{url} ? "url: $args{url}" : "";
62         my $w3mmodeline = defined $args{w3mmode} ? "w3mmode: $args{w3mmode}" : "";
63         my $reverseproxyline = defined $args{reverse_proxy} ? "reverse_proxy: $args{reverse_proxy}" : "";
65         writefile("test.setup", "t/tmp", <<EOF
66 # IkiWiki::Setup::Yaml - YAML formatted setup file
67 wikiname: this is the name of my wiki
68 srcdir: t/tmp/in
69 destdir: t/tmp/out
70 $urlline
71 cgiurl: $args{cgiurl}
72 $w3mmodeline
73 cgi_wrapper: t/tmp/ikiwiki.cgi
74 cgi_wrappermode: 0754
75 html5: $args{html5}
76 # make it easier to test previewing
77 add_plugins:
78 - anonok
79 anonok_pagespec: "*"
80 $reverseproxyline
81 ENV: { 'PERL5LIB': 'blib/lib:blib/arch' }
82 EOF
83         );
84 }
86 sub thoroughly_rebuild {
87         ok(unlink("t/tmp/ikiwiki.cgi") || $!{ENOENT});
88         ok(! system(@command, qw(--setup t/tmp/test.setup --rebuild --wrappers)));
89 }
91 sub check_cgi_mode_bits {
92         my (undef, undef, $mode, undef, undef,
93                 undef, undef, undef, undef, undef,
94                 undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
95         is($mode & 07777, 0754);
96 }
98 sub check_generated_content {
99         my $cgiurl_regex = shift;
100         ok(-e "t/tmp/out/a/b/c/index.html");
101         my $content = readfile("t/tmp/out/a/b/c/index.html");
102         # no <base> on static HTML
103         unlike($content, qr{<base\W});
104         like($content, $cgiurl_regex);
105         # cross-links between static pages are relative
106         like($content, qr{<li>A: <a href="../../">a</a></li>});
107         like($content, qr{<li>B: <a href="../">b</a></li>});
108         like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
111 sub run_cgi {
112         my (%args) = @_;
113         my ($in, $out);
114         my $is_preview = delete $args{is_preview};
115         my $is_https = delete $args{is_https};
116         my %defaults = (
117                 SCRIPT_NAME     => '/cgi-bin/ikiwiki.cgi',
118                 HTTP_HOST       => 'example.com',
119         );
120         if (defined $is_preview) {
121                 $defaults{REQUEST_METHOD} = 'POST';
122                 $in = 'do=edit&page=a/b/c&Preview';
123                 $defaults{CONTENT_LENGTH} = length $in;
124         } else {
125                 $defaults{REQUEST_METHOD} = 'GET';
126                 $defaults{QUERY_STRING} = 'do=prefs';
127         }
128         if (defined $is_https) {
129                 $defaults{SERVER_PORT} = '443';
130                 $defaults{HTTPS} = 'on';
131         } else {
132                 $defaults{SERVER_PORT} = '80';
133         }
134         my %envvars = (
135                 %defaults,
136                 %args,
137         );
138         run(["./t/tmp/ikiwiki.cgi"], \$in, \$out, init => sub {
139                 map {
140                         $ENV{$_} = $envvars{$_}
141                 } keys(%envvars);
142         });
144         return $out;
147 sub test_startup {
148         ok(! system("rm -rf t/tmp"));
149         ok(! system("mkdir t/tmp"));
151         write_old_file("a.mdwn", "A");
152         write_old_file("a/b.mdwn", "B");
153         write_old_file("a/b/c.mdwn",
154         "* A: [[a]]\n".
155         "* B: [[b]]\n".
156         "* E: [[a/d/e]]\n");
157         write_old_file("a/d.mdwn", "D");
158         write_old_file("a/d/e.mdwn", "E");
161 sub test_site1_perfectly_ordinary_ikiwiki {
162         write_setup_file(
163                 html5   => 0,
164                 url     => "http://example.com/wiki/",
165                 cgiurl  => "http://example.com/cgi-bin/ikiwiki.cgi",
166         );
167         thoroughly_rebuild();
168         check_cgi_mode_bits();
169         # url and cgiurl are on the same host so the cgiurl is host-relative
170         check_generated_content(qr{<a[^>]+href="/cgi-bin/ikiwiki.cgi\?do=prefs"});
171         my %bits = parse_cgi_content(run_cgi());
172         is($bits{basehref}, "http://example.com/wiki/");
173         like($bits{stylehref}, qr{^(?:(?:http:)?//example.com)?/wiki/style.css$});
174         like($bits{tophref}, qr{^(?:/wiki|\.)/$});
175         like($bits{cgihref}, qr{^(?:(?:http:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
177         # when accessed via HTTPS, links are secure
178         %bits = parse_cgi_content(run_cgi(is_https => 1));
179         is($bits{basehref}, "https://example.com/wiki/");
180         like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
181         like($bits{tophref}, qr{^(?:/wiki|\.)/$});
182         like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
184         # when accessed via a different hostname, links stay on that host
185         %bits = parse_cgi_content(run_cgi(HTTP_HOST => 'staging.example.net'));
186         is($bits{basehref}, "http://staging.example.net/wiki/");
187         like($bits{stylehref}, qr{^(?:(?:http:)?//staging.example.net)?/wiki/style.css$});
188         like($bits{tophref}, qr{^(?:/wiki|\.)/$});
189         like($bits{cgihref}, qr{^(?:(?:http:)?//staging.example.net)?/cgi-bin/ikiwiki.cgi$});
191         # previewing a page
192         %bits = parse_cgi_content(run_cgi(is_preview => 1));
193         is($bits{basehref}, "http://example.com/wiki/a/b/c/");
194         like($bits{stylehref}, qr{^(?:(?:http:)?//example.com)?/wiki/style.css$});
195         like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
196         like($bits{cgihref}, qr{^(?:(?:http:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
198         # in html5, the <base> is allowed to be relative, and we take full
199         # advantage of that
200         write_setup_file(
201                 html5   => 1,
202                 url     => "http://example.com/wiki/",
203                 cgiurl  => "http://example.com/cgi-bin/ikiwiki.cgi",
204         );
205         thoroughly_rebuild();
206         check_cgi_mode_bits();
207         # url and cgiurl are on the same host so the cgiurl is host-relative
208         check_generated_content(qr{<a[^>]+href="/cgi-bin/ikiwiki.cgi\?do=prefs"});
210         %bits = parse_cgi_content(run_cgi());
211         is($bits{basehref}, "/wiki/");
212         is($bits{stylehref}, "/wiki/style.css");
213         is($bits{tophref}, "/wiki/");
214         is($bits{cgihref}, "/cgi-bin/ikiwiki.cgi");
216         # when accessed via HTTPS, links are secure - this is easy because under
217         # html5 they're independent of the URL at which the CGI was accessed
218         %bits = parse_cgi_content(run_cgi(is_https => 1));
219         is($bits{basehref}, "/wiki/");
220         is($bits{stylehref}, "/wiki/style.css");
221         is($bits{tophref}, "/wiki/");
222         is($bits{cgihref}, "/cgi-bin/ikiwiki.cgi");
224         # when accessed via a different hostname, links stay on that host -
225         # this is really easy in html5 because we can use relative URLs
226         %bits = parse_cgi_content(run_cgi(HTTP_HOST => 'staging.example.net'));
227         is($bits{basehref}, "/wiki/");
228         is($bits{stylehref}, "/wiki/style.css");
229         is($bits{tophref}, "/wiki/");
230         is($bits{cgihref}, "/cgi-bin/ikiwiki.cgi");
232         # previewing a page
233         %bits = parse_cgi_content(run_cgi(is_preview => 1));
234         is($bits{basehref}, "/wiki/a/b/c/");
235         is($bits{stylehref}, "/wiki/style.css");
236         like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
237         is($bits{cgihref}, "/cgi-bin/ikiwiki.cgi");
240 sub test_site2_static_content_and_cgi_on_different_servers {
241         write_setup_file(
242                 html5   => 0,
243                 url     => "http://static.example.com/",
244                 cgiurl  => "http://cgi.example.com/ikiwiki.cgi",
245         );
246         thoroughly_rebuild();
247         check_cgi_mode_bits();
248         # url and cgiurl are not on the same host so the cgiurl has to be
249         # protocol-relative or absolute
250         check_generated_content(qr{<a[^>]+href="(?:http:)?//cgi.example.com/ikiwiki.cgi\?do=prefs"});
252         my %bits = parse_cgi_content(run_cgi(SCRIPT_NAME => '/ikiwiki.cgi', HTTP_HOST => 'cgi.example.com'));
253         like($bits{basehref}, qr{^http://static.example.com/$});
254         like($bits{stylehref}, qr{^(?:(?:http:)?//static.example.com)?/style.css$});
255         like($bits{tophref}, qr{^(?:http:)?//static.example.com/$});
256         like($bits{cgihref}, qr{^(?:(?:http:)?//cgi.example.com)?/ikiwiki.cgi$});
258         # when accessed via HTTPS, links are secure
259         %bits = parse_cgi_content(run_cgi(is_https => 1, SCRIPT_NAME => '/ikiwiki.cgi', HTTP_HOST => 'cgi.example.com'));
260         like($bits{basehref}, qr{^https://static.example.com/$});
261         like($bits{stylehref}, qr{^(?:(?:https:)?//static.example.com)?/style.css$});
262         like($bits{tophref}, qr{^(?:https:)?//static.example.com/$});
263         like($bits{cgihref}, qr{^(?:(?:https:)?//cgi.example.com)?/ikiwiki.cgi$});
265         # when accessed via a different hostname, links to the CGI (only) should
266         # stay on that host?
267         %bits = parse_cgi_content(run_cgi(is_preview => 1, SCRIPT_NAME => '/ikiwiki.cgi', HTTP_HOST => 'staging.example.net'));
268         like($bits{basehref}, qr{^http://static.example.com/a/b/c/$});
269         like($bits{stylehref}, qr{^(?:(?:http:)?//static.example.com|\.\./\.\./\.\.)/style.css$});
270         like($bits{tophref}, qr{^(?:(?:http:)?//static.example.com|\.\./\.\./\.\.)/$});
271         like($bits{cgihref}, qr{^(?:(?:http:)?//(?:staging\.example\.net|cgi\.example\.com))?/ikiwiki.cgi$});
272         TODO: {
273         local $TODO = "use self-referential CGI URL?";
274         like($bits{cgihref}, qr{^(?:(?:http:)?//staging.example.net)?/ikiwiki.cgi$});
275         }
277         write_setup_file(
278                 html5   => 1,
279                 url     => "http://static.example.com/",
280                 cgiurl  => "http://cgi.example.com/ikiwiki.cgi",
281         );
282         thoroughly_rebuild();
283         check_cgi_mode_bits();
284         # url and cgiurl are not on the same host so the cgiurl has to be
285         # protocol-relative or absolute
286         check_generated_content(qr{<a[^>]+href="(?:http:)?//cgi.example.com/ikiwiki.cgi\?do=prefs"});
288         %bits = parse_cgi_content(run_cgi(SCRIPT_NAME => '/ikiwiki.cgi', HTTP_HOST => 'cgi.example.com'));
289         is($bits{basehref}, "//static.example.com/");
290         is($bits{stylehref}, "//static.example.com/style.css");
291         is($bits{tophref}, "//static.example.com/");
292         is($bits{cgihref}, "//cgi.example.com/ikiwiki.cgi");
294         # when accessed via HTTPS, links are secure - in fact they're exactly the
295         # same as when accessed via HTTP
296         %bits = parse_cgi_content(run_cgi(is_https => 1, SCRIPT_NAME => '/ikiwiki.cgi', HTTP_HOST => 'cgi.example.com'));
297         is($bits{basehref}, "//static.example.com/");
298         is($bits{stylehref}, "//static.example.com/style.css");
299         is($bits{tophref}, "//static.example.com/");
300         is($bits{cgihref}, "//cgi.example.com/ikiwiki.cgi");
302         # when accessed via a different hostname, links to the CGI (only) should
303         # stay on that host?
304         %bits = parse_cgi_content(run_cgi(is_preview => 1, SCRIPT_NAME => '/ikiwiki.cgi', HTTP_HOST => 'staging.example.net'));
305         is($bits{basehref}, "//static.example.com/a/b/c/");
306         is($bits{stylehref}, "//static.example.com/style.css");
307         is($bits{tophref}, "../../../");
308         like($bits{cgihref}, qr{//(?:staging\.example\.net|cgi\.example\.com)/ikiwiki\.cgi});
309         TODO: {
310         local $TODO = "use self-referential CGI URL maybe?";
311         is($bits{cgihref}, "//staging.example.net/ikiwiki.cgi");
312         }
315 sub test_site3_we_specifically_want_everything_to_be_secure {
316         write_setup_file(
317                 html5   => 0,
318                 url     => "https://example.com/wiki/",
319                 cgiurl  => "https://example.com/cgi-bin/ikiwiki.cgi",
320         );
321         thoroughly_rebuild();
322         check_cgi_mode_bits();
323         # url and cgiurl are on the same host so the cgiurl is host-relative
324         check_generated_content(qr{<a[^>]+href="/cgi-bin/ikiwiki.cgi\?do=prefs"});
326         # when accessed via HTTPS, links are secure
327         my %bits = parse_cgi_content(run_cgi(is_https => 1));
328         is($bits{basehref}, "https://example.com/wiki/");
329         like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
330         like($bits{tophref}, qr{^(?:/wiki|\.)/$});
331         like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
333         # when not accessed via HTTPS, links should still be secure
334         # (but if this happens, that's a sign of web server misconfiguration)
335         %bits = parse_cgi_content(run_cgi());
336         like($bits{tophref}, qr{^(?:/wiki|\.)/$});
337         TODO: {
338         local $TODO = "treat https in configured url, cgiurl as required?";
339         is($bits{basehref}, "https://example.com/wiki/");
340         like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
341         }
342         like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
344         # when accessed via a different hostname, links stay on that host
345         %bits = parse_cgi_content(run_cgi(is_https => 1, HTTP_HOST => 'staging.example.net'));
346         is($bits{basehref}, "https://staging.example.net/wiki/");
347         like($bits{stylehref}, qr{^(?:(?:https:)?//staging.example.net)?/wiki/style.css$});
348         like($bits{tophref}, qr{^(?:/wiki|\.)/$});
349         like($bits{cgihref}, qr{^(?:(?:https:)?//staging.example.net)?/cgi-bin/ikiwiki.cgi$});
351         # previewing a page
352         %bits = parse_cgi_content(run_cgi(is_preview => 1, is_https => 1));
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         # not testing html5: 0 here because that ends up identical to site 1
361 sub test_site4_cgi_is_secure_static_content_doesnt_have_to_be {
362         # (NetBSD wiki)
363         write_setup_file(
364                 html5   => 0,
365                 url     => "http://example.com/wiki/",
366                 cgiurl  => "https://example.com/cgi-bin/ikiwiki.cgi",
367         );
368         thoroughly_rebuild();
369         check_cgi_mode_bits();
370         # url and cgiurl are on the same host but different schemes
371         check_generated_content(qr{<a[^>]+href="https://example.com/cgi-bin/ikiwiki.cgi\?do=prefs"});
373         # when accessed via HTTPS, links are secure (to avoid mixed-content)
374         my %bits = parse_cgi_content(run_cgi(is_https => 1));
375         is($bits{basehref}, "https://example.com/wiki/");
376         like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
377         like($bits{tophref}, qr{^(?:/wiki|\.)/$});
378         like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
380         # when not accessed via HTTPS, ???
381         %bits = parse_cgi_content(run_cgi());
382         like($bits{basehref}, qr{^https?://example.com/wiki/$});
383         like($bits{stylehref}, qr{^(?:(?:https?:)?//example.com)?/wiki/style.css$});
384         like($bits{tophref}, qr{^(?:(?:https?://example.com)?/wiki|\.)/$});
385         like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
387         # when accessed via a different hostname, links stay on that host
388         %bits = parse_cgi_content(run_cgi(is_https => 1, HTTP_HOST => 'staging.example.net'));
389         # because the static and dynamic stuff is on the same server, we assume that
390         # both are also on the staging server
391         like($bits{basehref}, qr{^https://staging.example.net/wiki/$});
392         like($bits{stylehref}, qr{^(?:(?:https:)?//staging.example.net)?/wiki/style.css$});
393         like($bits{tophref}, qr{^(?:(?:(?:https:)?//staging.example.net)?/wiki|\.)/$});
394         like($bits{cgihref}, qr{^(?:(?:https:)?//(?:staging\.example\.net|example\.com))?/cgi-bin/ikiwiki.cgi$});
395         TODO: {
396         local $TODO = "this should really point back to itself but currently points to example.com";
397         like($bits{cgihref}, qr{^(?:(?:https:)?//staging.example.net)?/cgi-bin/ikiwiki.cgi$});
398         }
400         # previewing a page
401         %bits = parse_cgi_content(run_cgi(is_preview => 1, is_https => 1));
402         is($bits{basehref}, "https://example.com/wiki/a/b/c/");
403         like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
404         like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
405         like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
407         write_setup_file(
408                 html5   => 1,
409                 url     => "http://example.com/wiki/",
410                 cgiurl  => "https://example.com/cgi-bin/ikiwiki.cgi",
411         );
412         thoroughly_rebuild();
413         check_cgi_mode_bits();
414         # url and cgiurl are on the same host but different schemes
415         check_generated_content(qr{<a[^>]+href="https://example.com/cgi-bin/ikiwiki.cgi\?do=prefs"});
417         # when accessed via HTTPS, links are secure (to avoid mixed-content)
418         %bits = parse_cgi_content(run_cgi(is_https => 1));
419         is($bits{basehref}, "/wiki/");
420         is($bits{stylehref}, "/wiki/style.css");
421         is($bits{tophref}, "/wiki/");
422         like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
424         # when not accessed via HTTPS, ???
425         %bits = parse_cgi_content(run_cgi());
426         like($bits{basehref}, qr{^(?:https?://example.com)?/wiki/$});
427         like($bits{stylehref}, qr{^(?:(?:https?:)?//example.com)?/wiki/style.css$});
428         like($bits{tophref}, qr{^(?:(?:https?://example.com)?/wiki|\.)/$});
429         like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
431         # when accessed via a different hostname, links stay on that host
432         %bits = parse_cgi_content(run_cgi(is_https => 1, HTTP_HOST => 'staging.example.net'));
433         # because the static and dynamic stuff is on the same server, we assume that
434         # both are also on the staging server
435         is($bits{basehref}, "/wiki/");
436         is($bits{stylehref}, "/wiki/style.css");
437         like($bits{tophref}, qr{^(?:/wiki|\.)/$});
438         like($bits{cgihref}, qr{^(?:(?:https:)?//(?:example\.com|staging\.example\.net))?/cgi-bin/ikiwiki.cgi$});
439         TODO: {
440         local $TODO = "this should really point back to itself but currently points to example.com";
441         like($bits{cgihref}, qr{^(?:(?:https:)?//staging.example.net)?/cgi-bin/ikiwiki.cgi$});
442         }
444         # previewing a page
445         %bits = parse_cgi_content(run_cgi(is_preview => 1, is_https => 1));
446         is($bits{basehref}, "/wiki/a/b/c/");
447         is($bits{stylehref}, "/wiki/style.css");
448         like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
449         like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
451         # Deliberately not testing https static content with http cgiurl,
452         # because that makes remarkably little sense.
455 sub test_site5_w3mmode {
456         # as documented in [[w3mmode]]
457         write_setup_file(
458                 html5   => 0, 
459                 url     => undef,
460                 cgiurl  => "ikiwiki.cgi",
461                 w3mmode => 1,
462         );
463         thoroughly_rebuild();
464         check_cgi_mode_bits();
465         # FIXME: does /$LIB/ikiwiki-w3m.cgi work under w3m?
466         check_generated_content(qr{<a[^>]+href="(?:file://)?/\$LIB/ikiwiki-w3m.cgi/ikiwiki.cgi\?do=prefs"});
468         my %bits = parse_cgi_content(run_cgi(PATH_INFO => '/ikiwiki.cgi', SCRIPT_NAME => '/cgi-bin/ikiwiki-w3m.cgi'));
469         my $pwd = getcwd();
470         like($bits{tophref}, qr{^(?:\Q$pwd\E/t/tmp/out|\.)/$});
471         like($bits{cgihref}, qr{^(?:file://)?/\$LIB/ikiwiki-w3m.cgi/ikiwiki.cgi$});
472         like($bits{basehref}, qr{^(?:(?:file:)?//)?\Q$pwd\E/t/tmp/out/$});
473         like($bits{stylehref}, qr{^(?:(?:(?:file:)?//)?\Q$pwd\E/t/tmp/out|\.)/style.css$});
475         write_setup_file(
476                 html5   => 1,
477                 url     => undef,
478                 cgiurl  => "ikiwiki.cgi",
479                 w3mmode => 1,
480         );
481         thoroughly_rebuild();
482         check_cgi_mode_bits();
483         # FIXME: does /$LIB/ikiwiki-w3m.cgi work under w3m?
484         check_generated_content(qr{<a[^>]+href="(?:file://)?/\$LIB/ikiwiki-w3m.cgi/ikiwiki.cgi\?do=prefs"});
486         %bits = parse_cgi_content(run_cgi(PATH_INFO => '/ikiwiki.cgi', SCRIPT_NAME => '/cgi-bin/ikiwiki-w3m.cgi'));
487         like($bits{tophref}, qr{^(?:\Q$pwd\E/t/tmp/out|\.)/$});
488         like($bits{cgihref}, qr{^(?:file://)?/\$LIB/ikiwiki-w3m.cgi/ikiwiki.cgi$});
489         like($bits{basehref}, qr{^(?:(?:file:)?//)?\Q$pwd\E/t/tmp/out/$});
490         like($bits{stylehref}, qr{^(?:(?:(?:file:)?//)?\Q$pwd\E/t/tmp/out|\.)/style.css$});
493 sub test_site6_behind_reverse_proxy {
494         write_setup_file(
495                 html5   => 0,
496                 url     => "https://example.com/wiki/",
497                 cgiurl  => "https://example.com/cgi-bin/ikiwiki.cgi",
498                 reverse_proxy => 1,
499         );
500         thoroughly_rebuild();
501         check_cgi_mode_bits();
502         # url and cgiurl are on the same host so the cgiurl is host-relative
503         check_generated_content(qr{<a[^>]+href="/cgi-bin/ikiwiki.cgi\?do=prefs"});
505         # because we are behind a reverse-proxy we must assume that
506         # we're being accessed by the configured cgiurl
507         my %bits = parse_cgi_content(run_cgi(HTTP_HOST => 'localhost'));
508         like($bits{tophref}, qr{^(?:/wiki|\.)/$});
509         like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
510         is($bits{basehref}, "https://example.com/wiki/");
511         like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
513         # previewing a page
514         %bits = parse_cgi_content(run_cgi(is_preview => 1, HTTP_HOST => 'localhost'));
515         like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
516         like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
517         is($bits{basehref}, "https://example.com/wiki/a/b/c/");
518         like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
520         # not testing html5: 1 because it would be the same as site 1 -
521         # the reverse_proxy config option is unnecessary under html5
524 test_startup();
526 test_site1_perfectly_ordinary_ikiwiki();
527 test_site2_static_content_and_cgi_on_different_servers();
528 test_site3_we_specifically_want_everything_to_be_secure();
529 test_site4_cgi_is_secure_static_content_doesnt_have_to_be();
530 test_site5_w3mmode();
531 test_site6_behind_reverse_proxy();
533 done_testing();