--- /dev/null
+use strict;
+use Module::Build;
+
+my $build = Module::Build->new(
+ create_makefile_pl => 'passthrough',
+ license => 'perl',
+ module_name => 'Catalyst::Plugin::RequireSSL',
+ requires => { 'Catalyst' => '5.23' },
+ create_makefile_pl => 'passthrough',
+ test_files => [
+ glob('t/*.t')
+ ]
+);
+$build->create_build_script;
--- /dev/null
+Revision history for Perl extension Catalyst::Plugin::RequireSSL
+
+0.01 2005-06-08 23:45:00
+ - initial release
--- /dev/null
+Build.PL
+Changes
+lib/Catalyst/Plugin/RequireSSL.pm
+Makefile.PL
+MANIFEST This list of files
+META.yml
+README
+t/01use.t
+t/02pod.t
+t/03podcoverage.t
--- /dev/null
+--- #YAML:1.0
+name: Catalyst-Plugin-RequireSSL
+version: 0.01
+author:
+ - Andy Grundman, C<andy@hybridized.org>
+abstract: Force SSL mode on select pages
+license: perl
+generated_by: Module::Build version 0.2604, without YAML.pm
--- /dev/null
+# Note: this file was auto-generated by Module::Build::Compat version 0.03
+
+ unless (eval "use Module::Build::Compat 0.02; 1" ) {
+ print "This module requires Module::Build to install itself.\n";
+
+ require ExtUtils::MakeMaker;
+ my $yn = ExtUtils::MakeMaker::prompt
+ (' Install Module::Build now from CPAN?', 'y');
+
+ unless ($yn =~ /^y/i) {
+ die " *** Cannot install without Module::Build. Exiting ...\n";
+ }
+
+ require Cwd;
+ require File::Spec;
+ require CPAN;
+
+ # Save this 'cause CPAN will chdir all over the place.
+ my $cwd = Cwd::cwd();
+ my $makefile = File::Spec->rel2abs($0);
+
+ CPAN::Shell->install('Module::Build::Compat')
+ or die " *** Cannot install without Module::Build. Exiting ...\n";
+
+ chdir $cwd or die "Cannot chdir() back to $cwd: $!";
+ }
+ eval "use Module::Build::Compat 0.02; 1" or die $@;
+ use lib '_build/lib';
+ Module::Build::Compat->run_build_pl(args => \@ARGV);
+ require Module::Build;
+ Module::Build::Compat->write_makefile(build_class => 'Module::Build');
--- /dev/null
+NAME
+ Catalyst::Plugin::PageCache - Cache the output of entire pages
+
+SYNOPSIS
+ use Catalyst 'PageCache';
+
+ MyApp->config->{page_cache} = {
+ expires => 300,
+ set_http_headers => 1,
+ auto_cache => [
+ '/view/.*',
+ '/list',
+ ],
+ debug => 1,
+ };
+
+ $c->cache_page( '3600' );
+
+ $c->clear_cached_page( '/list' );
+
+DESCRIPTION
+ Many dynamic websites perform heavy processing on most pages, yet this
+ information may rarely change from request to request. Using the
+ PageCache plugin, you can cache the full output of different pages so
+ they are served to your visitors as fast as possible. This method of
+ caching is very useful for withstanding a Slashdotting, for example.
+
+ This plugin requires that you also load a Cache plugin. Please see the
+ Known Issues when choosing a cache backend.
+
+WARNINGS
+ PageCache should be placed at the end of your plugin list.
+
+ You should only use the page cache on pages which have NO user-specific
+ or customized content. Also, be careful if caching a page which may
+ forward to another controller. For example, if you cache a page behind a
+ login screen, the logged-in version may be cached and served to
+ unauthenticated users.
+
+ Note that pages that result from POST requests will never be cached.
+
+PERFORMANCE
+ On my Athlon XP 1800+ Linux server, a cached page is served in 0.008
+ seconds when using the HTTP::Daemon server and any of the Cache plugins.
+
+CONFIGURATION
+ Configuration is optional. You may define the following configuration
+ values:
+
+ expires => $seconds
+
+ This will set the default expiration time for all page caches. If you do
+ not specify this, expiration defaults to 300 seconds (5 minutes).
+
+ set_http_headers => 1
+
+ Enabling this value will cause Catalyst to set the correct HTTP headers
+ to allow browsers and proxy servers to cache your page. This will
+ further reduce the load on your server. The headers are set in such a
+ way that the browser/proxy cache will expire at the same time as your
+ cache. The Last-Modified header will be preserved if you have already
+ specified it.
+
+ auto_cache => [
+ $uri,
+ ]
+
+ To automatically cache certain pages, or all pages, you can specify
+ auto-cache URIs as an array reference. Any controller within your
+ application that matches one of the auto_cache URIs will be cached using
+ the default expiration time. URIs may be specified as absolute: '/list'
+ or as a regex: '/view/.*'
+
+ debug => 1
+
+ This will print additional debugging information to the Catalyst log.
+ You will need to have -Debug enabled to see these messages.
+
+ METHODS
+ cache_page
+ Call cache_page in any controller method you wish to be cached.
+
+ $c->cache_page( $expire );
+
+ The page will be cached for $expire seconds. Every user who visits
+ the URI(s) referenced by that controller will receive the page
+ directly from cache. Your controller will not be processed again
+ until the cache expires. You can set this value to as low as 60
+ seconds if you have heavy traffic to greatly improve site
+ performance.
+
+ clear_cached_page
+ To clear the cached value for a URI, you may call clear_cached_page.
+
+ $c->clear_cached_page( '/view/userlist' );
+ $c->clear_cached_page( '/view/.*' );
+
+ This method takes an absolute path or regular expression. For
+ obvious reasons, this must be called from a different controller
+ than the cached controller. You may for example wish to build an
+ admin page that lets you clear page caches.
+
+ dispatch (extended)
+ Bypass the dispatch phase and send cached content if available
+
+ finalize (extended)
+ Cache the page output if requested.
+
+ setup
+ Setup default values.
+
+ _page_cache_key
+ Returns a cache key for the current page.
+
+KNOWN ISSUES
+ It is not currently possible to cache pages served from the Static
+ plugin. If you're concerned enough about performance to use this plugin,
+ you should be serving static files directly from your web server anyway.
+
+ Cache::FastMmap does not have the ability to specify different
+ expiration times for cached data. Therefore, if your
+ MyApp->config->{cache}->{expires} value is set to anything other than 0,
+ you may experience problems with the clear_cached_page method, because
+ the cache index may be removed. For best results, you may wish to use
+ Cache::FileCache or Cache::Memcached as your cache backend.
+
+SEE ALSO
+ Catalyst, Catalyst::Plugin::Cache::FastMmap,
+ Catalyst::Plugin::Cache::FileCache, Catalyst::Plugin::Cache::Memcached
+
+AUTHOR
+ Andy Grundman, "andy@hybridized.org"
+
+COPYRIGHT
+ This program is free software, you can redistribute it and/or modify it
+ under the same terms as Perl itself.
+
--- /dev/null
+package Catalyst::Plugin::RequireSSL;
+
+use strict;
+use base qw/Class::Accessor::Fast/;
+use NEXT;
+
+our $VERSION = '0.01';
+
+__PACKAGE__->mk_accessors( '_require_ssl' );
+
+=head1 NAME
+
+Catalyst::Plugin::RequireSSL - Force SSL mode on select pages
+
+=head1 SYNOPSIS
+
+ use Catalyst 'RequireSSL';
+
+ MyApp->config->{require_ssl} = {
+ https => 'secure.mydomain.com',
+ http => 'www.mydomain.com',
+ remain_in_ssl => 0,
+ };
+
+ $c->require_ssl;
+
+=head1 DESCRIPTION
+
+Use this plugin if you wish to selectively force SSL mode on some of your web pages,
+for example a user login form or shopping cart.
+
+Simply place $c->require_ssl calls in any controller method you wish to be secured.
+
+This plugin will automatically disable itself if you are running under the standalone
+HTTP::Daemon Catalyst server. A warning message will be printed to the log file whenever
+an SSL redirect would have occurred.
+
+=head1 WARNINGS
+
+If you utilize different servers or hostnames for non-SSL and SSL requests, and you rely
+on a session cookie to determine redirection (i.e for a login page), your cookie must
+be visible to both servers. For more information, see the documentation for the Session plugin
+you are using.
+
+=head1 CONFIGURATION
+
+Configuration is optional. You may define the following configuration values:
+
+ https => $ssl_host
+
+If your SSL domain name is different from your non-SSL domain, set this value.
+
+ http => $non_ssl_host
+
+If you have set the https value above, you must also set the hostname of your non-SSL
+server.
+
+ remain_in_ssl
+
+If you'd like your users to remain in SSL mode after visiting an SSL-required page, you can
+set this option to 1. By default, users will be redirected back to non-SSL mode as soon as
+possible.
+
+=head2 METHODS
+
+=over 4
+
+=item require_ssl
+
+Call require_ssl in any controller method you wish to be secured.
+
+ $c->require_ssl;
+
+The browser will be redirected to the same path on your SSL server. POST requests
+are never redirected.
+
+=cut
+
+sub require_ssl {
+ my $c = shift;
+
+ $c->_require_ssl( 1 );
+
+ unless ( $c->req->secure || $c->req->method eq "POST" ) {
+ if ( $c->config->{require_ssl}->{disabled} ) {
+ $c->log->warn( "RequireSSL: Would have redirected to " . $c->_redirect_uri( 'https' ) );
+ } else {
+ $c->res->redirect( $c->_redirect_uri( 'https' ) );
+ }
+ }
+}
+
+=item finalize (extended)
+
+Redirect back to non-SSL mode if necessary.
+
+=cut
+
+sub finalize {
+ my $c = shift;
+
+ # redirect unless:
+ # we're not in SSL mode,
+ # it's a POST request,
+ # we're already required to be in SSL for this request,
+ # or the user doesn't want us to redirect
+ unless ( !$c->req->secure
+ || $c->req->method eq "POST"
+ || $c->_require_ssl
+ || $c->config->{require_ssl}->{remain_in_ssl} ) {
+ $c->res->redirect( $c->_redirect_uri( 'http' ) );
+ }
+
+ return $c->NEXT::finalize(@_);
+}
+
+=item setup
+
+Setup default values.
+
+=cut
+
+sub setup {
+ my $c = shift;
+
+ $c->NEXT::setup(@_);
+
+ # disable the plugin when running under certain engines which don't support SSL
+ # XXX: I didn't include Catalyst::Engine::Server here as it may be used as a backend
+ # in a proxy setup.
+ if ( $c->engine eq "Catalyst::Engine::HTTP" ) {
+ $c->config->{require_ssl}->{disabled} = 1;
+ $c->log->warn( "RequireSSL: Disabling SSL redirection while running under " . $c->engine );
+ }
+}
+
+=item _redirect_uri
+
+Generate the redirection URI.
+
+=cut
+
+sub _redirect_uri {
+ my ( $c, $type ) = @_;
+
+ # XXX: Cat needs a $c->req->host method...
+ # until then, strip off the leading protocol from base
+ unless ( $c->config->{require_ssl}->{$type} ) {
+ my $host = $c->req->base;
+ $host =~ s/^http(s?):\/\///;
+ $c->config->{require_ssl}->{$type} = $host;
+ }
+
+ $c->config->{require_ssl}->{$type} .= '/'
+ unless ( $c->config->{require_ssl}->{$type} =~ /\/$/ );
+
+ my $redir = $type . '://' . $c->config->{require_ssl}->{$type} . $c->req->path;
+ if ( scalar keys %{ $c->req->params } ) {
+ my @params = ();
+ foreach my $k ( sort keys %{ $c->req->params } ) {
+ push @params, $k . "=" . $c->req->params->{$k};
+ }
+ $redir .= "?" . join "&", @params;
+ }
+
+ return $redir;
+}
+
+=back
+
+=head1 KNOWN ISSUES
+
+When viewing an SSL-required page that uses static files served from the Static plugin, the static
+files are redirected to the non-SSL path. It may be possible to work around this by checking the
+referer protocol, but currently there is no way to determine if a file being served is static content.
+
+For best results, always serve static files directly from your web server without using the Static
+plugin.
+
+=head1 SEE ALSO
+
+L<Catalyst>
+
+=head1 AUTHOR
+
+Andy Grundman, C<andy@hybridized.org>
+
+=head1 COPYRIGHT
+
+This program is free software, you can redistribute it and/or modify it under
+the same terms as Perl itself.
+
+=cut
+
+1;
--- /dev/null
+use Test::More tests => 1;
+
+use_ok('Catalyst::Plugin::RequireSSL');
--- /dev/null
+use Test::More;
+
+eval "use Test::Pod 1.14";
+plan skip_all => 'Test::Pod 1.14 required' if $@;
+plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD};
+
+all_pod_files_ok();
--- /dev/null
+use Test::More;
+
+eval "use Test::Pod::Coverage 1.04";
+plan skip_all => 'Test::Pod::Coverage 1.04 required' if $@;
+plan skip_all => 'set TEST_POD to enable this test' unless $ENV{TEST_POD};
+
+all_pod_coverage_ok();