summaryrefslogtreecommitdiff
path: root/IkiWiki/Plugin/404.pm
blob: 85486e559b0cdfa907d3000ed8f64a3a281d2d69 (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. IkiWiki::loadplugin("goto");
  12. }
  13. sub getsetup () {
  14. return
  15. plugin => {
  16. # not really a matter of safety, but enabling/disabling
  17. # through a web interface is useless - it needs web
  18. # server admin action too
  19. safe => 0,
  20. rebuild => 0,
  21. }
  22. }
  23. sub cgi_page_from_404 ($$$) {
  24. my $path = shift;
  25. my $baseurl = shift;
  26. my $usedirs = shift;
  27. # fail if missing from environment or whatever
  28. return undef unless defined $path;
  29. return undef unless defined $baseurl;
  30. # with usedirs on, path is like /~fred/foo/bar/ or /~fred/foo/bar or
  31. # /~fred/foo/bar/index.html
  32. # with usedirs off, path is like /~fred/foo/bar.html
  33. # baseurl is like 'http://people.example.com/~fred'
  34. # convert baseurl to ~fred
  35. unless ($baseurl =~ s{^https?://[^/]+/?}{}) {
  36. return undef;
  37. }
  38. # convert path to /~fred/foo/bar
  39. if ($usedirs) {
  40. $path =~ s/\/*(?:index\.$config{htmlext})?$//;
  41. }
  42. else {
  43. $path =~ s/\.$config{htmlext}$//;
  44. }
  45. # remove /~fred/
  46. unless ($path =~ s{^/*\Q$baseurl\E/*}{}) {
  47. return undef;
  48. }
  49. # special case for the index
  50. unless ($path) {
  51. return 'index';
  52. }
  53. return $path;
  54. }
  55. sub cgi ($) {
  56. my $cgi=shift;
  57. if (exists $ENV{REDIRECT_STATUS} &&
  58. $ENV{REDIRECT_STATUS} eq '404') {
  59. my $page = cgi_page_from_404(
  60. Encode::decode_utf8($ENV{REDIRECT_URL}),
  61. $config{url}, $config{usedirs});
  62. IkiWiki::Plugin::goto::cgi_goto($cgi, $page);
  63. }
  64. }
  65. 1;