From 7ef6c5a37a2a38161f68174bddb568d58679c322 Mon Sep 17 00:00:00 2001 From: bbrtj Date: Thu, 10 Oct 2024 17:59:16 +0200 Subject: [PATCH] Use better method for localizing env in adapt_psgi --- lib/Kelp/Util.pm | 21 +++++++------- t/psgi.t | 72 ++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 68 insertions(+), 25 deletions(-) diff --git a/lib/Kelp/Util.pm b/lib/Kelp/Util.pm index d79ca28..db268e7 100644 --- a/lib/Kelp/Util.pm +++ b/lib/Kelp/Util.pm @@ -138,17 +138,16 @@ sub adapt_psgi $path =~ s{^/?}{/}; $path =~ s{/?$}{$trailing_slash}; - # adjust script and path - $env->{SCRIPT_NAME} = $orig_path; - $env->{SCRIPT_NAME} =~ s{\Q$path\E$}{}; - $env->{PATH_INFO} = $path; - - # run the callback - my $result = $app->($env); - - # restore old script and path - $env->{SCRIPT_NAME} = $orig_script; - $env->{PATH_INFO} = $orig_path; + my $result; + { + # adjust script and path + local $env->{SCRIPT_NAME} = $orig_path; + $env->{SCRIPT_NAME} =~ s{\Q$path\E$}{}; + local $env->{PATH_INFO} = $path; + + # run the callback + $result = $app->($env); + } # produce a response if (ref $result eq 'ARRAY') { diff --git a/t/psgi.t b/t/psgi.t index b852f20..a63ee51 100644 --- a/t/psgi.t +++ b/t/psgi.t @@ -25,9 +25,39 @@ my $psgi_dumper = sub { ]; }; +# this is a PSGI app which compares env keys +my $psgi_comparer = sub { + my $env = shift; + + my %env_before = %$env; + my $res = Kelp->NEXT_APP->($env); + + my $all_valid = 1; + foreach my $key (keys %env_before) { + my $value = $env_before{$key}; + next if ref $value; + + $all_valid &&= $value eq $env->{$key}; + } + + if (!$all_valid) { + push @{$res->[2]}, "BADENV\n"; + } + + return $res; +}; + my $app = Kelp->new(mode => 'test'); $app->routes->fatal(1); +$app->add_route( + '/' => { + to => sub { 1 }, + bridge => 1, + psgi_middleware => $psgi_comparer, + } +); + $app->add_route( '/app1' => { to => $psgi_dumper, @@ -64,59 +94,72 @@ my $t = Kelp::Test->new(app => $app); $t->request(GET "/app1") ->code_is(200) ->content_like(qr{^script: /app1$}m) - ->content_like(qr{^path: $}m); + ->content_like(qr{^path: $}m) + ->content_unlike(qr{^BADENV$}m); $t->request(GET "/app1/") ->code_is(200) ->content_like(qr{^script: /app1$}m) - ->content_like(qr{^path: /$}m); + ->content_like(qr{^path: /$}m) + ->content_unlike(qr{^BADENV$}m); $t->request(GET "/app1/x") - ->code_is(404); + ->code_is(404) + ->content_unlike(qr{^BADENV$}m); $t->request(GET "/app2") ->code_is(200) ->content_like(qr{^script: /app2$}m) - ->content_like(qr{^path: $}m); + ->content_like(qr{^path: $}m) + ->content_unlike(qr{^BADENV$}m); $t->request(GET "/app2/") ->code_is(200) ->content_like(qr{^script: /app2$}m) - ->content_like(qr{^path: /$}m); + ->content_like(qr{^path: /$}m) + ->content_unlike(qr{^BADENV$}m); $t->request(GET "/app2/x") ->code_is(200) ->content_like(qr{^script: /app2$}m) - ->content_like(qr{^path: /x$}m); + ->content_like(qr{^path: /x$}m) + ->content_unlike(qr{^BADENV$}m); $t->request(GET "/app2/x/") ->code_is(200) ->content_like(qr{^script: /app2$}m) - ->content_like(qr{^path: /x/$}m); + ->content_like(qr{^path: /x/$}m) + ->content_unlike(qr{^BADENV$}m); $t->request(GET "/app2/x/y") ->code_is(200) ->content_like(qr{^script: /app2$}m) - ->content_like(qr{^path: /x/y$}m); + ->content_like(qr{^path: /x/y$}m) + ->content_unlike(qr{^BADENV$}m); $t->request(GET "/app3") - ->code_is(404); + ->code_is(404) + ->content_unlike(qr{^BADENV$}m); $t->request(GET "/app3/") - ->code_is(404); + ->code_is(404) + ->content_unlike(qr{^BADENV$}m); $t->request(GET "/app3/x") ->code_is(200) ->content_like(qr{^script: /app3$}m) - ->content_like(qr{^path: /x$}m); + ->content_like(qr{^path: /x$}m) + ->content_unlike(qr{^BADENV$}m); $t->request(GET "/app3/x/") ->code_is(200) ->content_like(qr{^script: /app3$}m) - ->content_like(qr{^path: /x/$}m); + ->content_like(qr{^path: /x/$}m) + ->content_unlike(qr{^BADENV$}m); $t->request(GET "/app3/x/y") - ->code_is(404); + ->code_is(404) + ->content_unlike(qr{^BADENV$}m); # application unicode support should be distinct from Kelp. Kelp will just have # to pass everything to the app through psgi env undecoded. App result should @@ -139,7 +182,8 @@ subtest 'testing unicode' => sub { ->code_is(200) ->full_content_type_is('text/plain') ->content_like(qr{^script: /zażółć$}m) - ->content_like(qr{^path: /gęślą/jaźń$}m); + ->content_like(qr{^path: /gęślą/jaźń$}m) + ->content_unlike(qr{^BADENV$}m); }; done_testing;