Use protocol-relative URIs if cgiurl and url differ only by authority (hostname)
authorSimon McVittie <smcv@debian.org>
Sun, 5 Oct 2014 14:56:19 +0000 (15:56 +0100)
committerSimon McVittie <smcv@debian.org>
Sun, 5 Oct 2014 14:56:19 +0000 (15:56 +0100)
IkiWiki.pm
doc/todo/Protocol_relative_urls_for_stylesheet_linking.mdwn
t/relativity.t
t/urlto.t

index d5d11ee857c02b1520fc6a971032cc592df78d23..c1518a2ae058a1682d883f628a9f7fb8fae2c97f 100644 (file)
@@ -613,12 +613,19 @@ sub checkconfig () {
 
                        $local_cgiurl = $cgiurl->path;
 
-                       if ($cgiurl->scheme ne $baseurl->scheme or
-                               $cgiurl->authority ne $baseurl->authority) {
+                       if ($cgiurl->scheme ne $baseurl->scheme) {
                                # too far apart, fall back to absolute URLs
                                $local_url = "$config{url}/";
                                $local_cgiurl = $config{cgiurl};
                        }
+                       elsif ($cgiurl->authority ne $baseurl->authority) {
+                               # slightly too far apart, fall back to
+                               # protocol-relative URLs
+                               $local_url = "$config{url}/";
+                               $local_url =~ s{^https?://}{//};
+                               $local_cgiurl = $config{cgiurl};
+                               $local_cgiurl =~ s{^https?://}{//};
+                       }
                }
 
                $local_url =~ s{//$}{/};
index ccbaf4e73711af75936d9a1ee6323242ab962617..0ab4814e6bc06cf198ce45dc7c9447157a434432 100644 (file)
@@ -26,6 +26,14 @@ but this breaks all sorts of things, like the 404 plugin and wiki rebuilds will
 > protocol-relative URLs in this situation, but it isn't clear to me how
 > widely-supported those are.
 >
+>> HTML5 says protocol-relative URLs work, and they seem to be widely
+>> supported in practice, so I've changed the rule to: if the url and cgiurl
+>> share a scheme (protocol) but differ only by hostname, use `//foo/bar`
+>> protocol-relative URLs. This partially addresses this todo.
+>> I'm still thinking about what the right thing is for more complicated
+>> situations: see [[todo/design for cross-linking between content and CGI]].
+>> --[[smcv]]
+>
 > If you set both the `$config{url}` and `$config{cgiurl}` to https, but make
 > the resulting HTML available over HTTP as well as HTTPS, that should work
 > fine - accesses will be over http until the user either explicitly
index eb6cc448a7929a3b3e661686941d2a991580f045..6c4d1107e2c7bd11ac417b2b51f679a21a6d264c 100755 (executable)
@@ -227,13 +227,10 @@ run(["./t/tmp/ikiwiki.cgi"], \undef, \$content, init => sub {
        $ENV{HTTPS} = 'on';
 });
 %bits = parse_cgi_content($content);
-TODO: {
-local $TODO = "avoid mixed content";
 like($bits{basehref}, qr{^https://static.example.com/$});
 like($bits{stylehref}, qr{^(?:(?:https:)?//static.example.com)?/style.css$});
 like($bits{tophref}, qr{^(?:https:)?//static.example.com/$});
 like($bits{cgihref}, qr{^(?:(?:https:)?//cgi.example.com)?/ikiwiki.cgi$});
-}
 
 # when accessed via a different hostname, links to the CGI (only) should
 # stay on that host?
index 338632e9450399a02a2fa416f0746996e33d80ad..025409b7fffe9c69cdd5542547793baaf8e64081 100755 (executable)
--- a/t/urlto.t
+++ b/t/urlto.t
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 use warnings;
 use strict;
-use Test::More tests => 26;
+use Test::More tests => 31;
 
 BEGIN { use_ok("IkiWiki"); }
 
@@ -41,11 +41,20 @@ is(IkiWiki::urlto('', 'penguin/herring'), "../../");
 is(IkiWiki::cgiurl(cgiurl => 'https://foo/ikiwiki'), "https://foo/ikiwiki");
 is(IkiWiki::cgiurl(do => 'badger', cgiurl => 'https://foo/ikiwiki'), "https://foo/ikiwiki?do=badger");
 
-# with url and cgiurl on different sites, "local" degrades to absolute
+# with url and cgiurl on different sites, "local" degrades to protocol-relative
 $IkiWiki::config{url} = "http://example.co.uk/~smcv";
 $IkiWiki::config{cgiurl} = "http://dynamic.example.co.uk/~smcv/ikiwiki.cgi";
 is(IkiWiki::checkconfig(), 1);
-is(IkiWiki::cgiurl(), "http://dynamic.example.co.uk/~smcv/ikiwiki.cgi");
+is(IkiWiki::cgiurl(), "//dynamic.example.co.uk/~smcv/ikiwiki.cgi");
+is(IkiWiki::baseurl(undef), "//example.co.uk/~smcv/");
+is(IkiWiki::urlto('stoats', undef), "//example.co.uk/~smcv/stoats/");
+is(IkiWiki::urlto('', undef), "//example.co.uk/~smcv/");
+
+# with url and cgiurl on different schemes, "local" degrades to absolute
+$IkiWiki::config{url} = "http://example.co.uk/~smcv";
+$IkiWiki::config{cgiurl} = "https://dynamic.example.co.uk/~smcv/ikiwiki.cgi";
+is(IkiWiki::checkconfig(), 1);
+is(IkiWiki::cgiurl(), "https://dynamic.example.co.uk/~smcv/ikiwiki.cgi");
 is(IkiWiki::baseurl(undef), "http://example.co.uk/~smcv/");
 is(IkiWiki::urlto('stoats', undef), "http://example.co.uk/~smcv/stoats/");
 is(IkiWiki::urlto('', undef), "http://example.co.uk/~smcv/");