Skip to content

Commit

Permalink
Merge branch 'master' from 'bbrtj/kelp' into dev
Browse files Browse the repository at this point in the history
  • Loading branch information
bbrtj committed Jun 18, 2024
2 parents f15d444 + 18b0ce4 commit 31e30c0
Show file tree
Hide file tree
Showing 14 changed files with 754 additions and 111 deletions.
36 changes: 33 additions & 3 deletions Changes
Original file line number Diff line number Diff line change
@@ -1,12 +1,42 @@
2024-06-15: Version 2.01
[New Features]
- PSGI-compatible applications can now be mounted directly by using 'psgi' route flag
- Added Kelp::Util::adapt_psgi (used by the new 'psgi' route flag)
- Added Kelp::Util::adapt_psgi function (used by the new 'psgi' route flag)
- Added a bunch of new methods with suffix '_param' to Kelp::Request, which work like 'param' but fetch from specific place
- Methods with prefix 'raw_' were added to Kelp::Request, returning encoded request data (see "Bug fixes" below)
- Added charset_encode, charset_decode methods to Kelp
- Added charset method to Kelp::Request
- Added charset_decode method to Kelp::Request, which decodes using either request or application charset

[Changes]
- 'kelp' template has been adjusted to match framework looks
- Scalar context behavior of the param method called without arguments on json request is now deprecated
* this is done in effort to make param method easier to use and harder to misuse
- Kelp::Test no longer uses HTTP::Cookies, implements a much slimmer cookie jar with the same interface
* The new cookie jar only stores key/value pairs without any special data for cookies like domains, paths or expiration dates
- Kelp::Test now has a new import flag: '-utf8'
* Importing with this flag will automatically set Test::More to encode wide characters on output
- Repeatedly fetching parameters from json request with the param method is now much faster
- Documentation improvements
- Added a homepage on github

[Bug fixes]
- Route destination will no longer be executed if a response was already rendered by a previous one
* Rendering a response in a bridge will work the same as if the bridge returned a false value
* If more than one normal routes were matched, they will be run until one of them renders or returns a defined value
* Delayed responses will no longer override a previously rendered normal response
* The destination will still be run if the render happened inside 'before_dispatch' hook

[Backward-Incompatible Changes]
- Request data will now be properly decoded using either charset from Content-Type or application charset
* Request paths, query parameters and body are automatically decoded
* Headers, cookies and sessions are unaffected (session encoding must be configured on the middleware level)
* Please use methods with prefix 'raw_' from Kelp::Request to access encoded request data if needed
* Not decoding input was a bug which needed to be fixed, but the application was already encoding the response correctly

[Tweaks]
- 'kelp' template has been adjusted to match framework looks
- Added a homepage on GitHub
- Kelp now has a logo and is developed by the Kelp-framework organization on GitHub


2024-06-10: Version 2.00
[New Features]
Expand Down
4 changes: 3 additions & 1 deletion cpanfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ requires 'Path::Tiny' => '0';
requires 'Template::Tiny' => 0;
requires 'Try::Tiny' => 0;
requires 'Class::Inspector' => '0';
requires 'HTTP::Cookies' => '0';
requires 'namespace::autoclean' => '0';
requires 'URI' => '0';
requires 'Hash::MultiValue' => '0';

on 'test' => sub {
requires 'Test::Deep' => '0';
Expand Down
58 changes: 39 additions & 19 deletions lib/Kelp.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@ use Kelp::Base;

use Carp qw/ longmess croak /;
use FindBin;
use Encode;
use Try::Tiny;
use Data::Dumper;
use Sys::Hostname;
use Plack::Util;
use Class::Inspector;
use Scalar::Util qw(blessed);
use Encode qw(encode decode);

our $VERSION = '2.01';

Expand All @@ -22,13 +21,12 @@ attr -name => sub { ( ref( $_[0] ) =~ /(\w+)$/ ) ? $1 : 'Noname' };
attr request_obj => 'Kelp::Request';
attr response_obj => 'Kelp::Response';


# Debug
attr long_error => $ENV{KELP_LONG_ERROR} // 0;

# The charset is UTF-8 unless otherwise instructed
attr -charset => sub {
$_[0]->config("charset") // 'UTF-8';
$_[0]->config('charset') // 'UTF-8';
};

# Name the config module
Expand Down Expand Up @@ -225,7 +223,7 @@ sub psgi {
return $self->finalize;
}

try {
return try {

# Go over the entire route chain
for my $route (@$match) {
Expand All @@ -235,23 +233,26 @@ sub psgi {
$req->route_name( $route->name );
my $data = $self->routes->dispatch( $self, $route );

# Is it a bridge? Bridges must return a true value
# to allow the rest of the routes to run.
if ( $route->bridge ) {
# Is it a bridge? Bridges must return a true value to allow the
# rest of the routes to run. They may also have rendered
# something, in which case trust that and don't render 403 (but
# still end the execution chain)

if ( !$data ) {
$res->render_403 unless $res->rendered;
last;
}
next;
}

# If the route returned something, then analyze it and render it
if ( defined $data ) {
elsif ( defined $data ) {
# If the non-bridge route returned something, then analyze it and render it

# Handle delayed response if CODE
return $data if ref($data) eq 'CODE';
$res->render($data) unless $res->rendered;
return $data if ref $data eq 'CODE';
$res->render( $data ) unless $res->rendered;
}

# Do not go any further if we got a render
last if $res->rendered;
}

# If nothing got rendered
Expand All @@ -268,7 +269,7 @@ sub psgi {
}
}

$self->finalize;
return $self->finalize;
}
catch {
my $exception = $_;
Expand All @@ -287,9 +288,10 @@ sub psgi {
$self->logger( 'critical', $message ) if $self->can('logger');

# Render 500
$res->render_500($_);
$res->render_500($exception);
}
$self->finalize;

return $self->finalize;
};
}

Expand Down Expand Up @@ -340,6 +342,18 @@ sub abs_url {
return URI->new_abs( $url, $self->config('app_url') )->as_string;
}

sub charset_encode {
my ( $self, $string ) = @_;
return $string unless $self->charset;
return encode $self->charset, $string;
}

sub charset_decode {
my ( $self, $string ) = @_;
return $string unless $self->charset;
return decode $self->charset, $string;
}

1;

__END__
Expand Down Expand Up @@ -512,8 +526,8 @@ class will be used.
=head2 charset
Sets of gets the encoding charset of the app. It will be C<UTF-8>, if not set to
anything else. The charset could also be changed in the config files.
Gets the encoding charset of the app. It will be C<UTF-8>, if not set to
anything else. The charset can changed in the config files.
=head2 long_error
Expand Down Expand Up @@ -725,6 +739,12 @@ arguments.
Same as L</url_for>, but returns the full absolute URI for the current
application (based on configuration).
=head2 charset_encode
=head2 charset_decode
Shortcut methods, which encode or decode a string using the application's current L</charset>.
=head1 AUTHOR
Stefan Geneshky - minimal <at> cpan.org
Expand Down
Loading

0 comments on commit 31e30c0

Please sign in to comment.