summaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin/404.pm
blob: 42cfa9e8aad04fc69b050df92b38a18905a33495 (plain)
  1. #!/usr/bin/perl
  2. # Copyright © 2009 Simon McVittie <http://smcv.pseudorandom.co.uk/>
  3. # Licensed under the GNU GPL, version 2, or any later version published by the
  4. # Free Software Foundation
  5. package IkiWiki::Plugin::404;
  6. use warnings;
  7. use strict;
  8. use IkiWiki 3.00;
  9. sub import {
  10. hook(type => "cgi", id => '404', call => \&cgi);
  11. hook(type => "getsetup", id => '404', call => \&getsetup);
  12. IkiWiki::loadplugin("goto");
  13. }
  14. sub getsetup () {
  15. return
  16. plugin => {
  17. # not really a matter of safety, but enabling/disabling
  18. # through a web interface is useless - it needs web
  19. # server admin action too
  20. safe => 0,
  21. rebuild => 0,
  22. section => "web",
  23. }
  24. }
  25. sub cgi_page_from_404 ($$$) {
  26. my $path = shift;
  27. my $baseurl = shift;
  28. my $usedirs = shift;
  29. # fail if missing from environment or whatever
  30. return undef unless defined $path;
  31. return undef unless defined $baseurl;
  32. # with usedirs on, path is like /~fred/foo/bar/ or /~fred/foo/bar or
  33. # /~fred/foo/bar/index.html
  34. # with usedirs off, path is like /~fred/foo/bar.html
  35. # baseurl is like 'http://people.example.com/~fred'
  36. # convert baseurl to ~fred
  37. unless ($baseurl =~ s{^https?://[^/]+/?}{}) {
  38. return undef;
  39. }
  40. # convert path to /~fred/foo/bar
  41. if ($usedirs) {
  42. $path =~ s/\/*(?:index\.$config{htmlext})?$//;
  43. }
  44. else {
  45. $path =~ s/\.$config{htmlext}$//;
  46. }
  47. # remove /~fred/
  48. unless ($path =~ s{^/*\Q$baseurl\E/*}{}) {
  49. return undef;
  50. }
  51. # special case for the index
  52. unless ($path) {
  53. return 'index';
  54. }
  55. return $path;
  56. }
  57. sub cgi ($) {
  58. my $cgi=shift;
  59. if (exists $ENV{REDIRECT_STATUS} &&
  60. $ENV{REDIRECT_STATUS} eq '404') {
  61. my $page = cgi_page_from_404(
  62. Encode::decode_utf8($ENV{REDIRECT_URL}),
  63. $config{url}, $config{usedirs});
  64. IkiWiki::Plugin::goto::cgi_goto($cgi, $page);
  65. }
  66. }
  67. 1;