diff --git a/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI.pm b/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI.pm index 65d003015..c5bb78afd 100644 --- a/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI.pm +++ b/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI.pm @@ -121,7 +121,7 @@ sub userError { sub sendJSONresponse { my ( $self, $req, $j, %args ) = @_; $args{code} ||= 200; - $args{headers} ||= $req->respHeaders || []; + $args{headers} ||= [ $req->spliceHdrs ]; my $type = 'application/json; charset=utf-8'; if ( ref $j ) { eval { $j = $_json->encode($j); }; @@ -151,9 +151,9 @@ sub sendError { return [ $code, [ - 'Content-Type' => 'application/xml; charset=utf-8', - @{ $req->respHeaders || [] }, - 'Content-Length' => length($s) + 'Content-Type' => 'application/xml; charset=utf-8', + 'Content-Length' => length($s), + $req->spliceHdrs, ], [$s] ]; @@ -188,8 +188,9 @@ body{background:#000;color:#fff;padding:10px 50px;font-family:sans-serif;}a{text return [ $code, [ - 'Content-Type' => 'text/html; charset=utf-8', - @{ $req->respHeaders || [] }, 'Content-Length' => length($s) + 'Content-Type' => 'text/html; charset=utf-8', + 'Content-Length' => length($s), + $req->spliceHdrs, ], [$s] ]; @@ -247,7 +248,7 @@ sub sendHtml { $sc = '.' unless ($sc); $sc =~ s#/*$#/#; $args{code} ||= 200; - $args{headers} ||= $req->respHeaders || []; + $args{headers} ||= [ $req->spliceHdrs ]; my $htpl; $template = ( $args{templateDir} // $self->templateDir ) . "/$template.tpl"; return $self->sendError( $req, "Unable to read $template", 500 ) diff --git a/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm b/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm index 8e64e36fe..79f1c5a4a 100644 --- a/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm +++ b/lemonldap-ng-common/lib/Lemonldap/NG/Common/PSGI/Request.pm @@ -55,6 +55,11 @@ sub respHeaders { return $self->{respHeaders}; } +sub spliceHdrs { + my ($self) = @_; + return splice @{ $self->{respHeaders} }; +} + sub accept { $_[0]->env->{HTTP_ACCEPT} } sub encodings { $_[0]->env->{HTTP_ACCEPT_ENCODING} } sub languages { $_[0]->env->{HTTP_ACCEPT_LANGUAGE} } @@ -189,6 +194,10 @@ Example: # Add header $req->respHeaders->{"X-Key"} = "Value"; +=head2 spliceHdrs + +Returns headers array and flush it. + =head2 set_param( $key, $value ) L param() method is read-only. This method can be used to diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Lib/PSGI.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Lib/PSGI.pm index 010d49c14..0000b0246 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Lib/PSGI.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Lib/PSGI.pm @@ -69,7 +69,7 @@ sub _run { return sub { my $req = Lemonldap::NG::Common::PSGI::Request->new( $_[0] ); my $res = $self->handler($req); - push @{ $res->[1] }, @{ $req->{respHeaders} }; + push @{ $res->[1] }, $req->spliceHdrs; return $res; }; } @@ -89,7 +89,7 @@ sub status { return sub { my $req = Lemonldap::NG::Common::PSGI::Request->new( $_[0] ); $self->api->status($req); - return [ 200, [ @{ $req->{respHeaders} } ], [ $req->{respBody} ] ]; + return [ 200, [ $req->spliceHdrs ], [ $req->{respBody} ] ]; }; } @@ -107,7 +107,7 @@ sub reload { return sub { my $req = Lemonldap::NG::Common::PSGI::Request->new( $_[0] ); $self->api->reload($req); - return [ 200, [ @{ $req->{respHeaders} } ], [ $req->{respBody} ] ]; + return [ 200, [ $req->spliceHdrs ], [ $req->{respBody} ] ]; }; } @@ -133,31 +133,19 @@ sub _authAndTrace { if ( $res < 300 ) { if ($noCall) { - return [ $res, $req->{respHeaders}, [] ]; + return [ $res, [ $req->spliceHdrs ], [] ]; } else { $self->logger->debug('User authenticated, calling handler()'); $res = $self->handler($req); - - # Insert respHeaders in response only if not already set - my %hdr1 = @{ $res->[1] }; - my %hdr2 = @{ $req->{respHeaders} }; - foreach ( keys %hdr2 ) { - unless ( $hdr1{$_} and $hdr2{$_} eq $hdr1{$_} ) { - push @{ $res->[1] }, ( $_ => $hdr2{$_} ); - } - } - - # Headers have been consumed -> remove them (#1863) - $req->{respHeaders} = []; + push @{ $res->[1] }, $req->spliceHdrs; + return $res; } - return $res; } elsif ( $res < 400 ) { - return [ $res, $req->{respHeaders}, [] ]; + return [ $res, [ $req->spliceHdrs ], [] ]; } else { - my %h = $req->{respHeaders} ? @{ $req->{respHeaders} } : (); my $s = $type->tsv->{portal}->() . "/lmerror/$res"; $s = 'Redirection' @@ -165,9 +153,15 @@ sub _authAndTrace { . '

Please wait

' . qq{

An error occurs, you're going to be redirected to $s.

} . ''; - $h{'Content-Type'} = 'text/html'; - $h{'Content-Length'} = length $s; - return [ $res, [%h], [$s] ]; + return [ + $res, + [ + $req->spliceHdrs, + 'Content-Type' => 'text/html', + 'Content-Length' => length $s + ], + [$s] + ]; } } diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI/Try.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI/Try.pm index 183e28f93..1169ed110 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI/Try.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/PSGI/Try.pm @@ -47,7 +47,7 @@ sub addAuthRouteWithRedirect { sub _auth_and_redirect { my ( $self, $req ) = @_; $self->api->goToPortal( $req, $req->{env}->{REQUEST_URI} ); - return [ 302, $req->respHeaders, [] ]; + return [ 302, [$req->spliceHdrs], [] ]; } sub defaultAuthRoute { @@ -71,6 +71,7 @@ sub _run { if ( $res->[0] < 300 ) { $self->routes( $self->authRoutes ); $req->userData( $self->api->data ); + $req->respHeaders($res->[1]); } elsif ( $res->[0] != 403 and not $req->data->{noTry} ) { @@ -85,15 +86,7 @@ sub _run { return $res; } $res = $self->handler($req); - - # Insert respHeaders in response only if not already set - my %hdr1 = @{ $res->[1] }; - my %hdr2 = @{ $req->{respHeaders} }; - foreach ( keys %hdr2 ) { - unless ( $hdr1{$_} and $hdr2{$_} eq $hdr1{$_} ) { - push @{ $res->[1] }, ( $_ => $hdr2{$_} ); - } - } + push @{ $res->[1] }, $req->spliceHdrs; return $res; }; } diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Server.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Server.pm index 30123a690..1a4d03484 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Server.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Server.pm @@ -26,7 +26,7 @@ sub _run { return sub { my $req = Lemonldap::NG::Common::PSGI::Request->new( $_[0] ); my $res = $self->_authAndTrace($req); - push @{ $res->[1] }, @{ $req->respHeaders }, + push @{ $res->[1] }, $req->spliceHdrs, Cookie => ( $req->{Cookie} // '' ); return $res; }; diff --git a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Server/Nginx.pm b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Server/Nginx.pm index 57efb0d6e..df25c4f1f 100644 --- a/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Server/Nginx.pm +++ b/lemonldap-ng-handler/lib/Lemonldap/NG/Handler/Server/Nginx.pm @@ -65,13 +65,10 @@ sub _run { #@param $req Lemonldap::NG::Common::PSGI::Request sub handler { my ( $self, $req ) = @_; - my $hdrs = $req->{respHeaders}; - $req->{respHeaders} = []; my @convertedHdrs = ( 'Content-Length' => 0, Cookie => ( $req->env->{HTTP_COOKIE} // '' ) ); my $i = 0; - while ( my $k = shift @$hdrs ) { - my $v = shift @$hdrs; + while ( my ( $k, $v ) = splice( @{ $req->{respHeaders} }, 0, 2 ) ) { if ( $k =~ /^(?:Lm-Remote-(?:User|Custom)|Cookie)$/ ) { push @convertedHdrs, $k, $v; } diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/CDC.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/CDC.pm index 83d1a1440..2933eea95 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/CDC.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/CDC.pm @@ -163,7 +163,7 @@ sub handler { ); # Redirect - return [ 302, [ Location => $urldc, @{ $req->respHeaders } ], [] ]; + return [ 302, [ Location => $urldc, $req->spliceHdrs ], [] ]; } @@ -180,7 +180,7 @@ sub handler { [ 'Content-Type' => 'text/plain', 'Content-Length' => 2, - @{ $req->respHeaders } + $req->spliceHdrs, ], ['OK'] ]; diff --git a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm index c3378488e..bfada8def 100644 --- a/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm +++ b/lemonldap-ng-portal/lib/Lemonldap/NG/Portal/Main/Run.pm @@ -339,8 +339,7 @@ sub autoRedirect { $req->data->{redirectFormMethod} = "get"; } else { - return [ 302, - [ Location => $req->{urldc}, @{ $req->respHeaders } ], [] ]; + return [ 302, [ Location => $req->{urldc}, $req->spliceHdrs ], [] ]; } } my ( $tpl, $prms ) = $self->display($req);