Mojolicious-Plugin-DirectoryServer-1.003/0000755000000000000000000000000014434663720017105 5ustar rootrootMojolicious-Plugin-DirectoryServer-1.003/META.yml0000644000000000000000000000160514434663720020360 0ustar rootroot--- abstract: 'Serve static files from document root with directory index' author: - 'brian d foy ' build_requires: Test::More: '1' configure_requires: ExtUtils::MakeMaker: '6.64' File::Spec::Functions: '0' dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010' license: artistic_2 meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: Mojolicious-Plugin-DirectoryServer no_index: directory: - t - inc requires: Mojolicious: '9' perl: '5.032' resources: bugtracker: https://github.com/briandfoy/mojolicious-plugin-directoryserver/issues homepage: https://github.com/briandfoy/mojolicious-plugin-directoryserver repository: https://github.com/briandfoy/mojolicious-plugin-directoryserver version: '1.003' x_serialization_backend: 'CPAN::Meta::YAML version 0.018' Mojolicious-Plugin-DirectoryServer-1.003/LICENSE0000644000000000000000000004371614434663673020134 0ustar rootrootThis software is copyright (c) 2015 by hayajo . This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. Terms of the Perl programming language system itself a) the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version, or b) the "Artistic License" --- The GNU General Public License, Version 1, February 1989 --- This software is Copyright (c) 2015 by hayajo . This is free software, licensed under: The GNU General Public License, Version 1, February 1989 GNU GENERAL PUBLIC LICENSE Version 1, February 1989 Copyright (C) 1989 Free Software Foundation, Inc. 51 Franklin St, Suite 500, Boston, MA 02110-1335 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The license agreements of most software companies try to keep users at the mercy of those companies. By contrast, our General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. The General Public License applies to the Free Software Foundation's software and to any other program whose authors commit to using it. You can use it for your programs, too. When we speak of free software, we are referring to freedom, not price. Specifically, the General Public License is designed to make sure that you have the freedom to give away or sell copies of free software, that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of a such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must tell them their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any work containing the Program or a portion of it, either verbatim or with modifications. Each licensee is addressed as "you". 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this General Public License and to the absence of any warranty; and give any other recipients of the Program a copy of this General Public License along with the Program. You may charge a fee for the physical act of transferring a copy. 2. You may modify your copy or copies of the Program or any portion of it, and copy and distribute such modifications under the terms of Paragraph 1 above, provided that you also do the following: a) cause the modified files to carry prominent notices stating that you changed the files and the date of any change; and b) cause the whole of any work that you distribute or publish, that in whole or in part contains the Program or any part thereof, either with or without modifications, to be licensed at no charge to all third parties under the terms of this General Public License (except that you may choose to grant warranty protection to some or all third parties, at your option). c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the simplest and most usual way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this General Public License. d) You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. Mere aggregation of another independent work with the Program (or its derivative) on a volume of a storage or distribution medium does not bring the other work under the scope of these terms. 3. You may copy and distribute the Program (or a portion or derivative of it, under Paragraph 2) in object code or executable form under the terms of Paragraphs 1 and 2 above provided that you also do one of the following: a) accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Paragraphs 1 and 2 above; or, b) accompany it with a written offer, valid for at least three years, to give any third party free (except for a nominal charge for the cost of distribution) a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Paragraphs 1 and 2 above; or, c) accompany it with the information you received as to where the corresponding source code may be obtained. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form alone.) Source code for a work means the preferred form of the work for making modifications to it. For an executable file, complete source code means all the source code for all modules it contains; but, as a special exception, it need not include source code for modules which are standard libraries that accompany the operating system on which the executable file runs, or for standard header files or definitions files that accompany that operating system. 4. You may not copy, modify, sublicense, distribute or transfer the Program except as expressly provided under this General Public License. Any attempt otherwise to copy, modify, sublicense, distribute or transfer the Program is void, and will automatically terminate your rights to use the Program under this License. However, parties who have received copies, or rights to use copies, from you under this General Public License will not have their licenses terminated so long as such parties remain in full compliance. 5. By copying, distributing or modifying the Program (or any work based on the Program) you indicate your acceptance of this license to do so, and all its terms and conditions. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. 7. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of the license which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the license, you may choose any version ever published by the Free Software Foundation. 8. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to humanity, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (a program to direct compilers to make passes at assemblers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice That's all there is to it! --- The Artistic License 1.0 --- This software is Copyright (c) 2015 by hayajo . This is free software, licensed under: The Artistic License 1.0 The Artistic License Preamble The intent of this document is to state the conditions under which a Package may be copied, such that the Copyright Holder maintains some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. Definitions: - "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. - "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder. - "Copyright Holder" is whoever is named in the copyright or copyrights for the package. - "You" is you, if you're thinking about copying or distributing this Package. - "Reasonable copying fee" is whatever you can justify on the basis of media cost, duplication charges, time of people involved, and so on. (You will not be required to justify it to the Copyright Holder, but only to the computing community at large as a market that must bear the fee.) - "Freely Available" means that no fee is charged for the item itself, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. 1. You may make and give away verbatim copies of the source form of the Standard Version of this Package without restriction, provided that you duplicate all of the original copyright notices and associated disclaimers. 2. You may apply bug fixes, portability fixes and other modifications derived from the Public Domain or from the Copyright Holder. A Package modified in such a way shall still be considered the Standard Version. 3. You may otherwise modify your copy of this Package in any way, provided that you insert a prominent notice in each changed file stating how and when you changed that file, and provided that you do at least ONE of the following: a) place your modifications in the Public Domain or otherwise make them Freely Available, such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive site such as ftp.uu.net, or by allowing the Copyright Holder to include your modifications in the Standard Version of the Package. b) use the modified Package only within your corporation or organization. c) rename any non-standard executables so the names do not conflict with standard executables, which must also be provided, and provide a separate manual page for each non-standard executable that clearly documents how it differs from the Standard Version. d) make other distribution arrangements with the Copyright Holder. 4. You may distribute the programs of this Package in object code or executable form, provided that you do at least ONE of the following: a) distribute a Standard Version of the executables and library files, together with instructions (in the manual page or equivalent) on where to get the Standard Version. b) accompany the distribution with the machine-readable source of the Package with your modifications. c) accompany any non-standard executables with their corresponding Standard Version executables, giving the non-standard executables non-standard names, and clearly documenting the differences in manual pages (or equivalent), together with instructions on where to get the Standard Version. d) make other distribution arrangements with the Copyright Holder. 5. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. However, you may distribute this Package in aggregate with other (possibly commercial) programs as part of a larger (possibly commercial) software distribution provided that you do not advertise this Package as a product of your own. 6. The scripts and library files supplied as input to or produced as output from the programs of this Package do not automatically fall under the copyright of this Package, but belong to whomever generated them, and may be sold commercially, and may be aggregated with this Package. 7. C or perl subroutines supplied by you and linked into this Package shall not be considered part of this Package. 8. The name of the Copyright Holder may not be used to endorse or promote products derived from this software without specific prior written permission. 9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. The End Mojolicious-Plugin-DirectoryServer-1.003/MANIFEST0000644000000000000000000000101114434663720020227 0ustar rootrootChanges cpanfile examples/documents/css/github.css examples/documents/index.md examples/documents/subdir/foo.md examples/markdown_viewer lib/iniweb.pm lib/Mojolicious/Plugin/DirectoryServer.pm LICENSE Makefile.PL MANIFEST This list of files MANIFEST.SKIP META.json README.pod t/00_compile.t t/auto_index.t t/default.t t/dir.t t/dir/delete.me t/dir/index.html t/dir_index.t t/dir_page.t t/dummy.txt t/file.t t/handle.t t/path_walking.t META.yml Module YAML meta-data (added by MakeMaker) Mojolicious-Plugin-DirectoryServer-1.003/lib/0000755000000000000000000000000014434663720017653 5ustar rootrootMojolicious-Plugin-DirectoryServer-1.003/lib/Mojolicious/0000755000000000000000000000000014434663720022147 5ustar rootrootMojolicious-Plugin-DirectoryServer-1.003/lib/Mojolicious/Plugin/0000755000000000000000000000000014434663720023405 5ustar rootrootMojolicious-Plugin-DirectoryServer-1.003/lib/Mojolicious/Plugin/DirectoryServer.pm0000644000000000000000000001702114434663673027106 0ustar rootrootuse v5.32; package Mojolicious::Plugin::DirectoryServer; our $VERSION = '1.003'; use Cwd (); use Encode (); use DirHandle; use Mojo::Base qw( Mojolicious::Plugin -signatures ); use Mojo::JSON qw(encode_json); use Mojolicious::Types; # Stolen from Plack::App::Direcotry my $dir_page = <<'PAGE'; Index of <%= $cur_path %>

