Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/Dancer2.pm
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use Import::Into;
use Dancer2::Core;
use Dancer2::Core::App;
use Dancer2::Core::Runner;
use Dancer2::FileUtils;

our $AUTHORITY = 'SUKRIA';

Expand Down
48 changes: 26 additions & 22 deletions lib/Dancer2/CLI/Command/gen.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,11 @@ use warnings;
use App::Cmd::Setup -command;

use HTTP::Tiny;
use Path::Tiny ();
use File::Find;
use File::Path 'mkpath';
use File::Spec::Functions;
use File::Share 'dist_dir';
use File::Basename qw/dirname basename/;
use Dancer2::Template::Simple;
use Module::Runtime 'require_module';
use Dancer2::Template::Simple;

my $SKEL_APP_FILE = 'lib/AppFile.pm';

Expand Down Expand Up @@ -45,12 +43,12 @@ sub validate_args {
);
}

my $path = $opt->{path};
-d $path or $self->usage_error("directory '$path' does not exist");
my $path = Path::Tiny::path( $opt->{path} );
$path->is_dir or $self->usage_error("directory '$path' does not exist");
-w $path or $self->usage_error("directory '$path' is not writeable");

if ( my $skel_path = $opt->{skel} ) {
-d $skel_path
Path::Tiny::path($skel_path)->is_dir
or $self->usage_error("skeleton directory '$skel_path' not found");
}
}
Expand All @@ -59,30 +57,35 @@ sub execute {
my ($self, $opt, $args) = @_;
$self->_version_check() unless $opt->{'no_check'};

my $dist_dir = dist_dir('Dancer2');
my $skel_dir = $opt->{skel} || catdir($dist_dir, 'skel');
-d $skel_dir or die "$skel_dir doesn't exist";
my @dirs =
$opt->{'skel'}
? ($opt->{'skel'})
: (dist_dir('Dancer2'), 'skel');

my $skel_dir = Path::Tiny::path(@dirs);
$skel_dir->is_dir
or die "Skeleton directory '$skel_dir' doesn't exist";

my $app_name = $opt->{application};
my $app_file = _get_app_file($app_name);
my $app_path = _get_app_path($opt->{path}, $app_name);

if( my $dir = $opt->{directory} ) {
$app_path = catdir( $opt->{path}, $dir );
$app_path = Path::Tiny::path( $opt->{path}, $dir );
}

my $files_to_copy = _build_file_list($skel_dir, $app_path);
foreach my $pair (@$files_to_copy) {
if ($pair->[0] =~ m/$SKEL_APP_FILE$/) {
$pair->[1] = catfile($app_path, $app_file);
$pair->[1] = Path::Tiny::path($app_path, $app_file);
last;
}
}

my $vars = {
appname => $app_name,
appfile => $app_file,
appdir => File::Spec->rel2abs($app_path),
appdir => Path::Tiny::path($app_path)->absolute,
perl_interpreter => _get_perl_interpreter(),
cleanfiles => _get_dashed_name($app_name),
dancer_version => $self->version(),
Expand Down Expand Up @@ -148,7 +151,7 @@ sub _build_file_list {
my $is_git = $file =~ m{^\.git(/|$)}
and return;

push @result, [ $_, catfile($to, $file) ];
push @result, [ $_, Path::Tiny::path($to, $file) ];
};

find({ wanted => $wanted, no_chdir => 1 }, $from);
Expand All @@ -167,15 +170,15 @@ sub _copy_templates {
next unless ($res eq 'y') or ($res eq 'a');
}

my $to_dir = dirname($to);
if (! -d $to_dir) {
my $to_dir = Path::Tiny::path($to)->parent;
if (! $to_dir->is_dir ) {
print "+ $to_dir\n";
mkpath $to_dir or die "could not mkpath $to_dir: $!";
$to_dir->mkpath or die "could not mkpath $to_dir: $!";
}

my $to_file = basename($to);
my $to_file = Path::Tiny::path($to)->parent->stringify;
my $ex = ($to_file =~ s/^\+//);
$to = catfile($to_dir, $to_file) if $ex;
$to = Path::Tiny::path($to_dir, $to_file)->stringify if $ex;

print "+ $to\n";
my $content;
Expand Down Expand Up @@ -210,7 +213,7 @@ sub _create_manifest {

foreach my $file (@{$files}) {
my $filename = substr $file->[1], length($dir) + 1;
my $basename = basename $filename;
my $basename = path($filename)->parent->stringify;
my $clean_basename = $basename;
$clean_basename =~ s/^\+//;
$filename =~ s/\Q$basename\E/$clean_basename/;
Expand Down Expand Up @@ -239,13 +242,14 @@ sub _process_template {

sub _get_app_path {
my ($path, $appname) = @_;
return catdir($path, _get_dashed_name($appname));
return Path::Tiny::path($path, _get_dashed_name($appname) );
}

sub _get_app_file {
my $appname = shift;

$appname =~ s{::}{/}g;
return catfile('lib', "$appname.pm");
return Path::Tiny::path( 'lib', "$appname.pm" );
}

sub _get_perl_interpreter {
Expand Down
12 changes: 6 additions & 6 deletions lib/Dancer2/Cookbook.pod
Original file line number Diff line number Diff line change
Expand Up @@ -903,13 +903,13 @@ API and then displays it dynamically in a web page.

Other than L<Dancer2> for defining routes, we will use L<HTTP::Tiny>
to make the weather API request, L<JSON> to decode it from JSON format,
and finally L<File::Spec> to provide a fully-qualified path to our
and finally L<Path::Tiny> to provide a fully-qualified path to our
template engine.

use JSON;
use Dancer2;
use HTTP::Tiny;
use File::Spec;
use Path::Tiny;

=head4 Configuration

Expand All @@ -919,16 +919,16 @@ to I<views> directory in our current directory. Since we want to put our
template in our current directory, we will configure that. However,
I<Template::Toolkit> does not want us to provide a relative path without
configuring it to allow it. This is a security issue. So, we're using
L<File::Spec> to create a full path to where we are.
L<Path::Tiny> to create a full path to where we are.

We also unset the default layout, so Dancer won't try to wrap our template
with another one. This is a feature in Dancer to allow you to wrap your
templates with a layout when your templating system doesn't support it. Since
we're not using a layout here, we don't need it.

set template => 'template_toolkit'; # set template engine
set layout => undef; # disable layout
set views => File::Spec->rel2abs('.'); # full path to views
set template => 'template_toolkit'; # set template engine
set layout => undef; # disable layout
set views => Path::Tiny->cwd->absolute; # full path to views

Now, we define our URL:

Expand Down
56 changes: 40 additions & 16 deletions lib/Dancer2/Core/App.pm
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use Scalar::Util 'blessed';
use Module::Runtime 'is_module_name';
use Safe::Isa;
use Sub::Quote;
use File::Spec;
use Path::Tiny ();
use Module::Runtime 'use_module';
use List::Util ();
use Ref::Util qw< is_ref is_globref is_scalarref >;
Expand All @@ -18,18 +18,16 @@ use Plack::Middleware::Head;
use Plack::Middleware::Conditional;
use Plack::Middleware::ConditionalGET;

use Dancer2::FileUtils 'path';
use Dancer2::Core;
use Dancer2::Core::Cookie;
use Dancer2::Core::HTTP;
use Dancer2::Core::Error;
use Dancer2::Core::Types;
use Dancer2::Core::Route;
use Dancer2::Core::Hook;
use Dancer2::Core::Request;
use Dancer2::Core::Factory;

use Dancer2::Handler::File;

our $EVAL_SHIM; $EVAL_SHIM ||= sub {
my $code = shift;
$code->(@_);
Expand Down Expand Up @@ -245,7 +243,7 @@ sub _build_session_engine {
# Note that engine options will replace the default session_dir (if provided).
return $self->_factory->create(
session => $value,
session_dir => path( $self->config->{appdir}, 'sessions' ),
session_dir => Path::Tiny::path( $self->config->{appdir}, 'sessions' )->stringify,
%{$engine_options},
postponed_hooks => $self->postponed_hooks,

Expand Down Expand Up @@ -681,13 +679,13 @@ around execute_hook => sub {
sub _build_default_config {
my $self = shift;

my $public = $ENV{DANCER_PUBLIC} || path( $self->location, 'public' );
my $public = $ENV{DANCER_PUBLIC} || Path::Tiny::path( $self->location, 'public' )->stringify;
return {
content_type => ( $ENV{DANCER_CONTENT_TYPE} || 'text/html' ),
charset => ( $ENV{DANCER_CHARSET} || '' ),
logger => ( $ENV{DANCER_LOGGER} || 'console' ),
views => ( $ENV{DANCER_VIEWS}
|| path( $self->location, 'views' ) ),
|| Path::Tiny::path( $self->location, 'views' )->stringify ),
environment => $self->environment,
appdir => $self->location,
public_dir => $public,
Expand Down Expand Up @@ -1030,30 +1028,41 @@ sub send_file {
}
# static file dir - either system root or public_dir
my $dir = $options{system_path}
? File::Spec->rootdir
? Path::Tiny->rootdir
: $ENV{DANCER_PUBLIC}
|| $self->config->{public_dir}
|| path( $self->location, 'public' );
|| Path::Tiny::path( $self->location, 'public' )->stringify;

$file_path = Dancer2::Handler::File->merge_paths( $path, $dir );
my $err_response = sub {
my $status = shift;
$self->response->status($status);
$self->response->header( 'Content-Type', 'text/plain' );
$self->response->content( Dancer2::Core::HTTP->status_message($status) );
$self->with_return->( $self->response );
};
$err_response->(403) if !defined $file_path;
$err_response->(404) if !-f $file_path;

# resolve relative paths (with '../') as much as possible
$file_path = Path::Tiny::path( $dir, $path )->realpath;

# We need to check whether they are trying to access
# a directory outside their scope
$err_response->(403) if !Path::Tiny::path($dir)->realpath->subsumes($file_path);

# other error checks
$err_response->(403) if !$file_path->exists;
$err_response->(404) if !$file_path->is_file;
$err_response->(403) if !-r $file_path;

# Read file content as bytes
$fh = Dancer2::FileUtils::open_file( "<", $file_path );
binmode $fh;
$fh = $file_path->openr_raw();

$content_type = Dancer2::runner()->mime_type->for_file($file_path) || 'text/plain';
if ( $content_type =~ m!^text/! ) {
$charset = $self->config->{charset} || "utf-8";
}

# cleanup for other functions not assuming on Path::Tiny
$file_path = $file_path->stringify;
}

# Now we are sure we can render the file...
Expand Down Expand Up @@ -1097,7 +1106,14 @@ sub send_file {
$response = $self->response;
# direct assignment to hash element, avoids around modifier
# trying to serialise this this content.
$response->{content} = Dancer2::FileUtils::read_glob_content($fh);

# optimized slurp
{
## no critic qw(Variables::RequireInitializationForLocalVars)
local $/;
$response->{'content'} = <$fh>;
}

$response->is_encoded(1); # bytes are already encoded
}

Expand Down Expand Up @@ -1402,7 +1418,15 @@ sub to_app {
# when the file exists. Otherwise the request passes into our app.
$psgi = Plack::Middleware::Conditional->wrap(
$psgi,
condition => sub { -f path( $self->config->{public_dir}, shift->{PATH_INFO} ) },
condition => sub {
my $env = shift;
Path::Tiny::path(
$self->config->{'public_dir'},
defined $env->{'PATH_INFO'} && length $env->{'PATH_INFO'}
? ($env->{'PATH_INFO'})
: (),
)->is_file;
},
builder => sub { Plack::Middleware::ConditionalGET->wrap( $static_app ) },
);
}
Expand Down
6 changes: 3 additions & 3 deletions lib/Dancer2/Core/DSL.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ package Dancer2::Core::DSL;

use Moo;
use Carp;
use Path::Tiny ();
use Module::Runtime 'require_module';
use Ref::Util qw< is_arrayref >;
use Dancer2::Core::Hook;
use Dancer2::FileUtils;
use Dancer2::Core::Response::Delayed;

with 'Dancer2::Core::Role::DSL';
Expand Down Expand Up @@ -143,8 +143,8 @@ sub error { shift->app->log( error => @_ ) }
sub true {1}
sub false {0}

sub dirname { shift and Dancer2::FileUtils::dirname(@_) }
sub path { shift and Dancer2::FileUtils::path(@_) }
sub dirname { shift and Path::Tiny::path(@_)->parent->stringify }
sub path { shift and Path::Tiny::path(@_)->stringify }

sub config { shift->app->settings }

Expand Down
7 changes: 3 additions & 4 deletions lib/Dancer2/Core/Error.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use Carp;
use Dancer2::Core::Types;
use Dancer2::Core::HTTP;
use Data::Dumper;
use Dancer2::FileUtils qw/path open_file/;
use Path::Tiny ();
use Sub::Quote;
use Module::Runtime 'require_module';
use Ref::Util qw< is_hashref >;
Expand Down Expand Up @@ -343,9 +343,8 @@ sub backtrace {
return $html unless $file and $line;

# file and line are located, let's read the source Luke!
my $fh = eval { open_file('<', $file) } or return $html;
my @lines = <$fh>;
close $fh;
my @lines;
eval { @lines = Path::Tiny::path($file)->lines_utf8; 1; } or return $html;

$html .= qq|<div class="title">$file around line $line</div>|;

Expand Down
12 changes: 4 additions & 8 deletions lib/Dancer2/Core/Request/Upload.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ package Dancer2::Core::Request::Upload;
use Moo;

use Carp;
use File::Spec;
use Module::Runtime 'require_module';
use Path::Tiny ();
use File::Copy ();

use Dancer2::Core::Types;
use Dancer2::FileUtils qw(open_file);

has filename => (
is => 'ro',
Expand All @@ -33,13 +32,11 @@ has size => (
sub file_handle {
my ($self) = @_;
return $self->{_fh} if defined $self->{_fh};
my $fh = open_file( '<', $self->tempname );
$self->{_fh} = $fh;
$self->{_fh} = Path::Tiny::path( $self->tempname )->openr_raw;
}

sub copy_to {
my ( $self, $target ) = @_;
require_module('File::Copy');
File::Copy::copy( $self->tempname, $target );
}

Expand Down Expand Up @@ -69,8 +66,7 @@ sub content {

sub basename {
my ($self) = @_;
require_module('File::Basename');
File::Basename::basename( $self->filename );
return Path::Tiny::path( $self->filename )->basename;
}

sub type {
Expand Down
Loading