]> sipb.mit.edu Git - ikiwiki.git/blob - t/relativity.t
7e1e7049fdd67653f67dfbfe693c479a1e0a4333
[ikiwiki.git] / 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 $PERL5LIB = 'blib/lib:blib/arch';
18 my $pwd = getcwd();
19
20 # Black-box (ish) test for relative linking between CGI and static content
21
22 my $blob;
23 my ($content, $in, %bits);
24
25 sub parse_cgi_content {
26         my %bits;
27         if ($content =~ qr{<base href="([^"]+)" */>}) {
28                 $bits{basehref} = $1;
29         }
30         if ($content =~ qr{href="([^"]+/style.css)"}) {
31                 $bits{stylehref} = $1;
32         }
33         if ($content =~ qr{class="parentlinks">\s+<a href="([^"]+)">this is the name of my wiki</a>/}s) {
34                 $bits{tophref} = $1;
35         }
36         if ($content =~ qr{<a[^>]+href="([^"]+)\?do=prefs"}) {
37                 $bits{cgihref} = $1;
38         }
39         return %bits;
40 }
41
42 ok(! system("make -s ikiwiki.out"));
43 ok(! system("rm -rf t/tmp"));
44 ok(! system("mkdir t/tmp"));
45
46 sub write_old_file {
47         my $name = shift;
48         my $content = shift;
49
50         writefile($name, "t/tmp/in", $content);
51         ok(utime(333333333, 333333333, "t/tmp/in/$name"));
52 }
53
54 write_old_file("a.mdwn", "A");
55 write_old_file("a/b.mdwn", "B");
56 write_old_file("a/b/c.mdwn",
57 "* A: [[a]]\n".
58 "* B: [[b]]\n".
59 "* E: [[a/d/e]]\n");
60 write_old_file("a/d.mdwn", "D");
61 write_old_file("a/d/e.mdwn", "E");
62
63 #######################################################################
64 # site 1: a perfectly ordinary ikiwiki
65
66 writefile("test.setup", "t/tmp", <<EOF
67 # IkiWiki::Setup::Yaml - YAML formatted setup file
68 wikiname: this is the name of my wiki
69 srcdir: t/tmp/in
70 destdir: t/tmp/out
71 templatedir: templates
72 url: "http://example.com/wiki/"
73 cgiurl: "http://example.com/cgi-bin/ikiwiki.cgi"
74 cgi_wrapper: t/tmp/ikiwiki.cgi
75 cgi_wrappermode: 0754
76 html5: 0
77 # make it easier to test previewing
78 add_plugins:
79 - anonok
80 anonok_pagespec: "*"
81 ENV: { 'PERL5LIB': '$PERL5LIB' }
82 EOF
83 );
84
85 ok(unlink("t/tmp/ikiwiki.cgi") || $!{ENOENT});
86 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
87
88 # CGI wrapper should be exactly the requested mode
89 my (undef, undef, $mode, undef, undef,
90         undef, undef, undef, undef, undef,
91         undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
92 is($mode & 07777, 0754);
93
94 ok(-e "t/tmp/out/a/b/c/index.html");
95 $content = readfile("t/tmp/out/a/b/c/index.html");
96 # no <base> on static HTML
97 unlike($content, qr{<base\W});
98 # url and cgiurl are on the same host so the cgiurl is host-relative
99 like($content, qr{<a[^>]+href="/cgi-bin/ikiwiki.cgi\?do=prefs"});
100 # cross-links between static pages are relative
101 like($content, qr{<li>A: <a href="../../">a</a></li>});
102 like($content, qr{<li>B: <a href="../">b</a></li>});
103 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
104
105 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
106         $ENV{REQUEST_METHOD} = 'GET';
107         $ENV{SERVER_PORT} = '80';
108         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
109         $ENV{QUERY_STRING} = 'do=prefs';
110         $ENV{HTTP_HOST} = 'example.com';
111 });
112 %bits = parse_cgi_content($content);
113 is($bits{basehref}, "http://example.com/wiki/");
114 like($bits{stylehref}, qr{^(?:(?:http:)?//example.com)?/wiki/style.css$});
115 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
116 like($bits{cgihref}, qr{^(?:(?:http:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
117
118 # when accessed via HTTPS, links are secure
119 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
120         $ENV{REQUEST_METHOD} = 'GET';
121         $ENV{SERVER_PORT} = '443';
122         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
123         $ENV{QUERY_STRING} = 'do=prefs';
124         $ENV{HTTP_HOST} = 'example.com';
125         $ENV{HTTPS} = 'on';
126 });
127 %bits = parse_cgi_content($content);
128 is($bits{basehref}, "https://example.com/wiki/");
129 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
130 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
131 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
132
133 # when accessed via a different hostname, links stay on that host
134 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
135         $ENV{REQUEST_METHOD} = 'GET';
136         $ENV{SERVER_PORT} = '80';
137         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
138         $ENV{QUERY_STRING} = 'do=prefs';
139         $ENV{HTTP_HOST} = 'staging.example.net';
140 });
141 %bits = parse_cgi_content($content);
142 is($bits{basehref}, "http://staging.example.net/wiki/");
143 like($bits{stylehref}, qr{^(?:(?:http:)?//staging.example.net)?/wiki/style.css$});
144 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
145 like($bits{cgihref}, qr{^(?:(?:http:)?//staging.example.net)?/cgi-bin/ikiwiki.cgi$});
146
147 # previewing a page
148 $in = 'do=edit&page=a/b/c&Preview';
149 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
150         $ENV{REQUEST_METHOD} = 'POST';
151         $ENV{SERVER_PORT} = '80';
152         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
153         $ENV{HTTP_HOST} = 'example.com';
154         $ENV{CONTENT_LENGTH} = length $in;
155 });
156 %bits = parse_cgi_content($content);
157 is($bits{basehref}, "http://example.com/wiki/a/b/c/");
158 like($bits{stylehref}, qr{^(?:(?:http:)?//example.com)?/wiki/style.css$});
159 like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
160 like($bits{cgihref}, qr{^(?:(?:http:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
161
162 # in html5, the <base> is allowed to be relative, and we take full
163 # advantage of that
164 writefile("test.setup", "t/tmp", <<EOF
165 # IkiWiki::Setup::Yaml - YAML formatted setup file
166 wikiname: this is the name of my wiki
167 srcdir: t/tmp/in
168 destdir: t/tmp/out
169 templatedir: templates
170 url: "http://example.com/wiki/"
171 cgiurl: "http://example.com/cgi-bin/ikiwiki.cgi"
172 cgi_wrapper: t/tmp/ikiwiki.cgi
173 cgi_wrappermode: 0754
174 html5: 1
175 # make it easier to test previewing
176 add_plugins:
177 - anonok
178 anonok_pagespec: "*"
179 ENV: { 'PERL5LIB': '$PERL5LIB' }
180 EOF
181 );
182
183 ok(unlink("t/tmp/ikiwiki.cgi") || $!{ENOENT});
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 on the same host so the cgiurl is host-relative
197 like($content, qr{<a[^>]+href="/cgi-bin/ikiwiki.cgi\?do=prefs"});
198 # cross-links between static pages are relative
199 like($content, qr{<li>A: <a href="../../">a</a></li>});
200 like($content, qr{<li>B: <a href="../">b</a></li>});
201 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
202
203 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
204         $ENV{REQUEST_METHOD} = 'GET';
205         $ENV{SERVER_PORT} = '80';
206         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
207         $ENV{QUERY_STRING} = 'do=prefs';
208         $ENV{HTTP_HOST} = 'example.com';
209 });
210 %bits = parse_cgi_content($content);
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 HTTPS, links are secure - this is easy because under
217 # html5 they're independent of the URL at which the CGI was accessed
218 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
219         $ENV{REQUEST_METHOD} = 'GET';
220         $ENV{SERVER_PORT} = '443';
221         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
222         $ENV{QUERY_STRING} = 'do=prefs';
223         $ENV{HTTP_HOST} = 'example.com';
224         $ENV{HTTPS} = 'on';
225 });
226 %bits = parse_cgi_content($content);
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");
231
232 # when accessed via a different hostname, links stay on that host -
233 # this is really easy in html5 because we can use relative URLs
234 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
235         $ENV{REQUEST_METHOD} = 'GET';
236         $ENV{SERVER_PORT} = '80';
237         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
238         $ENV{QUERY_STRING} = 'do=prefs';
239         $ENV{HTTP_HOST} = 'staging.example.net';
240 });
241 %bits = parse_cgi_content($content);
242 is($bits{basehref}, "/wiki/");
243 is($bits{stylehref}, "/wiki/style.css");
244 is($bits{tophref}, "/wiki/");
245 is($bits{cgihref}, "/cgi-bin/ikiwiki.cgi");
246
247 # previewing a page
248 $in = 'do=edit&page=a/b/c&Preview';
249 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
250         $ENV{REQUEST_METHOD} = 'POST';
251         $ENV{SERVER_PORT} = '80';
252         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
253         $ENV{HTTP_HOST} = 'example.com';
254         $ENV{CONTENT_LENGTH} = length $in;
255 });
256 %bits = parse_cgi_content($content);
257 is($bits{basehref}, "/wiki/a/b/c/");
258 is($bits{stylehref}, "/wiki/style.css");
259 like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
260 is($bits{cgihref}, "/cgi-bin/ikiwiki.cgi");
261
262 #######################################################################
263 # site 2: static content and CGI are on different servers
264
265 writefile("test.setup", "t/tmp", <<EOF
266 # IkiWiki::Setup::Yaml - YAML formatted setup file
267 wikiname: this is the name of my wiki
268 srcdir: t/tmp/in
269 destdir: t/tmp/out
270 templatedir: templates
271 url: "http://static.example.com/"
272 cgiurl: "http://cgi.example.com/ikiwiki.cgi"
273 cgi_wrapper: t/tmp/ikiwiki.cgi
274 cgi_wrappermode: 0754
275 html5: 0
276 # make it easier to test previewing
277 add_plugins:
278 - anonok
279 anonok_pagespec: "*"
280 ENV: { 'PERL5LIB': '$PERL5LIB' }
281 EOF
282 );
283
284 ok(unlink("t/tmp/ikiwiki.cgi"));
285 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
286
287 # CGI wrapper should be exactly the requested mode
288 (undef, undef, $mode, undef, undef,
289         undef, undef, undef, undef, undef,
290         undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
291 is($mode & 07777, 0754);
292
293 ok(-e "t/tmp/out/a/b/c/index.html");
294 $content = readfile("t/tmp/out/a/b/c/index.html");
295 # no <base> on static HTML
296 unlike($content, qr{<base\W});
297 # url and cgiurl are not on the same host so the cgiurl has to be
298 # protocol-relative or absolute
299 like($content, qr{<a[^>]+href="(?:http:)?//cgi.example.com/ikiwiki.cgi\?do=prefs"});
300 # cross-links between static pages are still relative
301 like($content, qr{<li>A: <a href="../../">a</a></li>});
302 like($content, qr{<li>B: <a href="../">b</a></li>});
303 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
304
305 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
306         $ENV{REQUEST_METHOD} = 'GET';
307         $ENV{SERVER_PORT} = '80';
308         $ENV{SCRIPT_NAME} = '/ikiwiki.cgi';
309         $ENV{QUERY_STRING} = 'do=prefs';
310         $ENV{HTTP_HOST} = 'cgi.example.com';
311 });
312 %bits = parse_cgi_content($content);
313 like($bits{basehref}, qr{^http://static.example.com/$});
314 like($bits{stylehref}, qr{^(?:(?:http:)?//static.example.com)?/style.css$});
315 like($bits{tophref}, qr{^(?:http:)?//static.example.com/$});
316 like($bits{cgihref}, qr{^(?:(?:http:)?//cgi.example.com)?/ikiwiki.cgi$});
317
318 # when accessed via HTTPS, links are secure
319 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
320         $ENV{REQUEST_METHOD} = 'GET';
321         $ENV{SERVER_PORT} = '443';
322         $ENV{SCRIPT_NAME} = '/ikiwiki.cgi';
323         $ENV{QUERY_STRING} = 'do=prefs';
324         $ENV{HTTP_HOST} = 'cgi.example.com';
325         $ENV{HTTPS} = 'on';
326 });
327 %bits = parse_cgi_content($content);
328 like($bits{basehref}, qr{^https://static.example.com/$});
329 like($bits{stylehref}, qr{^(?:(?:https:)?//static.example.com)?/style.css$});
330 like($bits{tophref}, qr{^(?:https:)?//static.example.com/$});
331 like($bits{cgihref}, qr{^(?:(?:https:)?//cgi.example.com)?/ikiwiki.cgi$});
332
333 # when accessed via a different hostname, links to the CGI (only) should
334 # stay on that host?
335 $in = 'do=edit&page=a/b/c&Preview';
336 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
337         $ENV{REQUEST_METHOD} = 'POST';
338         $ENV{SERVER_PORT} = '80';
339         $ENV{SCRIPT_NAME} = '/ikiwiki.cgi';
340         $ENV{HTTP_HOST} = 'staging.example.net';
341         $ENV{CONTENT_LENGTH} = length $in;
342 });
343 %bits = parse_cgi_content($content);
344 like($bits{basehref}, qr{^http://static.example.com/a/b/c/$});
345 like($bits{stylehref}, qr{^(?:(?:http:)?//static.example.com|\.\./\.\./\.\.)/style.css$});
346 like($bits{tophref}, qr{^(?:(?:http:)?//static.example.com|\.\./\.\./\.\.)/$});
347 like($bits{cgihref}, qr{^(?:(?:http:)?//(?:staging\.example\.net|cgi\.example\.com))?/ikiwiki.cgi$});
348 TODO: {
349 local $TODO = "use self-referential CGI URL?";
350 like($bits{cgihref}, qr{^(?:(?:http:)?//staging.example.net)?/ikiwiki.cgi$});
351 }
352
353 writefile("test.setup", "t/tmp", <<EOF
354 # IkiWiki::Setup::Yaml - YAML formatted setup file
355 wikiname: this is the name of my wiki
356 srcdir: t/tmp/in
357 destdir: t/tmp/out
358 templatedir: templates
359 url: "http://static.example.com/"
360 cgiurl: "http://cgi.example.com/ikiwiki.cgi"
361 cgi_wrapper: t/tmp/ikiwiki.cgi
362 cgi_wrappermode: 0754
363 html5: 1
364 # make it easier to test previewing
365 add_plugins:
366 - anonok
367 anonok_pagespec: "*"
368 ENV: { 'PERL5LIB': '$PERL5LIB' }
369 EOF
370 );
371
372 ok(unlink("t/tmp/ikiwiki.cgi"));
373 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
374
375 # CGI wrapper should be exactly the requested mode
376 (undef, undef, $mode, undef, undef,
377         undef, undef, undef, undef, undef,
378         undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
379 is($mode & 07777, 0754);
380
381 ok(-e "t/tmp/out/a/b/c/index.html");
382 $content = readfile("t/tmp/out/a/b/c/index.html");
383 # no <base> on static HTML
384 unlike($content, qr{<base\W});
385 # url and cgiurl are not on the same host so the cgiurl has to be
386 # protocol-relative or absolute
387 like($content, qr{<a[^>]+href="(?:http:)?//cgi.example.com/ikiwiki.cgi\?do=prefs"});
388 # cross-links between static pages are still relative
389 like($content, qr{<li>A: <a href="../../">a</a></li>});
390 like($content, qr{<li>B: <a href="../">b</a></li>});
391 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
392
393 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
394         $ENV{REQUEST_METHOD} = 'GET';
395         $ENV{SERVER_PORT} = '80';
396         $ENV{SCRIPT_NAME} = '/ikiwiki.cgi';
397         $ENV{QUERY_STRING} = 'do=prefs';
398         $ENV{HTTP_HOST} = 'cgi.example.com';
399 });
400 %bits = parse_cgi_content($content);
401 is($bits{basehref}, "//static.example.com/");
402 is($bits{stylehref}, "//static.example.com/style.css");
403 is($bits{tophref}, "//static.example.com/");
404 is($bits{cgihref}, "//cgi.example.com/ikiwiki.cgi");
405
406 # when accessed via HTTPS, links are secure - in fact they're exactly the
407 # same as when accessed via HTTP
408 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
409         $ENV{REQUEST_METHOD} = 'GET';
410         $ENV{SERVER_PORT} = '443';
411         $ENV{SCRIPT_NAME} = '/ikiwiki.cgi';
412         $ENV{QUERY_STRING} = 'do=prefs';
413         $ENV{HTTP_HOST} = 'cgi.example.com';
414         $ENV{HTTPS} = 'on';
415 });
416 %bits = parse_cgi_content($content);
417 is($bits{basehref}, "//static.example.com/");
418 is($bits{stylehref}, "//static.example.com/style.css");
419 is($bits{tophref}, "//static.example.com/");
420 is($bits{cgihref}, "//cgi.example.com/ikiwiki.cgi");
421
422 # when accessed via a different hostname, links to the CGI (only) should
423 # stay on that host?
424 $in = 'do=edit&page=a/b/c&Preview';
425 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
426         $ENV{REQUEST_METHOD} = 'POST';
427         $ENV{SERVER_PORT} = '80';
428         $ENV{SCRIPT_NAME} = '/ikiwiki.cgi';
429         $ENV{HTTP_HOST} = 'staging.example.net';
430         $ENV{CONTENT_LENGTH} = length $in;
431 });
432 %bits = parse_cgi_content($content);
433 is($bits{basehref}, "//static.example.com/a/b/c/");
434 is($bits{stylehref}, "//static.example.com/style.css");
435 is($bits{tophref}, "../../../");
436 like($bits{cgihref}, qr{//(?:staging\.example\.net|cgi\.example\.com)/ikiwiki\.cgi});
437 TODO: {
438 local $TODO = "use self-referential CGI URL maybe?";
439 is($bits{cgihref}, "//staging.example.net/ikiwiki.cgi");
440 }
441
442 #######################################################################
443 # site 3: we specifically want everything to be secure
444
445 writefile("test.setup", "t/tmp", <<EOF
446 # IkiWiki::Setup::Yaml - YAML formatted setup file
447 wikiname: this is the name of my wiki
448 srcdir: t/tmp/in
449 destdir: t/tmp/out
450 templatedir: templates
451 url: "https://example.com/wiki/"
452 cgiurl: "https://example.com/cgi-bin/ikiwiki.cgi"
453 cgi_wrapper: t/tmp/ikiwiki.cgi
454 cgi_wrappermode: 0754
455 html5: 0
456 # make it easier to test previewing
457 add_plugins:
458 - anonok
459 anonok_pagespec: "*"
460 ENV: { 'PERL5LIB': '$PERL5LIB' }
461 EOF
462 );
463
464 ok(unlink("t/tmp/ikiwiki.cgi"));
465 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
466
467 # CGI wrapper should be exactly the requested mode
468 (undef, undef, $mode, undef, undef,
469         undef, undef, undef, undef, undef,
470         undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
471 is($mode & 07777, 0754);
472
473 ok(-e "t/tmp/out/a/b/c/index.html");
474 $content = readfile("t/tmp/out/a/b/c/index.html");
475 # no <base> on static HTML
476 unlike($content, qr{<base\W});
477 # url and cgiurl are on the same host so the cgiurl is host-relative
478 like($content, qr{<a[^>]+href="/cgi-bin/ikiwiki.cgi\?do=prefs"});
479 # cross-links between static pages are relative
480 like($content, qr{<li>A: <a href="../../">a</a></li>});
481 like($content, qr{<li>B: <a href="../">b</a></li>});
482 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
483
484 # when accessed via HTTPS, links are secure
485 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
486         $ENV{REQUEST_METHOD} = 'GET';
487         $ENV{SERVER_PORT} = '443';
488         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
489         $ENV{QUERY_STRING} = 'do=prefs';
490         $ENV{HTTP_HOST} = 'example.com';
491         $ENV{HTTPS} = 'on';
492 });
493 %bits = parse_cgi_content($content);
494 is($bits{basehref}, "https://example.com/wiki/");
495 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
496 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
497 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
498
499 # when not accessed via HTTPS, links should still be secure
500 # (but if this happens, that's a sign of web server misconfiguration)
501 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
502         $ENV{REQUEST_METHOD} = 'GET';
503         $ENV{SERVER_PORT} = '80';
504         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
505         $ENV{QUERY_STRING} = 'do=prefs';
506         $ENV{HTTP_HOST} = 'example.com';
507 });
508 %bits = parse_cgi_content($content);
509 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
510 TODO: {
511 local $TODO = "treat https in configured url, cgiurl as required?";
512 is($bits{basehref}, "https://example.com/wiki/");
513 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
514 }
515 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
516
517 # when accessed via a different hostname, links stay on that host
518 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
519         $ENV{REQUEST_METHOD} = 'GET';
520         $ENV{SERVER_PORT} = '443';
521         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
522         $ENV{QUERY_STRING} = 'do=prefs';
523         $ENV{HTTP_HOST} = 'staging.example.net';
524         $ENV{HTTPS} = 'on';
525 });
526 %bits = parse_cgi_content($content);
527 is($bits{basehref}, "https://staging.example.net/wiki/");
528 like($bits{stylehref}, qr{^(?:(?:https:)?//staging.example.net)?/wiki/style.css$});
529 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
530 like($bits{cgihref}, qr{^(?:(?:https:)?//staging.example.net)?/cgi-bin/ikiwiki.cgi$});
531
532 # previewing a page
533 $in = 'do=edit&page=a/b/c&Preview';
534 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
535         $ENV{REQUEST_METHOD} = 'POST';
536         $ENV{SERVER_PORT} = '443';
537         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
538         $ENV{HTTP_HOST} = 'example.com';
539         $ENV{CONTENT_LENGTH} = length $in;
540         $ENV{HTTPS} = 'on';
541 });
542 %bits = parse_cgi_content($content);
543 is($bits{basehref}, "https://example.com/wiki/a/b/c/");
544 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
545 like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
546 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
547
548 # not testing html5: 0 here because that ends up identical to site 1
549
550 #######################################################################
551 # site 4 (NetBSD wiki): CGI is secure, static content doesn't have to be
552
553 writefile("test.setup", "t/tmp", <<EOF
554 # IkiWiki::Setup::Yaml - YAML formatted setup file
555 wikiname: this is the name of my wiki
556 srcdir: t/tmp/in
557 destdir: t/tmp/out
558 templatedir: templates
559 url: "http://example.com/wiki/"
560 cgiurl: "https://example.com/cgi-bin/ikiwiki.cgi"
561 cgi_wrapper: t/tmp/ikiwiki.cgi
562 cgi_wrappermode: 0754
563 html5: 0
564 # make it easier to test previewing
565 add_plugins:
566 - anonok
567 anonok_pagespec: "*"
568 ENV: { 'PERL5LIB': '$PERL5LIB' }
569 EOF
570 );
571
572 ok(unlink("t/tmp/ikiwiki.cgi"));
573 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
574
575 # CGI wrapper should be exactly the requested mode
576 (undef, undef, $mode, undef, undef,
577         undef, undef, undef, undef, undef,
578         undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
579 is($mode & 07777, 0754);
580
581 ok(-e "t/tmp/out/a/b/c/index.html");
582 $content = readfile("t/tmp/out/a/b/c/index.html");
583 # no <base> on static HTML
584 unlike($content, qr{<base\W});
585 # url and cgiurl are on the same host but different schemes
586 like($content, qr{<a[^>]+href="https://example.com/cgi-bin/ikiwiki.cgi\?do=prefs"});
587 # cross-links between static pages are relative
588 like($content, qr{<li>A: <a href="../../">a</a></li>});
589 like($content, qr{<li>B: <a href="../">b</a></li>});
590 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
591
592 # when accessed via HTTPS, links are secure (to avoid mixed-content)
593 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
594         $ENV{REQUEST_METHOD} = 'GET';
595         $ENV{SERVER_PORT} = '443';
596         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
597         $ENV{QUERY_STRING} = 'do=prefs';
598         $ENV{HTTP_HOST} = 'example.com';
599         $ENV{HTTPS} = 'on';
600 });
601 %bits = parse_cgi_content($content);
602 is($bits{basehref}, "https://example.com/wiki/");
603 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
604 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
605 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
606
607 # when not accessed via HTTPS, ???
608 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
609         $ENV{REQUEST_METHOD} = 'GET';
610         $ENV{SERVER_PORT} = '80';
611         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
612         $ENV{QUERY_STRING} = 'do=prefs';
613         $ENV{HTTP_HOST} = 'example.com';
614 });
615 %bits = parse_cgi_content($content);
616 like($bits{basehref}, qr{^https?://example.com/wiki/$});
617 like($bits{stylehref}, qr{^(?:(?:https?:)?//example.com)?/wiki/style.css$});
618 like($bits{tophref}, qr{^(?:(?:https?://example.com)?/wiki|\.)/$});
619 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
620
621 # when accessed via a different hostname, links stay on that host
622 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
623         $ENV{REQUEST_METHOD} = 'GET';
624         $ENV{SERVER_PORT} = '443';
625         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
626         $ENV{QUERY_STRING} = 'do=prefs';
627         $ENV{HTTP_HOST} = 'staging.example.net';
628         $ENV{HTTPS} = 'on';
629 });
630 %bits = parse_cgi_content($content);
631 # because the static and dynamic stuff is on the same server, we assume that
632 # both are also on the staging server
633 like($bits{basehref}, qr{^https://staging.example.net/wiki/$});
634 like($bits{stylehref}, qr{^(?:(?:https:)?//staging.example.net)?/wiki/style.css$});
635 like($bits{tophref}, qr{^(?:(?:(?:https:)?//staging.example.net)?/wiki|\.)/$});
636 like($bits{cgihref}, qr{^(?:(?:https:)?//(?:staging\.example\.net|example\.com))?/cgi-bin/ikiwiki.cgi$});
637 TODO: {
638 local $TODO = "this should really point back to itself but currently points to example.com";
639 like($bits{cgihref}, qr{^(?:(?:https:)?//staging.example.net)?/cgi-bin/ikiwiki.cgi$});
640 }
641
642 # previewing a page
643 $in = 'do=edit&page=a/b/c&Preview';
644 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
645         $ENV{REQUEST_METHOD} = 'POST';
646         $ENV{SERVER_PORT} = '443';
647         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
648         $ENV{HTTP_HOST} = 'example.com';
649         $ENV{CONTENT_LENGTH} = length $in;
650         $ENV{HTTPS} = 'on';
651 });
652 %bits = parse_cgi_content($content);
653 is($bits{basehref}, "https://example.com/wiki/a/b/c/");
654 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
655 like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
656 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
657
658 writefile("test.setup", "t/tmp", <<EOF
659 # IkiWiki::Setup::Yaml - YAML formatted setup file
660 wikiname: this is the name of my wiki
661 srcdir: t/tmp/in
662 destdir: t/tmp/out
663 templatedir: templates
664 url: "http://example.com/wiki/"
665 cgiurl: "https://example.com/cgi-bin/ikiwiki.cgi"
666 cgi_wrapper: t/tmp/ikiwiki.cgi
667 cgi_wrappermode: 0754
668 html5: 1
669 # make it easier to test previewing
670 add_plugins:
671 - anonok
672 anonok_pagespec: "*"
673 ENV: { 'PERL5LIB': '$PERL5LIB' }
674 EOF
675 );
676
677 ok(unlink("t/tmp/ikiwiki.cgi"));
678 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
679
680 # CGI wrapper should be exactly the requested mode
681 (undef, undef, $mode, undef, undef,
682         undef, undef, undef, undef, undef,
683         undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
684 is($mode & 07777, 0754);
685
686 ok(-e "t/tmp/out/a/b/c/index.html");
687 $content = readfile("t/tmp/out/a/b/c/index.html");
688 # no <base> on static HTML
689 unlike($content, qr{<base\W});
690 # url and cgiurl are on the same host but different schemes
691 like($content, qr{<a[^>]+href="https://example.com/cgi-bin/ikiwiki.cgi\?do=prefs"});
692 # cross-links between static pages are relative
693 like($content, qr{<li>A: <a href="../../">a</a></li>});
694 like($content, qr{<li>B: <a href="../">b</a></li>});
695 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
696
697 # when accessed via HTTPS, links are secure (to avoid mixed-content)
698 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
699         $ENV{REQUEST_METHOD} = 'GET';
700         $ENV{SERVER_PORT} = '443';
701         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
702         $ENV{QUERY_STRING} = 'do=prefs';
703         $ENV{HTTP_HOST} = 'example.com';
704         $ENV{HTTPS} = 'on';
705 });
706 %bits = parse_cgi_content($content);
707 is($bits{basehref}, "/wiki/");
708 is($bits{stylehref}, "/wiki/style.css");
709 is($bits{tophref}, "/wiki/");
710 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
711
712 # when not accessed via HTTPS, ???
713 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
714         $ENV{REQUEST_METHOD} = 'GET';
715         $ENV{SERVER_PORT} = '80';
716         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
717         $ENV{QUERY_STRING} = 'do=prefs';
718         $ENV{HTTP_HOST} = 'example.com';
719 });
720 %bits = parse_cgi_content($content);
721 like($bits{basehref}, qr{^(?:https?://example.com)?/wiki/$});
722 like($bits{stylehref}, qr{^(?:(?:https?:)?//example.com)?/wiki/style.css$});
723 like($bits{tophref}, qr{^(?:(?:https?://example.com)?/wiki|\.)/$});
724 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
725
726 # when accessed via a different hostname, links stay on that host
727 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
728         $ENV{REQUEST_METHOD} = 'GET';
729         $ENV{SERVER_PORT} = '443';
730         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
731         $ENV{QUERY_STRING} = 'do=prefs';
732         $ENV{HTTP_HOST} = 'staging.example.net';
733         $ENV{HTTPS} = 'on';
734 });
735 %bits = parse_cgi_content($content);
736 # because the static and dynamic stuff is on the same server, we assume that
737 # both are also on the staging server
738 is($bits{basehref}, "/wiki/");
739 is($bits{stylehref}, "/wiki/style.css");
740 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
741 like($bits{cgihref}, qr{^(?:(?:https:)?//(?:example\.com|staging\.example\.net))?/cgi-bin/ikiwiki.cgi$});
742 TODO: {
743 local $TODO = "this should really point back to itself but currently points to example.com";
744 like($bits{cgihref}, qr{^(?:(?:https:)?//staging.example.net)?/cgi-bin/ikiwiki.cgi$});
745 }
746
747 # previewing a page
748 $in = 'do=edit&page=a/b/c&Preview';
749 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
750         $ENV{REQUEST_METHOD} = 'POST';
751         $ENV{SERVER_PORT} = '443';
752         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
753         $ENV{HTTP_HOST} = 'example.com';
754         $ENV{CONTENT_LENGTH} = length $in;
755         $ENV{HTTPS} = 'on';
756 });
757 %bits = parse_cgi_content($content);
758 is($bits{basehref}, "/wiki/a/b/c/");
759 is($bits{stylehref}, "/wiki/style.css");
760 like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
761 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
762
763 # Deliberately not testing https static content with http cgiurl,
764 # because that makes remarkably little sense.
765
766 #######################################################################
767 # site 5: w3mmode, as documented in [[w3mmode]]
768
769 writefile("test.setup", "t/tmp", <<EOF
770 # IkiWiki::Setup::Yaml - YAML formatted setup file
771 wikiname: this is the name of my wiki
772 srcdir: t/tmp/in
773 destdir: t/tmp/out
774 templatedir: templates
775 cgiurl: ikiwiki.cgi
776 w3mmode: 1
777 cgi_wrapper: t/tmp/ikiwiki.cgi
778 cgi_wrappermode: 0754
779 html5: 0
780 add_plugins:
781 - anonok
782 anonok_pagespec: "*"
783 ENV: { 'PERL5LIB': '$PERL5LIB' }
784 EOF
785 );
786
787 ok(unlink("t/tmp/ikiwiki.cgi"));
788 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
789
790 # CGI wrapper should be exactly the requested mode
791 (undef, undef, $mode, undef, undef,
792         undef, undef, undef, undef, undef,
793         undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
794 is($mode & 07777, 0754);
795
796 ok(-e "t/tmp/out/a/b/c/index.html");
797 $content = readfile("t/tmp/out/a/b/c/index.html");
798 # no <base> on static HTML
799 unlike($content, qr{<base\W});
800 # FIXME: does /$LIB/ikiwiki-w3m.cgi work under w3m?
801 like($content, qr{<a[^>]+href="(?:file://)?/\$LIB/ikiwiki-w3m.cgi/ikiwiki.cgi\?do=prefs"});
802 # cross-links between static pages are still relative
803 like($content, qr{<li>A: <a href="../../">a</a></li>});
804 like($content, qr{<li>B: <a href="../">b</a></li>});
805 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
806
807 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
808         $ENV{REQUEST_METHOD} = 'GET';
809         $ENV{PATH_INFO} = '/ikiwiki.cgi';
810         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki-w3m.cgi';
811         $ENV{QUERY_STRING} = 'do=prefs';
812 });
813 %bits = parse_cgi_content($content);
814 like($bits{tophref}, qr{^(?:\Q$pwd\E/t/tmp/out|\.)/$});
815 like($bits{cgihref}, qr{^(?:file://)?/\$LIB/ikiwiki-w3m.cgi/ikiwiki.cgi$});
816 like($bits{basehref}, qr{^(?:(?:file:)?//)?\Q$pwd\E/t/tmp/out/$});
817 like($bits{stylehref}, qr{^(?:(?:(?:file:)?//)?\Q$pwd\E/t/tmp/out|\.)/style.css$});
818
819 writefile("test.setup", "t/tmp", <<EOF
820 # IkiWiki::Setup::Yaml - YAML formatted setup file
821 wikiname: this is the name of my wiki
822 srcdir: t/tmp/in
823 destdir: t/tmp/out
824 templatedir: templates
825 cgiurl: ikiwiki.cgi
826 w3mmode: 1
827 cgi_wrapper: t/tmp/ikiwiki.cgi
828 cgi_wrappermode: 0754
829 html5: 1
830 add_plugins:
831 - anonok
832 anonok_pagespec: "*"
833 ENV: { 'PERL5LIB': '$PERL5LIB' }
834 EOF
835 );
836
837 ok(unlink("t/tmp/ikiwiki.cgi"));
838 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
839
840 # CGI wrapper should be exactly the requested mode
841 (undef, undef, $mode, undef, undef,
842         undef, undef, undef, undef, undef,
843         undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
844 is($mode & 07777, 0754);
845
846 ok(-e "t/tmp/out/a/b/c/index.html");
847 $content = readfile("t/tmp/out/a/b/c/index.html");
848 # no <base> on static HTML
849 unlike($content, qr{<base\W});
850 # FIXME: does /$LIB/ikiwiki-w3m.cgi work under w3m?
851 like($content, qr{<a[^>]+href="(?:file://)?/\$LIB/ikiwiki-w3m.cgi/ikiwiki.cgi\?do=prefs"});
852 # cross-links between static pages are still relative
853 like($content, qr{<li>A: <a href="../../">a</a></li>});
854 like($content, qr{<li>B: <a href="../">b</a></li>});
855 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
856
857 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
858         $ENV{REQUEST_METHOD} = 'GET';
859         $ENV{PATH_INFO} = '/ikiwiki.cgi';
860         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki-w3m.cgi';
861         $ENV{QUERY_STRING} = 'do=prefs';
862 });
863 %bits = parse_cgi_content($content);
864 like($bits{tophref}, qr{^(?:\Q$pwd\E/t/tmp/out|\.)/$});
865 like($bits{cgihref}, qr{^(?:file://)?/\$LIB/ikiwiki-w3m.cgi/ikiwiki.cgi$});
866 like($bits{basehref}, qr{^(?:(?:file:)?//)?\Q$pwd\E/t/tmp/out/$});
867 like($bits{stylehref}, qr{^(?:(?:(?:file:)?//)?\Q$pwd\E/t/tmp/out|\.)/style.css$});
868
869 #######################################################################
870 # site 6: we're behind a reverse-proxy
871
872 writefile("test.setup", "t/tmp", <<EOF
873 # IkiWiki::Setup::Yaml - YAML formatted setup file
874 wikiname: this is the name of my wiki
875 srcdir: t/tmp/in
876 destdir: t/tmp/out
877 templatedir: templates
878 url: "https://example.com/wiki/"
879 cgiurl: "https://example.com/cgi-bin/ikiwiki.cgi"
880 cgi_wrapper: t/tmp/ikiwiki.cgi
881 cgi_wrappermode: 0754
882 html5: 0
883 # make it easier to test previewing
884 add_plugins:
885 - anonok
886 anonok_pagespec: "*"
887 reverse_proxy: 1
888 ENV: { 'PERL5LIB': '$PERL5LIB' }
889 EOF
890 );
891
892 ok(unlink("t/tmp/ikiwiki.cgi"));
893 ok(! system("./ikiwiki.out --setup t/tmp/test.setup --rebuild --wrappers"));
894
895 # CGI wrapper should be exactly the requested mode
896 (undef, undef, $mode, undef, undef,
897         undef, undef, undef, undef, undef,
898         undef, undef, undef) = stat("t/tmp/ikiwiki.cgi");
899 is($mode & 07777, 0754);
900
901 ok(-e "t/tmp/out/a/b/c/index.html");
902 $content = readfile("t/tmp/out/a/b/c/index.html");
903 # no <base> on static HTML
904 unlike($content, qr{<base\W});
905 # url and cgiurl are on the same host so the cgiurl is host-relative
906 like($content, qr{<a[^>]+href="/cgi-bin/ikiwiki.cgi\?do=prefs"});
907 # cross-links between static pages are relative
908 like($content, qr{<li>A: <a href="../../">a</a></li>});
909 like($content, qr{<li>B: <a href="../">b</a></li>});
910 like($content, qr{<li>E: <a href="../../d/e/">e</a></li>});
911
912 # because we are behind a reverse-proxy we must assume that
913 # we're being accessed by the configured cgiurl
914 run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
915         $ENV{REQUEST_METHOD} = 'GET';
916         $ENV{SERVER_PORT} = '80';
917         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
918         $ENV{QUERY_STRING} = 'do=prefs';
919         $ENV{HTTP_HOST} = 'localhost';
920 });
921 %bits = parse_cgi_content($content);
922 like($bits{tophref}, qr{^(?:/wiki|\.)/$});
923 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
924 is($bits{basehref}, "https://example.com/wiki/");
925 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
926
927 # previewing a page
928 $in = 'do=edit&page=a/b/c&Preview';
929 run(["./t/tmp/ikiwiki.cgi"], \$in, \$content, init => sub {
930         $ENV{REQUEST_METHOD} = 'POST';
931         $ENV{SERVER_PORT} = '80';
932         $ENV{SCRIPT_NAME} = '/cgi-bin/ikiwiki.cgi';
933         $ENV{HTTP_HOST} = 'localhost';
934         $ENV{CONTENT_LENGTH} = length $in;
935 });
936 %bits = parse_cgi_content($content);
937 like($bits{tophref}, qr{^(?:/wiki|\.\./\.\./\.\.)/$});
938 like($bits{cgihref}, qr{^(?:(?:https:)?//example.com)?/cgi-bin/ikiwiki.cgi$});
939 is($bits{basehref}, "https://example.com/wiki/a/b/c/");
940 like($bits{stylehref}, qr{^(?:(?:https:)?//example.com)?/wiki/style.css$});
941
942 # not testing html5: 1 because it would be the same as site 1 -
943 # the reverse_proxy config option is unnecessary under html5
944
945 done_testing;