add the beginnings of a test for CGI/static URL interactions
[ikiwiki.git] / t / relativity.t
1 #!/usr/bin/perl
2 use warnings;
3 use strict;
4
5 use Cwd qw(getcwd);
6 use Errno qw(ENOENT);
7
8 BEGIN {
9         if (!eval q{
10                 use IPC::Run qw(run);
11                 1;
12         }) {
13                 eval q{use Test::More skip_all => "IPC::Run not available"};
14         }
15         else {
16                 eval q{use Test::More};
17         }
18         use_ok("IkiWiki");
19 }
20
21 my $pwd = getcwd();
22
23 # Black-box (ish) test for relative linking between CGI and static content
24
25 my $blob;
26 my ($content, $in, %bits);
27
28 sub parse_cgi_content {
29         my %bits;
30         if ($content =~ qr{<base href="([^"]+)" */>}) {
31                 $bits{basehref} = $1;
32         }
33         if ($content =~ qr{href="([^"]+/style.css)"}) {
34                 $bits{stylehref} = $1;
35         }
36         if ($content =~ qr{class="parentlinks">\s+<a href="([^"]+)">this is the name of my wiki</a>/}s) {
37                 $bits{tophref} = $1;
38         }
39         if ($content =~ qr{<a[^>]+href="([^"]+)\?do=prefs"}) {
40                 $bits{cgihref} = $1;
41         }
42         return %bits;
43 }
44
45 ok(! system("make -s ikiwiki.out"));
46 ok(! system("rm -rf t/tmp"));
47 ok(! system("mkdir t/tmp"));
48
49 sub write_old_file {
50         my $name = shift;
51         my $content = shift;
52
53         writefile($name, "t/tmp/in", $content);
54         ok(utime(333333333, 333333333, "t/tmp/in/$name"));
55 }
56
57 write_old_file("a.mdwn", "A");
58 write_old_file("a/b.mdwn", "B");
59 write_old_file("a/b/c.mdwn",
60 "* A: [[a]]\n".
61 "* B: [[b]]\n".
62 "* E: [[a/d/e]]\n");
63 write_old_file("a/d.mdwn", "D");
64 write_old_file("a/d/e.mdwn", "E");
65
66 #######################################################################
67 # site 1: a perfectly ordinary ikiwiki
68
69 writefile("test.setup", "t/tmp", <<EOF
70 # IkiWiki::Setup::Yaml - YAML formatted setup file
71 wikiname: this is the name of my wiki
72 srcdir: t/tmp/in
73 destdir: t/tmp/out
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
78 cgi_wrappermode: 0754
79 # make it easier to test previewing
80 add_plugins:
81 - anonok
82 anonok_pagespec: "*"
83 EOF
84 );
85
86 ok(unlink("t/tmp/ikiwiki.cgi") || $!{ENOENT});
87 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
88
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);
94
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>});
105
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';
112 });
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$});
118
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';
126         $ENV{HTTPS} = 'on';
127 });
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$});
133
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';
141 });
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$});
147
148 # previewing a page
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;
156 });
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$});
162
163 #######################################################################
164 # site 2: static content and CGI are on different servers
165
166 writefile("test.setup", "t/tmp", <<EOF
167 # IkiWiki::Setup::Yaml - YAML formatted setup file
168 wikiname: this is the name of my wiki
169 srcdir: t/tmp/in
170 destdir: t/tmp/out
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
177 add_plugins:
178 - anonok
179 anonok_pagespec: "*"
180 EOF
181 );
182
183 ok(unlink("t/tmp/ikiwiki.cgi"));
184 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
185
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);
191
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>});
203
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';
210 });
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$});
216
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';
224         $ENV{HTTPS} = 'on';
225 });
226 %bits = parse_cgi_content($content);
227 TODO: {
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$});
233 }
234
235 # when accessed via a different hostname, links to the CGI (only) should
236 # stay on that host?
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';
243         $ENV{HTTPS} = 'on';
244         $ENV{CONTENT_LENGTH} = length $in;
245 });
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 TODO: {
250 local $TODO = "use self-referential CGI URL?";
251 like($bits{cgihref}, qr{^(?:(?:http:)?//staging.example.net)?/ikiwiki.cgi$});
252 }
253
254 #######################################################################
255 # site 3: we specifically want everything to be secure
256
257 writefile("test.setup", "t/tmp", <<EOF
258 # IkiWiki::Setup::Yaml - YAML formatted setup file
259 wikiname: this is the name of my wiki
260 srcdir: t/tmp/in
261 destdir: t/tmp/out
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
268 add_plugins:
269 - anonok
270 anonok_pagespec: "*"
271 EOF
272 );
273
274 ok(unlink("t/tmp/ikiwiki.cgi"));
275 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
276
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);
282
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>});
293
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';
301         $ENV{HTTPS} = 'on';
302 });
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$});
308
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';
317 });
318 %bits = parse_cgi_content($content);
319 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
320 TODO: {
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$});
324 }
325 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
326
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';
334         $ENV{HTTPS} = 'on';
335 });
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$});
341
342 # previewing a page
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;
350         $ENV{HTTPS} = 'on';
351 });
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$});
357
358 #######################################################################
359 # site 4 (NetBSD wiki): CGI is secure, static content doesn't have to be
360
361 writefile("test.setup", "t/tmp", <<EOF
362 # IkiWiki::Setup::Yaml - YAML formatted setup file
363 wikiname: this is the name of my wiki
364 srcdir: t/tmp/in
365 destdir: t/tmp/out
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
372 add_plugins:
373 - anonok
374 anonok_pagespec: "*"
375 EOF
376 );
377
378 ok(unlink("t/tmp/ikiwiki.cgi"));
379 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
380
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);
386
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>});
397
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';
405         $ENV{HTTPS} = 'on';
406 });
407 %bits = parse_cgi_content($content);
408 TODO: {
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|\.)/$});
413 }
414 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
415
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';
423 });
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$});
429
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';
437         $ENV{HTTPS} = 'on';
438 });
439 %bits = parse_cgi_content($content);
440 TODO: {
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$});
446 }
447
448 # previewing a page
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;
456         $ENV{HTTPS} = 'on';
457 });
458 %bits = parse_cgi_content($content);
459 TODO: {
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$});
463 }
464 like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
465 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
466
467 # Deliberately not testing https static content with http cgiurl,
468 # because that makes remarkably little sense.
469
470 #######################################################################
471 # site 5: w3mmode, as documented in [[w3mmode]]
472
473 writefile("test.setup", "t/tmp", <<EOF
474 # IkiWiki::Setup::Yaml - YAML formatted setup file
475 wikiname: this is the name of my wiki
476 srcdir: t/tmp/in
477 destdir: t/tmp/out
478 templatedir: templates
479 cgiurl: ikiwiki.cgi
480 w3mmode: 1
481 cgi_wrapper: t/tmp/ikiwiki.cgi
482 cgi_wrappermode: 0754
483 add_plugins:
484 - anonok
485 anonok_pagespec: "*"
486 EOF
487 );
488
489 ok(unlink("t/tmp/ikiwiki.cgi"));
490 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
491
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);
497
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>});
508
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';
514 });
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$});
518 TODO: {
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$});
522 }
523
524 #######################################################################
525 # site 6: we're behind a reverse-proxy
526
527 writefile("test.setup", "t/tmp", <<EOF
528 # IkiWiki::Setup::Yaml - YAML formatted setup file
529 wikiname: this is the name of my wiki
530 srcdir: t/tmp/in
531 destdir: t/tmp/out
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
538 add_plugins:
539 - anonok
540 anonok_pagespec: "*"
541 reverse_proxy: 1
542 EOF
543 );
544
545 ok(unlink("t/tmp/ikiwiki.cgi"));
546 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
547
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);
553
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>});
564
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';
573 });
574 %bits = parse_cgi_content($content);
575 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
576 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
577 TODO: {
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$});
581 }
582
583 # previewing a page
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;
591 });
592 %bits = parse_cgi_content($content);
593 like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
594 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
595 TODO: {
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$});
599 }
600
601 done_testing;