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