Index of <%= $cur_path %>


% for my $file (@$files) { % }
Name Size Type Last Modified
<%== $file->{name} %><%= $file->{size} %><%= $file->{type} %><%= $file->{mtime} %>

PAGE my $types = Mojolicious::Types->new; sub register { my ( $self, $app, $args ) = @_; my $root = Mojo::Home->new( $args->{root} || Cwd::getcwd ); my $handler = $args->{handler}; my $index = $args->{dir_index}; my $auto_index = $args->{auto_index} // 1; my $json = $args->{json}; $dir_page = $args->{dir_page} if ( $args->{dir_page} ); $app->hook( before_dispatch => sub { my $c = shift; return render_file( $c, $root, $handler ) if ( -f $root->to_string() ); if( $c->req->url->path =~ m"\Q/..\E(/|\z)"n ) { $c->reply->not_found; return; } my $path = $root->rel_file( Mojo::Util::url_unescape( $c->req->url->path ) ); if ( -f $path ) { render_file( $c, $path, $handler ); } elsif ( -d $path ) { if ( $index && ( my $index_path = locate_index( $index, $path ) ) ) { return render_file( $c, $index_path, $handler ); } if ( $c->req->url->path ne '/' && ! $c->req->url->path->trailing_slash ) { $c->redirect_to($c->req->url->path->trailing_slash(1)); return; } if( $auto_index ) { render_indexes( $c, $path, $json ); } else { $c->reply->not_found; } } }, ); return $app; } sub locate_index { my $index = shift || return; my $dir = shift || Cwd::getcwd; my $root = Mojo::Home->new($dir); $index = ( ref $index eq 'ARRAY' ) ? $index : ["$index"]; for (@$index) { my $path = $root->rel_file($_); return $path if ( -e $path ); } } sub render_file ($c, $path, $handler) { $handler->( $c, $path ) if ref $handler eq 'CODE'; return if $c->tx->res->code; $c->reply->file($path); } sub render_indexes ($c, $dir, $json) { my @files = ( $c->req->url->path eq '/' ) ? () : ( { url => '../', name => 'Parent Directory', size => '', type => '', mtime => '' } ); my $children = list_files($dir); my $cur_path = Encode::decode_utf8( Mojo::Util::url_unescape( $c->req->url->path ) ); for my $basename ( sort { $a cmp $b } @$children ) { my $file = "$dir/$basename"; my $url = Mojo::Path->new($cur_path)->trailing_slash(0); push @{ $url->parts }, $basename; my $is_dir = -d $file; my @stat = stat _; if ($is_dir) { $basename .= '/'; $url->trailing_slash(1); } my $mime_type = $is_dir ? 'directory' : ( $types->type( get_ext($file) || 'txt' ) || 'text/plain' ); my $mtime = Mojo::Date->new( $stat[9] )->to_string(); push @files, { url => $url, name => $basename, size => $stat[7] || 0, type => $mime_type, mtime => $mtime, }; } my $any = { inline => $dir_page, files => \@files, cur_path => $cur_path }; if ($json) { $c->respond_to( json => { json => encode_json(\@files) }, any => $any, ); } else { $c->render( %$any ); } } sub get_ext { $_[0] =~ /\.([0-9a-zA-Z]+)$/ || return; return lc $1; } sub list_files { my $dir = shift || return []; my $dh = DirHandle->new($dir); my @children; while ( defined( my $ent = $dh->read ) ) { next if $ent eq '.' or $ent eq '..'; push @children, Encode::decode_utf8($ent); } return [ @children ]; } 1; __END__ =head1 NAME Mojolicious::Plugin::DirectoryServer - Serve static files from document root with directory index =head1 SYNOPSIS # simple usage use Mojolicious::Lite; plugin( 'DirectoryServer', root => "/path/to/htdocs" )->start; # with handler use Text::Markdown qw{ markdown }; use Path::Class; use Encode qw{ decode_utf8 }; plugin('DirectoryServer', root => "/path/to/htdocs", handler => sub { my ($c, $path) = @_; if ( -f $path && $path =~ /\.(md|mkdn)$/ ) { my $text = file($path)->slurp; my $html = markdown( decode_utf8($text) ); $c->render( inline => $html ); } })->start; or > perl -Mojo -E 'a->plugin("DirectoryServer", root => "/path/to/htdocs")->start' daemon or > perl -Miniweb =head1 DESCRIPTION L is a static file server with a directory index similar to Apache's mod_autoindex. =head2 Methods L inherits all methods from L. =head2 Options L supports the following options. =over 4 =item * C # Mojolicious::Lite plugin DirectoryServer => { root => "/path/to/htdocs" }; Document root directory. Defaults to the current directory. If root is a file, serve only root file. =item * C # Mojolicious::Lite plugin DirectoryServer => { auto_index => 0 }; Automatically generate index page for directory, default true. =item * C # Mojolicious::Lite plugin DirectoryServer => { dir_index => [qw/index.html index.htm/] }; Like a Apache's DirectoryIndex directive. =item * C # Mojolicious::Lite plugin DirectoryServer => { dir_page => $template_str }; a HTML template of index page =item * C # Mojolicious::Lite use Text::Markdown qw{ markdown }; use Path::Class; use Encode qw{ decode_utf8 }; plugin DirectoryServer => { handler => sub { my ($c, $path) = @_; if ($path =~ /\.(md|mkdn)$/) { my $text = file($path)->slurp; my $html = markdown( decode_utf8($text) ); $c->render( inline => $html ); } } }; CODEREF for handle a request file. If not rendered in CODEREF, serve as static file. =item * C # Mojolicious::Lite # /dir (Accept: application/json) # /dir?_format=json plugin DirectoryServer => { json => 1 }; Enable json response. =back =head1 AUTHOR The original author was hayajo Ehayajo@cpan.orgE. The module was forked by brian d foy Ebdfoy@cpan.orgE after the module was abandoned. =head1 CONTRIBUTORS Many thanks to the contributors for their work. =over 4 =item ChinaXing =back =head1 SEE ALSO L, L. =head1 LICENSE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut Mojolicious-Plugin-DirectoryServer-1.003/lib/iniweb.pm0000644000000000000000000000213114434663673021472 0ustar rootrootpackage iniweb; use feature ':5.16'; use ojo; sub import { $ENV{PERL_MINIWEB_ROOT} //= '.'; $ENV{PERL_MINIWEB_DIR_INDEX} //= 'index.html:index.htm'; local @ARGV = 'daemon'; my %opts = ( root => $ENV{PERL_MINIWEB_ROOT}, dir_index => [ split ':', $ENV{PERL_MINIWEB_DIR_INDEX} ], ); a->plugin( DirectoryServer => %opts )->start; exit( 0 ); } 1; =head1 NAME iniweb - Very quickly spawn a web server =head1 SYNOPSIS perl -Miniweb =head1 DESCRIPTION The command in the synopsis will spawn a web server, serving static files from the current working directory. =head2 Environment Variables =over =item C Root directory to serve. Defaults to the current directory. =item C Colon-seperated list of filenames to treat as a directory index. Defaults to C<< "index.html:index.htm" >>. =back =head1 AUTHOR Toby Inkster Etobyink@cpan.orgE. =head1 SEE ALSO L =head1 LICENSE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut Mojolicious-Plugin-DirectoryServer-1.003/t/0000755000000000000000000000000014434663720017350 5ustar rootrootMojolicious-Plugin-DirectoryServer-1.003/t/file.t0000644000000000000000000000061514434663673020465 0ustar rootrootuse Mojo::Base qw{ -strict }; use Mojolicious::Lite; use File::Basename; use File::Spec; my $dir = dirname(__FILE__); plugin 'DirectoryServer', root => File::Spec->catfile( $dir, 'dummy.txt' ); use Test::More tests => 6; use Test::Mojo; my $t = Test::Mojo->new; $t->get_ok('/')->status_is(200)->content_like(qr/^DUMMY$/); $t->get_ok('/foo/bar/buz')->status_is(200)->content_like(qr/^DUMMY$/); Mojolicious-Plugin-DirectoryServer-1.003/t/dir.t0000644000000000000000000000152114434663673020321 0ustar rootrootuse Mojo::Base qw{ -strict }; use Mojolicious::Lite; use File::Basename; use Encode (); use version; my $dir = dirname(__FILE__); plugin 'DirectoryServer', root => $dir, json => 1; use Test::More tests => 2; use Test::Mojo; my $t = Test::Mojo->new; subtest 'entries' => sub { $t->get_ok('/')->status_is(200); my $dh = DirHandle->new($dir); while ( defined( my $ent = $dh->read ) ) { next if $ent eq '.' or $ent eq '..'; $ent = Encode::decode_utf8($ent); $t->content_like(qr/$ent/); } }; subtest 'json' => sub { my $res = $t->get_ok('/?_format=json')->status_is(200); if ( version->parse($Mojolicious::VERSION)->numify >= version->parse('6.09')->numify ) { $res->content_type_is('application/json;charset=UTF-8'); } else { $res->content_type_is('application/json'); } }; Mojolicious-Plugin-DirectoryServer-1.003/t/dir_index.t0000644000000000000000000000071514434663673021514 0ustar rootrootuse Mojo::Base qw{ -strict }; use Mojolicious::Lite; use File::Basename; use Mojo::Home; use Encode (); my $dir = dirname(__FILE__); plugin 'DirectoryServer', root => Mojo::Home->new($dir)->rel_file('dir'), dir_index => [qw/index.html index.htm/]; use Test::More tests => 3; use Test::Mojo; my $t = Test::Mojo->new; $t->get_ok('/')->status_is(200); my $body = $t->tx->res->dom->at('body')->text; is Mojo::Util::trim($body), 'Hello World'; Mojolicious-Plugin-DirectoryServer-1.003/t/default.t0000644000000000000000000000057514434663673021177 0ustar rootrootuse Mojo::Base qw{ -strict }; use Mojolicious::Lite; plugin 'DirectoryServer'; use Test::More tests => 3; use Test::Mojo; my $t = Test::Mojo->new; $t->get_ok('/')->status_is(200); subtest 'entries' => sub { my $dh = DirHandle->new('.'); while ( defined( my $ent = $dh->read ) ) { next if $ent eq '.' or $ent eq '..'; $t->content_like(qr/$ent/); } } Mojolicious-Plugin-DirectoryServer-1.003/t/00_compile.t0000644000000000000000000000014114434663673021467 0ustar rootrootuse strict; use Test::More; END {done_testing()} use_ok 'Mojolicious::Plugin::DirectoryServer'; Mojolicious-Plugin-DirectoryServer-1.003/t/dir/0000755000000000000000000000000014434663720020126 5ustar rootrootMojolicious-Plugin-DirectoryServer-1.003/t/dir/index.html0000644000000000000000000000020414434663673022126 0ustar rootroot test Hello World Mojolicious-Plugin-DirectoryServer-1.003/t/dir/delete.me0000644000000000000000000000001214434663673021713 0ustar rootrootdelete me Mojolicious-Plugin-DirectoryServer-1.003/t/path_walking.t0000644000000000000000000000076414434663673022223 0ustar rootrootuse Mojo::Base qw{ -strict }; use Mojolicious::Lite; use File::Basename; my $dir = dirname(__FILE__); plugin 'DirectoryServer', root => $dir; use Test::More; use Test::Mojo; my $t = Test::Mojo->new; subtest good_paths => sub { $t->get_ok('/')->status_is(200); $t->get_ok('/dir/index.html')->status_is(200); $t->get_ok('/foo/bar/buz')->status_is(404); }; subtest '.. paths' => sub { $t->get_ok('/..')->status_is(404); $t->get_ok('/dir/../index.html')->status_is(404); }; done_testing(); Mojolicious-Plugin-DirectoryServer-1.003/t/auto_index.t0000644000000000000000000000041114434663673021677 0ustar rootrootuse Mojo::Base qw{ -strict }; use Mojolicious::Lite; use File::Basename; my $dir = dirname(__FILE__); plugin 'DirectoryServer', root => $dir, auto_index => 0; use Test::More tests => 2; use Test::Mojo; my $t = Test::Mojo->new; $t->get_ok('/')->status_is(404); Mojolicious-Plugin-DirectoryServer-1.003/t/handle.t0000644000000000000000000000224514434663673021002 0ustar rootrootuse Mojo::Base qw{ -strict }; use Mojolicious::Lite; use File::Basename; use File::Spec; use Encode (); my $dir = dirname(__FILE__); plugin 'DirectoryServer', root => $dir, handler => sub { my ($c, $path) = @_; $c->render( data => $path, format => 'txt' ) if (-f $path); }; use Test::More; use Test::Mojo; my $t = Test::Mojo->new; $t->get_ok('/')->status_is(200); my $location_is = sub { my ($t, $regex, $desc) = @_; local $Test::Builder::Level = $Test::Builder::Level + 1; return $t->success(like($t->tx->res->headers->location, $regex)); }; subtest 'entries' => sub { my $dh = DirHandle->new($dir); while ( defined( my $ent = $dh->read ) ) { $ent = Encode::decode_utf8($ent); next if $ent eq '.' or $ent eq '..'; my $path = File::Spec->catdir( $dir, $ent ); if (-f $path) { $t->get_ok("/$ent")->status_is(200)->content_is( Encode::encode_utf8($path) ); } elsif (-d $path) { $t->get_ok("/$ent")->status_is(302)->$location_is(qr|/$ent/$|); $t->get_ok("/$ent/")->status_is(200)->content_like( qr/Parent Directory/ ); } else { ok 0 } } }; done_testing(); Mojolicious-Plugin-DirectoryServer-1.003/t/dummy.txt0000644000000000000000000000000614434663673021247 0ustar rootrootDUMMY Mojolicious-Plugin-DirectoryServer-1.003/t/dir_page.t0000644000000000000000000000114014434663673021312 0ustar rootrootuse Mojo::Base qw{ -strict }; use Mojolicious::Lite; use File::Basename; my $dir = dirname(__FILE__); plugin 'DirectoryServer', root => $dir, dir_page => <<'EOF'; entries: <%= scalar @$files %> EOF use Test::More tests => 3; use Test::Mojo; my $t = Test::Mojo->new; $t->get_ok('/')->status_is(200); use File::Basename; subtest 'entries' => sub { my $dh = DirHandle->new($dir); my $entries; while ( defined( my $ent = $dh->read ) ) { next if -d $ent or $ent eq '.' or $ent eq '..'; $entries++; } $t->get_ok('/')->status_is(200)->content_like(qr/entries: $entries/); } Mojolicious-Plugin-DirectoryServer-1.003/Changes0000644000000000000000000000343014434663673020407 0ustar rootrootRevision history for Mojolicious-Plugin-DirectoryServer 1.003 2023-05-28T13:32:10Z * Update documents to use the right namespace (GitHub #3, lbe) 1.002 2023-04-03T08:26:18Z * tobyink added the iniweb.pm so you can type perl -Miniweb to start a server in the local directory. 1.001 2023-03-06T10:48:05Z * First release of a fork of Mojolicious::Plugin::Directory, which has been abandoned. This is a static file server with auto_index for directory entries. # Beyond here is from Mojolicious::Plugin::Directory # https://github.com/hayajo/Mojolicious-Plugin-Directory 0.14 2017-04-30T04:13:45Z - changed required version to Mojolicious 7.15 or higher. 0.13 2017-04-30T03:54:40Z - fixed issue #5. thanks plicease@github 0.12 2016-07-22T02:21:24Z - fixed to pass the test with Mojolicious 7. 0.11 2015-04-28T03:13:29Z - fixed a bug in the test. 0.10 2015-04-27T13:56:32Z - fixed the test because Mojolicious::Types came get the json MIME type with charset. 0.09 2015-01-29T02:20:25Z - fixed to use Mojo::JSON with functional interface. thanks reneeb@github - minillaize 0.08 2013-06-09 16:34:06 JST - added auto_index configuration. thanks ChinaXing@github - added json configuration. 0.07 2013-05-17 11:50:14 JST - changed to Mojolicious::Controller#render from Mojolicious::Controller#render_data - millaize 0.06 - added dir_index configuration 0.05 - modified the order of handler execution 0.04 - fixed to get request path with Mojo::URL->path - changed to "$cur_path" from "$cur_url" in dir_page tempalte 0.03 - fixed to pass the test on Windows 0.02 - added dir_page configuration - added handler configuration 0.01 - original version Mojolicious-Plugin-DirectoryServer-1.003/README.pod0000644000000000000000000001102514434663673020554 0ustar rootroot=pod =encoding utf8 =for HTML =for HTML =for HTML =for HTML =for HTML Coverage Status =for HTML =for HTML =head1 The Mojolicious::Plugin::DirectoryServer module This is the I for the L, look at the embedded documentation in the module itself. Inside the distribution, you can format it with L: % perldoc lib/Mojolicious/Plugin/DirectoryServer.pm If you have already installed the module, you can specify the module name instead of the file location: % perldoc Mojolicious::Plugin::DirectoryServer You can read the documentation and inspect the meta data on L. The standard module documentation has example uses in the SYNOPSIS section, but you can also look in the I directory (if it's there), or look at the test files in I. =head2 Installation You can install this module with a CPAN client, which will resolve and install the dependencies: % cpan Mojolicious::Plugin::DirectoryServer % cpanm Mojolicious::Plugin::DirectoryServer You can also install directly from the distribution directory, which will also install the dependencies: % cpan . % cpanm . You could install just this module manually: % perl Makefile.PL % make % make test % make install You probably don't want to do that unless you're fiddling with the module and only want to run the tests without installing anything. =head2 Source location The meta data, such as the source repository and bug tracker, is in I or the I files it creates. You can find that on those CPAN web interfaces, but you can also look at files directly in the source repository: =over 4 =item * L =back If you find a problem, file a ticket in the L: =over 4 =item * L =back =head2 Getting help Although I'm happy to hear from module users in private email, that's the best way for me to forget to do something. Besides the issue trackers, you can find help at L or L, both of which have many competent Perlers who can answer your question, almost in real time. They might not know the particulars of this module, but they can help you diagnose your problem. You might like to read L. =head2 Copyright and License You should have received a I file, but the license is also noted in the module files. About the only thing you can't do is pretend that you wrote code that you didn't. =head2 Good luck! Enjoy, brian d foy, bdfoy@cpan.org =cut Mojolicious-Plugin-DirectoryServer-1.003/MANIFEST.SKIP0000644000000000000000000000233414434663673021014 0ustar rootroot #!start included /usr/local/perls/perl-5.22.0/lib/5.22.0/ExtUtils/MANIFEST.SKIP # Avoid version control files. \bRCS\b \bCVS\b \bSCCS\b ,v$ \B\.svn\b \B\.git\b \B\.gitignore\b \b_darcs\b \B\.cvsignore$ # Avoid VMS specific MakeMaker generated files \bDescrip.MMS$ \bDESCRIP.MMS$ \bdescrip.mms$ # Avoid Makemaker generated and utility files. \bMANIFEST\.bak \bMakefile$ \bblib/ \bMakeMaker-\d \bpm_to_blib\.ts$ \bpm_to_blib$ \bblibdirs\.ts$ # 6.18 through 6.25 generated this \b_eumm/ # 7.05_05 and above # Avoid Module::Build generated and utility files. \bBuild$ \b_build/ \bBuild.bat$ \bBuild.COM$ \bBUILD.COM$ \bbuild.com$ # and Module::Build::Tiny generated files \b_build_params$ # Avoid temp and backup files. ~$ \.old$ \#$ \b\.# \.bak$ \.tmp$ \.# \.rej$ \..*\.sw.?$ # Avoid OS-specific files/dirs # Mac OSX metadata \B\.DS_Store # Mac OSX SMB mount metadata files \B\._ # Avoid Devel::Cover and Devel::CoverX::Covered files. \bcover_db\b \bcovered\b # Avoid prove files \B\.prove$ # Avoid MYMETA files ^MYMETA\. #!end included /usr/local/perls/perl-5.22.0/lib/5.22.0/ExtUtils/MANIFEST.SKIP \.releaserc \.lwpcookies \.appveyor\.yml \bMANIFEST\s\d \bChanges\s\d \.icloud$ \A\.github\b \.gitattributes\b Mojolicious-Plugin-DirectoryServer-1.003/cpanfile0000644000000000000000000000023714434663673020622 0ustar rootrootrequires 'perl', '5.010001'; # requires 'Some::Module', 'VERSION'; requires 'Mojolicious', '>= 7.15'; on test => sub { requires 'Test::More', '0.88'; }; Mojolicious-Plugin-DirectoryServer-1.003/META.json0000644000000000000000000000302614434663720020527 0ustar rootroot{ "abstract" : "Serve static files from document root with directory index", "author" : [ "brian d foy " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version 2.150010", "license" : [ "artistic_2" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "Mojolicious-Plugin-DirectoryServer", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : {} }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "6.64", "File::Spec::Functions" : "0" } }, "runtime" : { "requires" : { "Mojolicious" : "9", "perl" : "5.032" } }, "test" : { "requires" : { "Test::More" : "1" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/briandfoy/mojolicious-plugin-directoryserver/issues" }, "homepage" : "https://github.com/briandfoy/mojolicious-plugin-directoryserver", "repository" : { "type" : "git", "url" : "https://github.com/briandfoy/mojolicious-plugin-directoryserver", "web" : "https://github.com/briandfoy/mojolicious-plugin-directoryserver" } }, "version" : "1.003", "x_serialization_backend" : "JSON::PP version 4.07" } Mojolicious-Plugin-DirectoryServer-1.003/examples/0000755000000000000000000000000014434663720020723 5ustar rootrootMojolicious-Plugin-DirectoryServer-1.003/examples/documents/0000755000000000000000000000000014434663720022724 5ustar rootrootMojolicious-Plugin-DirectoryServer-1.003/examples/documents/subdir/0000755000000000000000000000000014434663720024214 5ustar rootrootMojolicious-Plugin-DirectoryServer-1.003/examples/documents/subdir/foo.md0000644000000000000000000000005414434663673025327 0ustar rootrootThis is subdir/foo.md ===================== Mojolicious-Plugin-DirectoryServer-1.003/examples/documents/index.md0000644000000000000000000000014414434663673024363 0ustar rootrootMarkdown Viewer =============== Other Documents --------------- - [subdir/foo.md](subdir/foo.md) Mojolicious-Plugin-DirectoryServer-1.003/examples/documents/css/0000755000000000000000000000000014434663720023514 5ustar rootrootMojolicious-Plugin-DirectoryServer-1.003/examples/documents/css/github.css0000644000000000000000000001272214434663673025523 0ustar rootrootbody { font-family: Helvetica, arial, sans-serif; font-size: 14px; line-height: 1.6; padding-top: 10px; padding-bottom: 10px; background-color: white; padding: 30px; } body > *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } a { color: #4183C4; } a.absent { color: #cc0000; } a.anchor { display: block; padding-left: 30px; margin-left: -30px; cursor: pointer; position: absolute; top: 0; left: 0; bottom: 0; } h1, h2, h3, h4, h5, h6 { margin: 20px 0 10px; padding: 0; font-weight: bold; -webkit-font-smoothing: antialiased; cursor: text; position: relative; } h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor { background: url("../../images/modules/styleguide/para.png") no-repeat 10px center; text-decoration: none; } h1 tt, h1 code { font-size: inherit; } h2 tt, h2 code { font-size: inherit; } h3 tt, h3 code { font-size: inherit; } h4 tt, h4 code { font-size: inherit; } h5 tt, h5 code { font-size: inherit; } h6 tt, h6 code { font-size: inherit; } h1 { font-size: 28px; color: black; } h2 { font-size: 24px; border-bottom: 1px solid #cccccc; color: black; } h3 { font-size: 18px; } h4 { font-size: 16px; } h5 { font-size: 14px; } h6 { color: #777777; font-size: 14px; } p, blockquote, ul, ol, dl, li, table, pre { margin: 15px 0; } hr { background: transparent url("../../images/modules/pulls/dirty-shade.png") repeat-x 0 0; border: 0 none; color: #cccccc; height: 4px; padding: 0; } body > h2:first-child { margin-top: 0; padding-top: 0; } body > h1:first-child { margin-top: 0; padding-top: 0; } body > h1:first-child + h2 { margin-top: 0; padding-top: 0; } body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child { margin-top: 0; padding-top: 0; } a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 { margin-top: 0; padding-top: 0; } h1 p, h2 p, h3 p, h4 p, h5 p, h6 p { margin-top: 0; } li p.first { display: inline-block; } ul, ol { padding-left: 30px; } ul :first-child, ol :first-child { margin-top: 0; } ul :last-child, ol :last-child { margin-bottom: 0; } dl { padding: 0; } dl dt { font-size: 14px; font-weight: bold; font-style: italic; padding: 0; margin: 15px 0 5px; } dl dt:first-child { padding: 0; } dl dt > :first-child { margin-top: 0; } dl dt > :last-child { margin-bottom: 0; } dl dd { margin: 0 0 15px; padding: 0 15px; } dl dd > :first-child { margin-top: 0; } dl dd > :last-child { margin-bottom: 0; } blockquote { border-left: 4px solid #dddddd; padding: 0 15px; color: #777777; } blockquote > :first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } table { padding: 0; } table tr { border-top: 1px solid #cccccc; background-color: white; margin: 0; padding: 0; } table tr:nth-child(2n) { background-color: #f8f8f8; } table tr th { font-weight: bold; border: 1px solid #cccccc; text-align: left; margin: 0; padding: 6px 13px; } table tr td { border: 1px solid #cccccc; text-align: left; margin: 0; padding: 6px 13px; } table tr th :first-child, table tr td :first-child { margin-top: 0; } table tr th :last-child, table tr td :last-child { margin-bottom: 0; } img { max-width: 100%; } span.frame { display: block; overflow: hidden; } span.frame > span { border: 1px solid #dddddd; display: block; float: left; overflow: hidden; margin: 13px 0 0; padding: 7px; width: auto; } span.frame span img { display: block; float: left; } span.frame span span { clear: both; color: #333333; display: block; padding: 5px 0 0; } span.align-center { display: block; overflow: hidden; clear: both; } span.align-center > span { display: block; overflow: hidden; margin: 13px auto 0; text-align: center; } span.align-center span img { margin: 0 auto; text-align: center; } span.align-right { display: block; overflow: hidden; clear: both; } span.align-right > span { display: block; overflow: hidden; margin: 13px 0 0; text-align: right; } span.align-right span img { margin: 0; text-align: right; } span.float-left { display: block; margin-right: 13px; overflow: hidden; float: left; } span.float-left span { margin: 13px 0 0; } span.float-right { display: block; margin-left: 13px; overflow: hidden; float: right; } span.float-right > span { display: block; overflow: hidden; margin: 13px auto 0; text-align: right; } code, tt { margin: 0 2px; padding: 0 5px; white-space: nowrap; border: 1px solid #eaeaea; background-color: #f8f8f8; border-radius: 3px; } pre code { margin: 0; padding: 0; white-space: pre; border: none; background: transparent; } .highlight pre { background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-radius: 3px; } pre { background-color: #f8f8f8; border: 1px solid #cccccc; font-size: 13px; line-height: 19px; overflow: auto; padding: 6px 10px; border-radius: 3px; } pre code, pre tt { background-color: transparent; border: none; } Mojolicious-Plugin-DirectoryServer-1.003/examples/markdown_viewer0000755000000000000000000000142514434663673024065 0ustar rootroot#!/usr/bin/env perl use Mojolicious::Lite; use Text::Markdown qw/markdown/; use Encode qw/encode_utf8 decode_utf8/; plugin 'DirectoryServer', { auto_index => 0, # disabled directory index dir_index => 'index.md', root => app->home->rel_file('documents'), handler => sub { my ( $c, $path ) = @_; return unless $path =~ /\.(md|mkdn)$/; my $markdown = Mojo::File::slurp($path); my $html = markdown( decode_utf8 $markdown ); $c->render( template => 'markdown', html => $html ); }, }; app->start; __DATA__ @@ markdown.html.ep Markdown Viewer <%== $html %> Mojolicious-Plugin-DirectoryServer-1.003/Makefile.PL0000644000000000000000000000523514434663673021073 0ustar rootrootpackage Mojolicious::Plugin::DirectoryServer; use strict; use warnings; =encoding utf8 =head1 The build file for Mojolicious::Plugin::DirectoryServer This build file is a modulino; it works as both a build script and a module. To build the distribution, run this file normally: % perl Makefile.PL But, it's more interesting than that. You can load it with C and call C to get the data structure it passes to C: my $package = require '/path/to/Makefile.PL'; my $arguments = $package->arguments; Note that C-ing a file makes an entry in C<%INC> for exactly that name. If you try to C another file with the same name, even from a different path, C thinks it has already loaded the file. As such, I recommend you always require the full path to the file. The return value of the C is a package name (in this case, the name of the main module. Use that to call the C method. Even if this distribution needs a higher version of Perl, this bit only needs v5.8. You can play with the data structure with a primitive Perl. =cut use File::Spec::Functions qw(catfile); my $module = __PACKAGE__; ( my $dist = $module ) =~ s/::/-/g; my $github = 'https://github.com/briandfoy/mojolicious-plugin-directoryserver'; my $main_file = catfile( 'lib', split /::/, "$module.pm" ); my %WriteMakefile = ( 'MIN_PERL_VERSION' => '5.032', 'NAME' => $module, 'ABSTRACT_FROM' => $main_file, 'VERSION_FROM' => $main_file, 'LICENSE' => 'artistic_2', 'AUTHOR' => 'brian d foy ', 'CONFIGURE_REQUIRES' => { 'ExtUtils::MakeMaker' => '6.64', 'File::Spec::Functions' => '0', }, 'BUILD_REQUIRES' => { }, 'TEST_REQUIRES' => { 'Test::More' => '1', }, 'PREREQ_PM' => { 'Mojolicious' => 9, }, 'META_MERGE' => { 'meta-spec' => { version => 2 }, resources => { repository => { type => 'git', url => $github, web => $github, }, bugtracker => { web => "$github/issues", }, homepage => $github, }, }, clean => { FILES => "$dist-*" }, ); sub arguments { \%WriteMakefile } do_it() unless caller; sub do_it { require File::Spec; my $MM ='ExtUtils::MakeMaker'; my $MM_version = eval{ "$MM " . $WriteMakefile{'CONFIGURE_REQUIRES'}{'ExtUtils::MakeMaker'} } || "$MM 6.64"; eval "use $MM_version; 1" or die "Could not load $MM_version: $@"; eval "use Test::Manifest 1.21" if -e File::Spec->catfile( qw(t test_manifest) ); my $arguments = arguments(); my $minimum_perl = $arguments->{MIN_PERL_VERSION} || '5.008'; eval "require $minimum_perl;" or die $@; WriteMakefile( %$arguments ); } no warnings; __PACKAGE__;