Bug 29420: HTTP status code incorrect when calling error pages directly under Plack/PSGI

The error pages wrote a HTTP status code of 200 for all PSGI requests, even
though it should have only done it for PSGI requests from the ErrorDocument
middleware. This patch fixes that.

0) Do not apply patch
1) Open F12 dev tools and go to Network tab
2) Go to http://localhost:8081/files/blah
3) Note that the webpage is a 404 error but HTTP status code is 200
4) Go to http://localhost:8081/cgi-bin/koha/circ/blah
5) Note that the webpage is a 404 error and HTTP status code is 404

6) Apply patch
7) Go to http://localhost:8081/files/blah
8) Note that the webpage is a 404 error and HTTP status code is 404
9) Go to http://localhost:8081/cgi-bin/koha/circ/blah
10) Note that the webpage is a 404 error and HTTP status code is 404

Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Fridolin Somers <fridolin.somers@biblibre.com>
This commit is contained in:
David Cook 2021-12-01 01:31:27 +00:00 committed by Fridolin Somers
parent 05ba079814
commit 437e584407
13 changed files with 46 additions and 12 deletions

View file

@ -42,6 +42,7 @@ use File::Spec;
use POSIX;
use YAML::XS;
use ZOOM;
use List::MoreUtils qw(any);
use Koha::Caches;
use Koha::Config::SysPref;
@ -978,6 +979,39 @@ sub needs_install {
return ($self->preference('Version')) ? 0 : 1;
}
=head3 is_psgi_or_plack
is_psgi_or_plack returns true if there is an environmental variable
prefixed with "psgi" or "plack". This is useful for detecting whether
this is a PSGI app or a CGI app, and implementing code as appropriate.
=cut
sub is_psgi_or_plack {
my $is_psgi_or_plack = 0;
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
$is_psgi_or_plack = 1;
}
return $is_psgi_or_plack;
}
=head3 is_internal_PSGI_request
is_internal_PSGI_request is used to detect if this request was made
from within the individual PSGI app or externally from the mounted PSGI
app
=cut
#NOTE: This is not a very robust method but it's the best we have so far
sub is_internal_PSGI_request {
my $is_internal = 0;
if ( (__PACKAGE__->is_psgi_or_plack) && ( $ENV{REQUEST_URI} !~ /^(\/intranet|\/opac)/ ) ){
$is_internal = 1;
}
return $is_internal;
}
__END__
=head1 ENVIRONMENT

View file

@ -38,7 +38,7 @@ $template->param (
errno => 400,
);
my $status = '400 Bad Request';
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
if ( C4::Context->is_internal_PSGI_request() ) {
$status = '200 OK';
}
output_with_http_headers $query, $cookie, $template->output, 'html', $status;

View file

@ -37,7 +37,7 @@ $template->param (
errno => 401,
);
my $status = '401 Unauthorized';
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
if ( C4::Context->is_internal_PSGI_request() ) {
$status = '200 OK';
}
output_with_http_headers $query, $cookie, $template->output, 'html', $status;

View file

@ -38,7 +38,7 @@ $template->param (
errno => 402,
);
my $status = '402 Payment Required';
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
if ( C4::Context->is_internal_PSGI_request() ) {
$status = '200 OK';
}
output_with_http_headers $query, $cookie, $template->output, 'html', $status;

View file

@ -38,7 +38,7 @@ $template->param (
errno => 403,
);
my $status = '403 Forbidden';
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
if ( C4::Context->is_internal_PSGI_request() ) {
$status = '200 OK';
}
output_with_http_headers $query, $cookie, $template->output, 'html', $status;

View file

@ -38,7 +38,7 @@ $template->param (
errno => 404,
);
my $status = '404 Not Found';
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
if ( C4::Context->is_internal_PSGI_request() ) {
$status = '200 OK';
}
output_with_http_headers $query, $cookie, $template->output, 'html', $status;

View file

@ -38,7 +38,7 @@ $template->param (
errno => 500,
);
my $status = '500 Internal Server Error';
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
if ( C4::Context->is_internal_PSGI_request() ) {
$status = '200 OK';
}
output_with_http_headers $query, $cookie, $template->output, 'html', $status;

View file

@ -38,7 +38,7 @@ $template->param (
errno => 400,
);
my $status = '400 Bad Request';
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
if ( C4::Context->is_internal_PSGI_request() ) {
$status = '200 OK';
}
output_with_http_headers $query, $cookie, $template->output, 'html', $status;

View file

@ -38,7 +38,7 @@ $template->param (
errno => 401,
);
my $status = '401 Unauthorized';
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
if ( C4::Context->is_internal_PSGI_request() ) {
$status = '200 OK';
}
output_with_http_headers $query, $cookie, $template->output, 'html', $status;

View file

@ -38,7 +38,7 @@ $template->param (
errno => 402,
);
my $status = '402 Payment Required';
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
if ( C4::Context->is_internal_PSGI_request() ) {
$status = '200 OK';
}
output_with_http_headers $query, $cookie, $template->output, 'html', $status;

View file

@ -38,7 +38,7 @@ $template->param (
errno => 403,
);
my $status = '403 Forbidden';
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
if ( C4::Context->is_internal_PSGI_request() ) {
$status = '200 OK';
}
output_with_http_headers $query, $cookie, $template->output, 'html', $status;

View file

@ -38,7 +38,7 @@ $template->param (
errno => 404,
);
my $status = '404 Not Found';
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
if ( C4::Context->is_internal_PSGI_request() ) {
$status = '200 OK';
}
output_with_http_headers $query, $cookie, $template->output, 'html', $status;

View file

@ -38,7 +38,7 @@ $template->param (
errno => 500,
);
my $status = '500 Internal Server Error';
if ( any { /(^psgi\.|^plack\.)/i } keys %ENV ) {
if ( C4::Context->is_internal_PSGI_request() ) {
$status = '200 OK';
}
output_with_http_headers $query, $cookie, $template->output, 'html', $status;