]> sipb.mit.edu Git - ikiwiki.git/blob - doc/todo/want_to_avoid_ikiwiki_using_http_or_https_in_urls_to_allow_serving_both.mdwn
143bf0edcdaa79dd4e37cb1758c187be0083a55a
[ikiwiki.git] / doc / todo / want_to_avoid_ikiwiki_using_http_or_https_in_urls_to_allow_serving_both.mdwn
1 ## current status
2
3 99% of the way there, but:
4
5 * CGI pages, with the exception of edit pages, set `<base>` to
6   `$config{url}`
7
8   I had to revert using `baseurl(undef)` for that, because it needs
9   to be a full url.
10
11   Ideally, baseurl would return an absolute url derived from the url
12   being used to access the cgi, but that needs access to the CGI object,
13   which it does not currently have. Similarly, `misctemplate`
14   does not have access to the CGI object, so it cannot use it to
15   generate a better baseurl. Not sure yet what to do; may have to thread
16   a cgi parameter through all the calls to misctemplate. --[[Joey]]
17
18 * Using `do=goto` to go to a comment or recentchanges item
19   will redirect to the `$config{url}`-based url, since the
20   permalinks are made to be absolute urls now.
21
22   Fixing this would seem to involve making meta force permalinks
23   to absolute urls when fulling out templates, while allowing them
24   to be left as partial urls internally, for use by goto. --[[Joey]]
25
26   > This reversion has now been fixed. --[[Joey]]
27
28 ## old attempt
29
30 It looks like all links in websites are absolute paths, this has some limitations:
31
32 * If connecting to website via https://... all links will take you back to http://
33 * Makes it harder to mirror website via HTML version, as all links have to be updated.
34
35 It would be good if relative paths could be used instead, so the transport method isn't changed unless specifically requested.
36
37 -- Brian May
38
39 > Er, which absolute links are you talking about? If you view the source
40 > to this page, you'll find links such as "../favicon.ico", "../style.css",
41 > "../../", and "../". The only absolute links are to CGIs and the w3c DTD.
42 > --[[Joey]]
43
44 >> The problem is within the CGI script. The links within the HTML page are all
45 >> absolute, including links to the css file. Having a http links within a HTML
46 >> page retrieved using https upset most browsers (I think). Also if I push cancel
47 >> on the edit page in https, I end up at at http page. -- Brian May
48
49 >>> Ikiwiki does not hardcode http links anywhere. If you don't want
50 >>> it to use such links, change your configuration to use https
51 >>> consistently. --[[Joey]]
52
53 Errr... That is not a solution, that is a work around. ikiwiki does not hard
54 code the absolute paths, but absolute paths are hard coded in the configuration
55 file. If you want to serve your website so that the majority of users can see
56 it as http, including in rss feeds (this allows proxy caches to cache the
57 contents and has reduced load requirements), but editing is done via https for
58 increased security, it is not possible. I have some ideas how this can be
59 implemented (as ikiwiki has the absolute path to the CGI script and the
60 absolute path to the destination, it should be possible to generate a relative
61 path from one to the other), although some minor issues still need to be
62 resolved. -- Brian May
63
64 I noticed the links to the images on <http://ikiwiki.info/recentchanges/> are
65 also absolute, that is <http://ikiwiki.info/wikiicons/diff.png>; this seems
66 surprising, as the change.tmpl file uses &lt;TMPL_VAR BASEURL&gt; which seems
67 to do the right thing in page.tmpl, but not for change.tmpl. Where is BASEURL
68 set? -- Brian May
69
70 > The use of an absolute baseurl in change.tmpl is a special case. --[[Joey]]
71
72 So I'm facing this same issue. I have a wiki which needs to be accessed on
73 three different URLs(!) and the hard coding of the URL from the setup file is
74 becoming a problem for me. Is there anything I can do here? --[[Perry]]
75
76 > I remain puzzled by the problem that Brian is discussing. I don't see
77 > why you can't just set the cgiurl and url to a https url, and serve
78 > the site using both http and https.
79
80 > Just for example, <https://kitenet.net/> is an ikiwiki, and it is accessible
81 > via https or http, and if you use https, links will remain on https (except
82 > for links using the cgi, which I could fix by changing the cgiurl to https).
83
84 > I think it's possible ikiwiki used to have some
85 > absolute urls that have been fixed since Brian filed the bug. --[[Joey]]  
86
87 [[wishlist]]
88
89 ----
90
91 [[!toggle id="smcv-https" text="Some discussion of a rejected implementation, smcv/https."]]
92 [[!toggleable id="smcv-https" text="""
93
94 [[!template id=gitbranch branch=smcv/https author="[[smcv]]"]]
95
96 For a while I've been using a configuration where each wiki has a HTTP and
97 a HTTPS mirror, and updating one automatically updates the other, but
98 that seems unnecessarily complicated. My `https` branch adds `https_url`
99 and `https_cgiurl` config options which can be used to provide a HTTPS
100 variant of an existing site; the CGI script automatically detects whether
101 it was accessed over HTTPS and switches to the other one.
102
103 This required some refactoring, which might be worth merging even if
104 you don't like my approach:
105
106 * change `IkiWiki::cgiurl` to return the equivalent of `$config{cgiurl}` if
107   called with no parameters, and change all plugins to indirect through it
108   (then I only need to change that one function for the HTTPS hack)
109
110 * `IkiWiki::baseurl` already has similar behaviour, so change nearly all
111   references to the `$config{url}` to call `baseurl` (a couple of references
112   specifically wanted the top-level public URL for Google or Blogspam rather
113   than a URL for the user's browser, so I left those alone)
114
115 --[[smcv]]
116
117 > The justification for your patch seems to be wanting to use a different
118 > domain, like secure.foo.com, for https? Can you really not just configure
119 > both url and cgiurl to use `https://secure.foo.com/...` and rely on
120 > relative links to keep users of `http://insecure.foo.com/` on http until
121 > they need to use the cgi? 
122
123 >> My problem with that is that uses of the CGI aren't all equal (and that
124 >> the CA model is broken). You could put CGI uses in two classes:
125 >>
126 >> - websetup and other "serious" things (for the sites I'm running, which
127 >>   aren't very wiki-like, editing pages is also in this class).
128 >>   I'd like to be able to let privileged users log in over
129 >>   https with httpauth (or possibly even a client certificate), and I don't
130 >>   mind teaching these few people how to do the necessary contortions to
131 >>   enable something like CACert.
132 >>
133 >> - Random users making limited use of the CGI: do=goto, do=404, and
134 >>   commenting with an OpenID. I don't think it's realistic to expect
135 >>   users to jump through all the CA hoops to get CACert installed for that,
136 >>   which leaves their browsers being actively obstructive, unless I either
137 >>   pay the CA tax (per subdomain) to get "real" certificates, or use plain
138 >>   http.
139 >>
140 >> On a more wiki-like wiki, the second group would include normal page edits.
141 >>
142 >>> I see your use case. It still seems to me that for the more common
143 >>> case where CA tax has been paid (getting a cert that is valid for
144 >>> multiple subdomains should be doable?), having anything going through the
145 >>> cgiurl upgrade to https would be ok. In that case, http is just an
146 >>> optimisation for low-value, high-aggregate-bandwidth type uses, so a
147 >>> little extra https on the side is not a big deal. --[[Joey]]
148 >>
149 >> Perhaps I'm doing this backwards, and instead of having the master
150 >> `url`/`cgiurl` be the HTTP version and providing tweakables to override
151 >> these with HTTPS, I should be overriding particular uses to plain HTTP...
152 >>
153 >> --[[smcv]]
154 >>> 
155 >>> Maybe, or I wonder if you could just use RewriteEngine for such selective
156 >>> up/downgrading. Match on `do=(edit|create|prefs)`. --[[Joey]]
157
158 > I'm unconvinced.
159
160 > `Ikiwiki::baseurl()."foo"` just seems to be asking for trouble,
161 > ie being accidentially written as `IkiWiki::baseurl("foo")`,
162 > which will fail when foo is not a page, but some file.
163
164 >> That's a good point. --s
165
166 > I see multiple places (inline.pm, meta.pm, poll.pm, recentchanges.pm)
167 > where it will now put the https url into a static page if the build
168 > happens to be done by the cgi accessed via https, but not otherwise.
169 > I would rather not have to audit for such problems going forward.
170
171 >> Yes, that's a problem with this approach (either way round). Perhaps
172 >> making it easier to run two mostly-synched copies like I was previously
173 >> doing is the only solution... --s
174
175 """]]
176
177 ----
178
179 [[!template id=gitbranch branch=smcv/ready/localurl author="[[smcv]]"]]
180 [[!tag patch]]
181
182 OK, here's an alternative approach, closer in spirit to what was initially
183 requested. I included a regression test for `urlto`, `baseurl` and `cgiurl`,
184 now that they have slightly more complex behaviour.
185
186 The idea is that in the common case, the CGI and the pages will reside on the
187 same server, so they can use "semi-absolute" URLs (`/ikiwiki.cgi`, `/style.css`,
188 `/bugs/done`) to refer to each other. Most redirects, form actions, links etc.
189 can safely use this form rather than the fully-absolute URL.
190
191 The initial version of the branch had config options `local_url` and
192 `local_cgiurl`, but they're now automatically computed by checking
193 whether `url` and `cgiurl` are on the same server with the the same URL
194 scheme. In theory you could use things like `//static.example.com/wiki/`
195 and `//dynamic.example.com/ikiwiki.cgi` to preserve choice of http/https
196 while switching server, but I don't know how consistently browsers
197 support that.
198
199 "local" here is short for "locally valid", because these URLs are neither
200 fully relative nor fully absolute, and there doesn't seem to be a good name
201 for them...
202
203 I've tested this on a demo website with the CGI enabled, and it seemed to
204 work nicely (there might be bugs in some plugins, I didn't try all of them).
205 The branch at [[todo/use secure cookies for SSL logins]] goes well with
206 this one.
207
208 The `$config{url}` and `$config{cgiurl}` are both HTTP, but if I enable
209 `httpauth`, set `cgiauthurl` to a HTTPS version of the same site and log
210 in via that, links all end up in the HTTPS version.
211
212 New API added by this branch:
213
214 * `urlto(x, y, 'local')` uses `$local_url` instead of `$config{url}`
215
216   > Yikes. I see why you wanted to keep it to 3 parameters (4 is too many,
217   > and po overrides it), but I dislike overloading the third parameter
218   > like that.
219   > 
220   > There are fairly few calls to `urlto($foo, $bar)`, so why not
221   > make that always return the semi-local url form, and leave the third
222   > parameter for the cases that need a true fully-qualified url.
223   > The new form for local urls will typically be only a little bit longer,
224   > except in the unusual case where the cgiurl is elsewhere. --[[Joey]]
225
226   >> So, have urlto(x, y) use `$local_url`? There are few calls, but IMO
227   >> they're for the most important things - wikilinks, img, map and
228   >> other ordinary hyperlinks. Using `$local_url` would be fine for
229   >> webserver-based use, but it does stop you browsing your wiki's
230   >> HTML over `file:///` (unless you set that as the base URL, but
231   >> then you can't move it around), and stops you moving simple
232   >> outputs (like the docwiki!) around.
233   >>
234   >> I personally think breaking the docwiki is enough to block that.
235   >>
236   >>> Well, the docwiki doesn't have an url configured at all, so I assumed
237   >>> it would need to fall back to current behavior in that case. I had
238   >>> not thought about browsing wiki's html files though, good point.
239   >>
240   >> How about this?
241   >>
242   >> * `urlto($link, $page)` with `$page` defined: relative
243   >> * `urlto($link, undef)`: local, starts with `/`
244   >> * `urlto($link)`: also local, as a side-effect
245   >> * `urlto($link, $anything, 1)` (but idiomatically, `$anything` is
246   >>   normally undef): absolute, starts with `http[s]://`
247   >>
248   >> --[[smcv]]
249   >> 
250   >>> That makes a great deal of sense, bravo for actually removing
251   >>> parameters in the common case while maintaining backwards
252   >>> compatability! --[[Joey]]
253   >>>
254   >>>> Done in my `localurl` branch; not tested in a whole-wiki way
255   >>>> yet, but I did add a regression test. I've used
256   >>>> `urlto(x, undef)` rather than `urlto(x)` so far, but I could
257   >>>> go back through the codebase using the short form if you'd
258   >>>> prefer. --[[smcv]]
259   >>> 
260   >>> It does highlight that it would be better to have a
261   >>> `absolute_urlto($link)` (or maybe `absolute(urlto($link))` )
262   >>> rather than the 3 parameter form. --[[Joey]]
263   >>>
264   >>> Possibly. I haven't added this.
265
266 * `IkiWiki::baseurl` has a new second argument which works like the
267   third argument of `urlto`
268
269   > I assume you have no objection to this --[[smcv]]
270
271   >> It's so little used that I don't really care if it's a bit ugly.
272   >> (But I assume changes to `urlto` will follow through here anyway.)
273   >> --[[Joey]] 
274
275   >>> I had to use it a bit more, as a replacement for `$config{url}`
276   >>> when doing things like referencing stylesheets or redirecting to
277   >>> the top of the wiki.
278   >>>
279   >>> I ended up redoing this without the extra parameter. Previously,
280   >>> `baseurl(undef)` was the absolute URL; now, `baseurl(undef)` is
281   >>> the local path. I know you objected to me using `baseurl()` in
282   >>> an earlier branch, because `baseurl().$x` looks confusingly
283   >>> similar to `baseurl($x)` but has totally different semantics;
284   >>> I've generally written it `baseurl(undef)` now, to be more
285   >>> explicit. --[[smcv]]
286
287 * `IkiWiki::cgiurl` uses `$local_cgiurl` if passed `local_cgiurl => 1`
288
289   > Now changed to always use the `$local_cgiurl`. --[[smcv]]
290
291 * `IkiWiki::cgiurl` omits the trailing `?` if given no named parameters
292   except `cgiurl` and/or `local_cgiurl`
293
294   > I assume you have no objection to this --[[smcv]]
295   > 
296   >> Nod, although I don't know of a use case. --[[Joey]]
297
298   >>> The use-case is that I can replace `$config{cgiurl}` with
299   >>> `IkiWiki::cgiurl()` for things like the action attribute of
300   >>> forms. --[[smcv]]
301
302 Fixed bugs:
303
304 * I don't think anything except `openid` calls `cgiurl` without also
305   passing in `local_cgiurl => 1`, so perhaps that should be the default;
306   `openid` uses the `cgiurl` named parameter anyway, so there doesn't even
307   necessarily need to be a way to force absolute URLs? Any other module
308   that really needs an absolute URL could use
309   `cgiurl(cgiurl => $config{cgiurl}, ...)`,
310   although that does look a bit strange
311
312   > I agree that makes sense. --[[Joey]]
313
314   >> I'm not completely sure whether you're agreeing with "perhaps do this"
315   >> or "that looks too strange", so please disambiguate:
316   >> would you accept a patch that makes `cgiurl` default to a local
317   >> (starts-with-`/`) result? If you would, that'd reduce the diff. --[[smcv]]
318
319   >>> Yes, I absolutely think it should default to local. (Note that
320   >>> if `absolute()` were implemented as suggested above, it could also
321   >>> be used with cgiurl if necessary.) --[[Joey]]
322
323   >>>> Done (minus `absolute()`). --[[smcv]]
324
325 Potential future things:
326
327 * It occurs to me that `IkiWiki::cgiurl` could probably benefit from being
328   exported? Perhaps also `IkiWiki::baseurl`?
329
330   > Possibly, see [[firm_up_plugin_interface]]. --[[Joey]]
331
332   >> Not really part of this branch, though, so wontfix (unless you ask me
333   >> to do so). --[[smcv]]
334
335 * Or, to reduce use of the unexported `baseurl` function, it might make
336   sense to give `urlto` a special case that references the root of the wiki,
337   with a trailing slash ready to append stuff: perhaps `urlto('/')`,
338   with usage like this?
339
340         do_something(baseurl => urlto('/', undef, local)`);
341         do_something_else(urlto('/').'style.css');
342         IkiWiki::redirect(urlto('/', undef, 1));
343
344   > AFACIS, `baseurl` is only called in 3 places so I don't think that's
345   > needed. --[[Joey]] 
346
347   >> OK, wontfix. For what it's worth, my branch has 6 uses in IkiWiki
348   >> core code (IkiWiki, CGI, Render and the pseudo-core part of editpage)
349   >> and 5 in plugins, since I used it for things like redirection back
350   >> to the top of the wiki --[[smcv]]
351
352 merged|done --[[Joey]] (But reopened, see above.)
353
354 ----
355
356 Update: I had to revert part of 296e5cb2fd3690e998b3824d54d317933c595873,
357 since it broke openid logins. The openid object requires a complete,
358 not a relative cgiurl. I'm not sure if my changing that back to using
359 `$config{cgiurl}` will force users back to eg, the non-https version of a
360 site when logging in via openid.
361
362 > Ok, changed it to use `CGI->url` to get the current absolute cgi url. --[[Joey]]