From a166efc133029d2d7dbf7b5fd3b99c3b9e6c5cb0 Mon Sep 17 00:00:00 2001 From: David Cook Date: Thu, 21 Jan 2021 01:02:49 +0000 Subject: [PATCH] Bug 26048: Use ErrorDocument middleware for Plack HTTP errors This patch uses the ErrorDocument middleware to use Koha's custom error pages instead of generic Plack error responses Test plan: 0. Apply patch 1. vi /usr/sbin/koha-plack (and change "development" to "deployment") 2. vi ./opac/opac-main.pl 3. Add "die" to line 2 4. vi ./mainpage.pl 5. Add "die" to line 2 6. cp ./debian/templates/plack.psgi /etc/koha/sites/kohadev/plack.psgi 7. koha-plack --restart kohadev 8. Go to http://localhost:8080/cgi-bin/koha/opac-main.pl 9. See a beautiful OPAC 500 error instead of "Internal Server Error" 10. Go to http://localhost:8080/cgi-bin/koha/blah.pl 11. See a beautiful OPAC 404 error instead of "not found" 12. Go to http://localhost:8081/cgi-bin/koha/mainpage.pl 13. See a beautiful Staff interface 500 error instead of "Internal Server Error" 14. Go to http://localhost:8081/cgi-bin/koha/blah.pl 15. See a beautiful Staff interface 404 error instead of "not found" For bonus points: 16. koha-plack --disable kohadev 17. koha-plack --stop kohadev 18. service apache restart 19. Repeat the above test plan to show CGI still works for 404 (although 500 will show "Software Error" due to C4::Context needing some improvements) 20. Using the "Network" tab on your developer tools, make sure 404 and 500 are returned by the appropriate error pages Signed-off-by: Eden Bacani Signed-off-by: Nick Clemens --- debian/templates/plack.psgi | 24 ++++++++++++++++++++++++ errors/400.pl | 7 ++++++- errors/401.pl | 7 ++++++- errors/402.pl | 7 ++++++- errors/403.pl | 7 ++++++- errors/404.pl | 23 ++++++++++++++++++++++- errors/500.pl | 7 ++++++- opac/errors/400.pl | 7 ++++++- opac/errors/401.pl | 7 ++++++- opac/errors/402.pl | 7 ++++++- opac/errors/403.pl | 7 ++++++- opac/errors/404.pl | 7 ++++++- opac/errors/500.pl | 7 ++++++- 13 files changed, 112 insertions(+), 12 deletions(-) diff --git a/debian/templates/plack.psgi b/debian/templates/plack.psgi index 99438c595a..a322114192 100644 --- a/debian/templates/plack.psgi +++ b/debian/templates/plack.psgi @@ -78,6 +78,18 @@ builder { enable "+Koha::Middleware::RealIP"; mount '/opac' => builder { + #NOTE: it is important that these are relative links + enable 'ErrorDocument', + 400 => 'errors/400.pl', + 401 => 'errors/401.pl', + 402 => 'errors/402.pl', + 403 => 'errors/403.pl', + 404 => 'errors/404.pl', + 500 => 'errors/500.pl', + subrequest => 1; + #NOTE: Without this middleware to catch fatal errors, ErrorDocument won't be able to render a 500 document + #NOTE: This middleware must be closer to the PSGI app than ErrorDocument + enable "HTTPExceptions"; if ( Log::Log4perl->get_logger('plack-opac')->has_appenders ){ enable 'Log4perl', category => 'plack-opac'; enable 'LogWarn'; @@ -85,6 +97,18 @@ builder { $opac; }; mount '/intranet' => builder { + #NOTE: it is important that these are relative links + enable 'ErrorDocument', + 400 => 'errors/400.pl', + 401 => 'errors/401.pl', + 402 => 'errors/402.pl', + 403 => 'errors/403.pl', + 404 => 'errors/404.pl', + 500 => 'errors/500.pl', + subrequest => 1; + #NOTE: Without this middleware to catch fatal errors, ErrorDocument won't be able to render a 500 document + #NOTE: This middleware must be closer to the PSGI app than ErrorDocument + enable "HTTPExceptions"; if ( Log::Log4perl->get_logger('plack-intranet')->has_appenders ){ enable 'Log4perl', category => 'plack-intranet'; enable 'LogWarn'; diff --git a/errors/400.pl b/errors/400.pl index d16f22bd5c..2e9324d6ea 100755 --- a/errors/400.pl +++ b/errors/400.pl @@ -21,6 +21,7 @@ use CGI qw ( -utf8 ); use C4::Auth; use C4::Output; use C4::Context; +use List::MoreUtils qw(any); my $query = CGI->new; my $admin = C4::Context->preference('KohaAdminEmailAddress'); @@ -37,4 +38,8 @@ $template->param ( admin => $admin, errno => 400, ); -output_with_http_headers $query, $cookie, $template->output, 'html', '400 Bad Request'; +my $status = '400 Bad Request'; +if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) { + $status = '200 OK'; +} +output_with_http_headers $query, $cookie, $template->output, 'html', $status; diff --git a/errors/401.pl b/errors/401.pl index b271b60dcd..8b67c98174 100755 --- a/errors/401.pl +++ b/errors/401.pl @@ -20,6 +20,7 @@ use CGI qw ( -utf8 ); use C4::Auth; use C4::Output; use C4::Context; +use List::MoreUtils qw(any); my $query = CGI->new; my $admin = C4::Context->preference('KohaAdminEmailAddress'); @@ -36,4 +37,8 @@ $template->param ( admin => $admin, errno => 401, ); -output_with_http_headers $query, $cookie, $template->output, 'html', '401 Unauthorized'; +my $status = '401 Unauthorized'; +if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) { + $status = '200 OK'; +} +output_with_http_headers $query, $cookie, $template->output, 'html', $status; diff --git a/errors/402.pl b/errors/402.pl index 386bf6b4df..0e5719d677 100755 --- a/errors/402.pl +++ b/errors/402.pl @@ -21,6 +21,7 @@ use CGI qw ( -utf8 ); use C4::Auth; use C4::Output; use C4::Context; +use List::MoreUtils qw(any); my $query = CGI->new; my $admin = C4::Context->preference('KohaAdminEmailAddress'); @@ -37,4 +38,8 @@ $template->param ( admin => $admin, errno => 402, ); -output_with_http_headers $query, $cookie, $template->output, 'html', '402 Payment Required'; +my $status = '402 Payment Required'; +if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) { + $status = '200 OK'; +} +output_with_http_headers $query, $cookie, $template->output, 'html', $status; diff --git a/errors/403.pl b/errors/403.pl index 066b597817..dbb6ee6722 100755 --- a/errors/403.pl +++ b/errors/403.pl @@ -21,6 +21,7 @@ use CGI qw ( -utf8 ); use C4::Auth; use C4::Output; use C4::Context; +use List::MoreUtils qw(any); my $query = CGI->new; my $admin = C4::Context->preference('KohaAdminEmailAddress'); @@ -37,4 +38,8 @@ $template->param ( admin => $admin, errno => 403, ); -output_with_http_headers $query, $cookie, $template->output, 'html', '403 Forbidden'; +my $status = '403 Forbidden'; +if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) { + $status = '200 OK'; +} +output_with_http_headers $query, $cookie, $template->output, 'html', $status; diff --git a/errors/404.pl b/errors/404.pl index 1c43ee6408..95215a7a8d 100755 --- a/errors/404.pl +++ b/errors/404.pl @@ -18,7 +18,28 @@ use Modern::Perl; use CGI qw ( -utf8 ); +use C4::Auth; use C4::Output; +use C4::Context; +use List::MoreUtils qw(any); my $query = CGI->new; -output_error( $query, '404' ); +my $admin = C4::Context->preference('KohaAdminEmailAddress'); +my ( $template, $loggedinuser, $cookie ) = get_template_and_user( + { + template_name => 'errors/errorpage.tt', + query => $query, + type => 'intranet', + authnotrequired => 1, + debug => 1, + } +); +$template->param ( + admin => $admin, + errno => 404, +); +my $status = '404 Not Found'; +if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) { + $status = '200 OK'; +} +output_with_http_headers $query, $cookie, $template->output, 'html', $status; diff --git a/errors/500.pl b/errors/500.pl index 4140b75d34..7f92673ce1 100755 --- a/errors/500.pl +++ b/errors/500.pl @@ -21,6 +21,7 @@ use CGI qw ( -utf8 ); use C4::Auth; use C4::Output; use C4::Context; +use List::MoreUtils qw(any); my $query = CGI->new; my $admin = C4::Context->preference('KohaAdminEmailAddress'); @@ -37,4 +38,8 @@ $template->param ( admin => $admin, errno => 500, ); -output_with_http_headers $query, $cookie, $template->output, 'html', '500 Internal Server Error'; +my $status = '500 Internal Server Error'; +if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) { + $status = '200 OK'; +} +output_with_http_headers $query, $cookie, $template->output, 'html', $status; diff --git a/opac/errors/400.pl b/opac/errors/400.pl index f1dc8da77a..e295c0bf29 100755 --- a/opac/errors/400.pl +++ b/opac/errors/400.pl @@ -21,6 +21,7 @@ use CGI qw ( -utf8 ); use C4::Auth; use C4::Output; use C4::Context; +use List::MoreUtils qw(any); my $query = CGI->new; my $admin = C4::Context->preference('KohaAdminEmailAddress'); @@ -37,4 +38,8 @@ $template->param ( admin => $admin, errno => 400, ); -output_with_http_headers $query, $cookie, $template->output, 'html', '400 Bad Request'; +my $status = '400 Bad Request'; +if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) { + $status = '200 OK'; +} +output_with_http_headers $query, $cookie, $template->output, 'html', $status; diff --git a/opac/errors/401.pl b/opac/errors/401.pl index a3358a7ea2..011698d5a6 100755 --- a/opac/errors/401.pl +++ b/opac/errors/401.pl @@ -21,6 +21,7 @@ use CGI qw ( -utf8 ); use C4::Auth; use C4::Output; use C4::Context; +use List::MoreUtils qw(any); my $query = CGI->new; my $admin = C4::Context->preference('KohaAdminEmailAddress'); @@ -37,4 +38,8 @@ $template->param ( admin => $admin, errno => 401, ); -output_with_http_headers $query, $cookie, $template->output, 'html', '401 Unauthorized'; +my $status = '401 Unauthorized'; +if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) { + $status = '200 OK'; +} +output_with_http_headers $query, $cookie, $template->output, 'html', $status; diff --git a/opac/errors/402.pl b/opac/errors/402.pl index 7dc8c9b99e..b3f94e6992 100755 --- a/opac/errors/402.pl +++ b/opac/errors/402.pl @@ -21,6 +21,7 @@ use CGI qw ( -utf8 ); use C4::Auth; use C4::Output; use C4::Context; +use List::MoreUtils qw(any); my $query = CGI->new; my $admin = C4::Context->preference('KohaAdminEmailAddress'); @@ -37,4 +38,8 @@ $template->param ( admin => $admin, errno => 402, ); -output_with_http_headers $query, $cookie, $template->output, 'html', '402 Payment Required'; +my $status = '402 Payment Required'; +if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) { + $status = '200 OK'; +} +output_with_http_headers $query, $cookie, $template->output, 'html', $status; diff --git a/opac/errors/403.pl b/opac/errors/403.pl index ced08dd8ba..2768a14945 100755 --- a/opac/errors/403.pl +++ b/opac/errors/403.pl @@ -21,6 +21,7 @@ use CGI qw ( -utf8 ); use C4::Auth; use C4::Output; use C4::Context; +use List::MoreUtils qw(any); my $query = CGI->new; my $admin = C4::Context->preference('KohaAdminEmailAddress'); @@ -37,4 +38,8 @@ $template->param ( admin => $admin, errno => 403, ); -output_with_http_headers $query, $cookie, $template->output, 'html', '403 Forbidden'; +my $status = '403 Forbidden'; +if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) { + $status = '200 OK'; +} +output_with_http_headers $query, $cookie, $template->output, 'html', $status; diff --git a/opac/errors/404.pl b/opac/errors/404.pl index 0ac32ca96c..6fe04c218b 100755 --- a/opac/errors/404.pl +++ b/opac/errors/404.pl @@ -21,6 +21,7 @@ use CGI qw ( -utf8 ); use C4::Auth; use C4::Output; use C4::Context; +use List::MoreUtils qw(any); my $query = CGI->new; my $admin = C4::Context->preference('KohaAdminEmailAddress'); @@ -37,4 +38,8 @@ $template->param ( admin => $admin, errno => 404, ); -output_html_with_http_headers $query, $cookie, $template->output, '404 Not Found'; +my $status = '404 Not Found'; +if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) { + $status = '200 OK'; +} +output_with_http_headers $query, $cookie, $template->output, 'html', $status; diff --git a/opac/errors/500.pl b/opac/errors/500.pl index 22d86647d6..be1e374fbe 100755 --- a/opac/errors/500.pl +++ b/opac/errors/500.pl @@ -21,6 +21,7 @@ use CGI qw ( -utf8 ); use C4::Auth; use C4::Output; use C4::Context; +use List::MoreUtils qw(any); my $query = CGI->new; my $admin = C4::Context->preference('KohaAdminEmailAddress'); @@ -37,4 +38,8 @@ $template->param ( admin => $admin, errno => 500, ); -output_with_http_headers $query, $cookie, $template->output, 'html', '500 Internal Server Error'; +my $status = '500 Internal Server Error'; +if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) { + $status = '200 OK'; +} +output_with_http_headers $query, $cookie, $template->output, 'html', $status; -- 2.11.0