HTTP-Server-Simple-Static-0.09000755001750001750 012203107021 16424 5ustar00stephenstephen000000000000HTTP-Server-Simple-Static-0.09/META.yml000444001750001750 134712203107021 20037 0ustar00stephenstephen000000000000--- abstract: 'Serve static files with HTTP::Server::Simple' author: - 'Stephen Quinney ' build_requires: {} configure_requires: Module::Build: 0.38 dynamic_config: 1 generated_by: 'Module::Build version 0.38, CPAN::Meta::Converter version 2.110440' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: HTTP-Server-Simple-Static provides: HTTP::Server::Simple::Static: file: lib/HTTP/Server/Simple/Static.pm version: 0.09 requires: CGI: 3.46 Exporter: 0 File::LibMagic: 0 File::Spec::Functions: 0 HTTP::Date: 0 HTTP::Server::Simple: 0.01 IO::File: 0 URI::Escape: 0 resources: license: http://dev.perl.org/licenses/ version: 0.09 HTTP-Server-Simple-Static-0.09/MANIFEST000444001750001750 24212203107021 17670 0ustar00stephenstephen000000000000Build.PL Changes example.pl lib/HTTP/Server/Simple/Static.pm Makefile.PL MANIFEST This list of files META.yml t/01basic.t t/02pod.t t/03podcoverage.t META.json HTTP-Server-Simple-Static-0.09/Changes000444001750001750 530012203107021 20052 0ustar00stephenstephen000000000000Revision history for Perl extension HTTP:Server::Simple::Static 0.09 Thu, 15 Aug 2013 09:08:00 +0100 - Added support for clients which send an If-Modified-Since HTTP header in the request. We return a 304 if the file has not been changed. 0.08 Wed, 14 Aug 2013 17:00:00 +0100 - Replaced File::MMagic and MIME::Types with File::LibMagic which should be more reliable. Closes: http://rt.cpan.org/Public/Bug/Display.html?id=39598 - Improved docs and code example. Closes: http://rt.cpan.org/Public/Bug/Display.html?id=37701 - Added support for the Last-Modified and Date HTTP headers, this consequently adds a new dependency on HTTP::Date. - Added support for not sending the content when the request method is HEAD. 0.07 Wed, 19 Mar 2008 18:41:56 +0000 - Only serve files not directories, thanks to Bradley Bailey for the report. Closes http://rt.cpan.org/Public/Bug/Display.html?id=34068 - Fixed url handling for requests from IE/ Closes http://rt.cpan.org/Public/Bug/Display.html?id=27650 0.06 Mon, 23 Jul 2007 10:42:37 +0100 - Fixed problem with handling empty files where they have no file extension or it is not recognised by MIME::Types. Thanks to Mark Stosberg for the report 0.05 Mon, 6 Nov 2006 09:29:42 +0000 - Applied patch from Max Maischein to use the binmode function rather than the binmode method of IO::File, which only exists in newer versions of that module which we were not requiring. 0.04 Thu, 20 Jul 2006 12:03:21 +0100 - Applied patch from Tom Hukins to make HTTP::Server::Simple::Static RFC compliant. Section 4.1 of RFC 2616, "Message Types", states that header fields should be separated by CRLF. This is done in the manner recommended in perlport(1). - Also applied patch from Tom Hukins to add the "use bytes" pragma to ensure Content-Length contains the number of bytes in the response body, not the number of characters. 0.03 Tue, 13 Jun 2006 11:00:58 +0100 - Fixed documentation to show that HTTP::Server::Simple::CGI should be used as the base class. Closes: http://rt.cpan.org/Public/Bug/Display.html?id=18682 - Switched to using IO::File for the file handling, also turned on binmode to help those on Windows serve images, etc. 0.02 Wed Mar 29 12:00:00 2005 - close fh after reading content. (Max Maischein) - fixed content-type header (Kang-min Liu & Max) 0.01 Thu Jan 06 21:40:02 2005 - forked from patch to HTTP::Server::Simple HTTP-Server-Simple-Static-0.09/Build.PL000555001750001750 122012203107021 20053 0ustar00stephenstephen000000000000#!/usr/bin/perl use strict; use warnings; use Module::Build; Module::Build->new ( module_name => 'HTTP::Server::Simple::Static', dist_author => 'Stephen Quinney ', license => 'perl', create_makefile_pl => 'traditional', requires => { 'CGI' => '3.46', 'Exporter' => 0, 'File::LibMagic' => 0, 'File::Spec::Functions' => 0, 'HTTP::Date' => 0, 'HTTP::Server::Simple' => 0.01 , 'IO::File' => 0, 'URI::Escape' => 0, }, )->create_build_script; HTTP-Server-Simple-Static-0.09/META.json000444001750001750 226312203107021 20205 0ustar00stephenstephen000000000000{ "abstract" : "Serve static files with HTTP::Server::Simple", "author" : [ "Stephen Quinney " ], "dynamic_config" : 1, "generated_by" : "Module::Build version 0.38, CPAN::Meta::Converter version 2.110440", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "HTTP-Server-Simple-Static", "prereqs" : { "configure" : { "requires" : { "Module::Build" : "0.38" } }, "runtime" : { "requires" : { "CGI" : "3.46", "Exporter" : 0, "File::LibMagic" : 0, "File::Spec::Functions" : 0, "HTTP::Date" : 0, "HTTP::Server::Simple" : "0.01", "IO::File" : 0, "URI::Escape" : 0 } } }, "provides" : { "HTTP::Server::Simple::Static" : { "file" : "lib/HTTP/Server/Simple/Static.pm", "version" : "0.09" } }, "release_status" : "stable", "resources" : { "license" : [ "http://dev.perl.org/licenses/" ] }, "version" : "0.09" } HTTP-Server-Simple-Static-0.09/example.pl000555001750001750 100712203107021 20552 0ustar00stephenstephen000000000000#!/usr/bin/perl use strict; use warnings; package MyServer; use lib qw(./lib); use base 'HTTP::Server::Simple::CGI'; use HTTP::Server::Simple::Static; my $webroot = '/tmp'; sub handle_request { my ( $self, $cgi ) = @_; if ( !$self->serve_static( $cgi, $webroot ) ) { print "HTTP/1.0 404 Not found\r\n"; print $cgi->header, $cgi->start_html('Not found'), $cgi->h1('Not found'), $cgi->end_html; } } package main; my $server = MyServer->new(); $server->run(); HTTP-Server-Simple-Static-0.09/Makefile.PL000444001750001750 122012203107021 20526 0ustar00stephenstephen000000000000# Note: this file was auto-generated by Module::Build::Compat version 0.3800 use ExtUtils::MakeMaker; WriteMakefile ( 'NAME' => 'HTTP::Server::Simple::Static', 'VERSION_FROM' => 'lib/HTTP/Server/Simple/Static.pm', 'PREREQ_PM' => { 'CGI' => '3.46', 'Exporter' => 0, 'File::LibMagic' => 0, 'File::Spec::Functions' => 0, 'HTTP::Date' => 0, 'HTTP::Server::Simple' => '0.01', 'IO::File' => 0, 'URI::Escape' => 0 }, 'INSTALLDIRS' => 'site', 'EXE_FILES' => [], 'PL_FILES' => {} ) ; HTTP-Server-Simple-Static-0.09/t000755001750001750 012203107021 16667 5ustar00stephenstephen000000000000HTTP-Server-Simple-Static-0.09/t/03podcoverage.t000444001750001750 35212203107021 21632 0ustar00stephenstephen000000000000#!/usr/bin/perl -w use strict; use Test::More; eval "use Test::Pod::Coverage 1.04"; plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@; all_pod_coverage_ok({ also_private => [ qr/^[A-Z_]+$/ ], }); HTTP-Server-Simple-Static-0.09/t/02pod.t000444001750001750 24312203107021 20114 0ustar00stephenstephen000000000000#!/usr/bin/perl -w use strict; use Test::More; eval "use Test::Pod 1.14"; plan skip_all => "Test::Pod 1.14 required for testing POD" if $@; all_pod_files_ok(); HTTP-Server-Simple-Static-0.09/t/01basic.t000444001750001750 16712203107021 20417 0ustar00stephenstephen000000000000use Test::More tests=>2; use_ok ("HTTP::Server::Simple::Static"); ok (HTTP::Server::Simple::Static->isa("Exporter")); HTTP-Server-Simple-Static-0.09/lib000755001750001750 012203107021 17172 5ustar00stephenstephen000000000000HTTP-Server-Simple-Static-0.09/lib/HTTP000755001750001750 012203107021 17751 5ustar00stephenstephen000000000000HTTP-Server-Simple-Static-0.09/lib/HTTP/Server000755001750001750 012203107021 21217 5ustar00stephenstephen000000000000HTTP-Server-Simple-Static-0.09/lib/HTTP/Server/Simple000755001750001750 012203107021 22450 5ustar00stephenstephen000000000000HTTP-Server-Simple-Static-0.09/lib/HTTP/Server/Simple/Static.pm000444001750001750 1204512203107021 24414 0ustar00stephenstephen000000000000package HTTP::Server::Simple::Static; use strict; use warnings; use File::LibMagic (); use File::Spec::Functions qw(canonpath); use HTTP::Date (); use IO::File (); use URI::Escape (); use base qw(Exporter); our @EXPORT = qw(serve_static); our $VERSION = '0.09'; my $line_end = "\015\012"; my $magic = File::LibMagic->new(); sub serve_static { my ( $self, $cgi, $base ) = @_; my $path = $cgi->url( -absolute => 1, -path_info => 1 ); # Internet Explorer provides the full URI in the GET section # of the request header, so remove the protocol, domain name, # and port if they exist. $path =~ s{^https?://([^/:]+)(:\d+)?/}{/}; # Sanitize the path and try it. $path = $base . canonpath( URI::Escape::uri_unescape($path) ); my $fh = IO::File->new(); if ( -f $path && $fh->open($path) ) { my $mtime = ( stat $path )[9]; my $now = time; # RFC-2616 Section 14.25 "If-Modified-Since": my $if_modified_since = $cgi->http('If-Modified-Since'); if ($if_modified_since) { $if_modified_since = HTTP::Date::str2time($if_modified_since); if ( defined $if_modified_since && # parsed ok $if_modified_since <= $now && # not in future $mtime <= $if_modified_since ) { # not changed print 'HTTP/1.1 304 Not Modified' . $line_end; print $line_end; return 1; } } # Read the file contents and get the length in bytes binmode $fh; binmode $self->stdout_handle; my $content; { local $/; $content = <$fh>; } $fh->close; my $content_length; if ( defined $content ) { use bytes; # Content-Length in bytes, not characters $content_length = length $content; } else { $content_length = 0; $content = q{}; } # Find MIME type my $mimetype = $magic->checktype_filename($path); # RFC-2616 Section 14.29 "Last-Modified": # # An origin server MUST NOT send a Last-Modified date which is # later than the server's time of message origination. In such # cases, where the resource's last modification would indicate # some time in the future, the server MUST replace that date # with the message origination date. if ( $mtime > $now ) { $mtime = $now; } my $last_modified = HTTP::Date::time2str($mtime); my $date = HTTP::Date::time2str($now); print 'HTTP/1.1 200 OK' . $line_end; print 'Date: ' . $date . $line_end; print 'Last-Modified: ' . $last_modified . $line_end; print 'Content-type: ' . $mimetype . $line_end; print 'Content-length: ' . $content_length . $line_end; print $line_end; if ( $cgi->request_method() ne 'HEAD' ) { print $content; } return 1; } return 0; } 1; __END__ =head1 NAME HTTP::Server::Simple::Static - Serve static files with HTTP::Server::Simple =head1 VERSION This documentation refers to HTTP::Server::Simple::Static version 0.07 =head1 SYNOPSIS package MyServer; use base qw(HTTP::Server::Simple::CGI); use HTTP::Server::Simple::Static; my $webroot = '/var/www'; sub handle_request { my ( $self, $cgi ) = @_; if ( !$self->serve_static( $cgi, $webroot ) ) { print "HTTP/1.0 404 Not found\r\n"; print $cgi->header, $cgi->start_html('Not found'), $cgi->h1('Not found'), $cgi->end_html; } } package main; my $server = MyServer->new(); $server->run(); =head1 DESCRIPTION this mixin adds a method to serve static files from your HTTP::Server::Simple subclass. =head1 SUBROUTINES/METHODS =over 4 =item serve_static( $cgi, $base ) Takes a reference to the CGI object and a document root path, and tries to serve a static file. Returns 0 if the file does not exist, returns 1 on success. This method sets the C and C HTTP headers when sending a response for a valid file. Further to this, the method supports clients which send an C HTTP header in the request, it will return a 304 C response if the file is unchanged. See RFC-2616 for full details. If the client makes a C request then no message body will be returned in the response. =back =head1 BUGS AND LIMITATIONS Bugs or wishlist requests should be submitted via http://rt.cpan.org/ =head1 DEPENDENCIES The L module is used to detect the MIME-type of a file. The L module is used for URI handling. The L module is used to format the timestamp in the Last-Modified HTTP header. =head1 SEE ALSO L, L =head1 AUTHOR Stephen Quinney C Thanks to Marcus Ramberg C and Simon Cozens for initial implementation. =head1 LICENSE AND COPYRIGHT Copyright 2006 - 2013. Stephen Quinney C You may distribute this code under the same terms as Perl itself. =cut