Missed a hard tab
[catagits/Catalyst-Plugin-RequireSSL.git] / lib / Catalyst / Plugin / RequireSSL.pm
CommitLineData
1763fe29 1package Catalyst::Plugin::RequireSSL;
2
3use strict;
4use base qw/Class::Accessor::Fast/;
5use NEXT;
6
ffd9355f 7our $VERSION = '0.07';
1763fe29 8
4585dfb1 9__PACKAGE__->mk_accessors( qw/_require_ssl _ssl_strip_output/ );
eeefd598 10
11sub require_ssl {
12 my $c = shift;
13
14 $c->_require_ssl(1);
15
16 if ( !$c->req->secure && $c->req->method ne "POST" ) {
17 my $redir = $c->_redirect_uri('https');
18 if ( $c->config->{require_ssl}->{disabled} ) {
19 $c->log->warn( "RequireSSL: Would have redirected to $redir" );
20 }
21 else {
4585dfb1 22 $c->_ssl_strip_output(1);
eeefd598 23 $c->res->redirect( $redir );
24 }
25 }
26}
27
28sub finalize {
29 my $c = shift;
30
31 # Do not redirect static files (only works with Static::Simple)
32 if ( $c->isa( "Catalyst::Plugin::Static::Simple" ) ) {
33 return $c->NEXT::finalize(@_) if $c->_static_file;
34 }
35
36 # redirect back to non-SSL mode
37 REDIRECT:
38 {
39 # No redirect if:
40 # we're not in SSL mode
41 last REDIRECT if !$c->req->secure;
42 # it's a POST request
43 last REDIRECT if $c->req->method eq "POST";
44 # we're already required to be in SSL for this request
45 last REDIRECT if $c->_require_ssl;
46 # or the user doesn't want us to redirect
47 last REDIRECT if $c->config->{require_ssl}->{remain_in_ssl};
48
49 $c->res->redirect( $c->_redirect_uri('http') );
50 }
51
4585dfb1 52 # do not allow any output to be displayed on the insecure page
53 if ( $c->_ssl_strip_output ) {
cc4f2717 54 $c->res->body( '' );
4585dfb1 55 }
56
eeefd598 57 return $c->NEXT::finalize(@_);
58}
59
60sub setup {
61 my $c = shift;
62
63 $c->NEXT::setup(@_);
64
65 # disable the plugin when running under certain engines which don't
66 # support SSL
cae2ad7f 67 if ( $c->engine =~ /Catalyst::Engine::HTTP/ ) {
eeefd598 68 $c->config->{require_ssl}->{disabled} = 1;
69 $c->log->warn( "RequireSSL: Disabling SSL redirection while running "
70 . "under " . $c->engine );
71 }
72}
73
74sub _redirect_uri {
75 my ( $c, $type ) = @_;
76
77 # XXX: Cat needs a $c->req->host method...
78 # until then, strip off the leading protocol from base
79 if ( !$c->config->{require_ssl}->{$type} ) {
80 my $host = $c->req->base;
81 $host =~ s/^http(s?):\/\///;
82 $c->config->{require_ssl}->{$type} = $host;
83 }
84
85 if ( $c->config->{require_ssl}->{$type} !~ /\/$/xms ) {
86 $c->config->{require_ssl}->{$type} .= '/';
87 }
88
89 my $redir
90 = $type . '://' . $c->config->{require_ssl}->{$type} . $c->req->path;
4585dfb1 91
eeefd598 92 if ( scalar $c->req->param ) {
4585dfb1 93 my @params;
94 foreach my $arg ( sort keys %{ $c->req->params } ) {
95 if ( ref $c->req->params->{$arg} ) {
96 my $list = $c->req->params->{$arg};
97 push @params, map { "$arg=" . $_ } sort @{$list};
98 }
99 else {
100 push @params, "$arg=" . $c->req->params->{$arg};
101 }
102 }
103 $redir .= '?' . join( '&', @params );
51ef6cb3 104 }
105
b0b7bb46 106 if ( $c->config->{require_ssl}->{no_cache} ) {
ffd9355f 107 delete $c->config->{require_ssl}->{$type};
108 }
109
eeefd598 110 return $redir;
111}
112
1131;
114__END__
1763fe29 115
116=head1 NAME
117
118Catalyst::Plugin::RequireSSL - Force SSL mode on select pages
119
120=head1 SYNOPSIS
121
eeefd598 122 # in MyApp.pm
123 use Catalyst;
124 MyApp->setup( qw/RequireSSL/ );
1763fe29 125
126 MyApp->config->{require_ssl} = {
127 https => 'secure.mydomain.com',
128 http => 'www.mydomain.com',
129 remain_in_ssl => 0,
ffd9355f 130 no_cache => 0,
1763fe29 131 };
132
eeefd598 133 # in any controller methods that should be secured
1763fe29 134 $c->require_ssl;
135
136=head1 DESCRIPTION
137
eeefd598 138Use this plugin if you wish to selectively force SSL mode on some of your web
139pages, for example a user login form or shopping cart.
1763fe29 140
eeefd598 141Simply place $c->require_ssl calls in any controller method you wish to be
142secured.
1763fe29 143
eeefd598 144This plugin will automatically disable itself if you are running under the
145standalone HTTP::Daemon Catalyst server. A warning message will be printed to
146the log file whenever an SSL redirect would have occurred.
1763fe29 147
148=head1 WARNINGS
149
eeefd598 150If you utilize different servers or hostnames for non-SSL and SSL requests,
151and you rely on a session cookie to determine redirection (i.e for a login
152page), your cookie must be visible to both servers. For more information, see
153the documentation for the Session plugin you are using.
1763fe29 154
155=head1 CONFIGURATION
156
157Configuration is optional. You may define the following configuration values:
158
159 https => $ssl_host
160
161If your SSL domain name is different from your non-SSL domain, set this value.
162
163 http => $non_ssl_host
164
eeefd598 165If you have set the https value above, you must also set the hostname of your
166non-SSL server.
1763fe29 167
168 remain_in_ssl
169
eeefd598 170If you'd like your users to remain in SSL mode after visiting an SSL-required
171page, you can set this option to 1. By default, this option is disabled and
172users will be redirected back to non-SSL mode as soon as possible.
1763fe29 173
ffd9355f 174 no_cache
11f9b043 175
176If you have a wildcard certificate you will need to set this option if you are
51ef6cb3 177using multiple domains on one instance of Catalyst.
11f9b043 178
eeefd598 179=head1 METHODS
1763fe29 180
eeefd598 181=head2 require_ssl
1763fe29 182
183Call require_ssl in any controller method you wish to be secured.
184
185 $c->require_ssl;
186
eeefd598 187The browser will be redirected to the same path on your SSL server. POST
188requests are never redirected.
1763fe29 189
ffd9355f 190=head2 setup
191
192Disables this plugin if running under an engine which does not support SSL.
193
194=head2 finalize
195
196Performs the redirect to SSL url if required.
197
1763fe29 198=head1 KNOWN ISSUES
199
eeefd598 200When viewing an SSL-required page that uses static files served from the
201Static plugin, the static files are redirected to the non-SSL path.
1763fe29 202
eeefd598 203In order to get the correct behaviour where static files are not redirected,
204you should use the Static::Simple plugin or always serve static files
205directly from your web server.
1763fe29 206
207=head1 SEE ALSO
208
eeefd598 209L<Catalyst>, L<Catalyst::Plugin::Static::Simple>
1763fe29 210
211=head1 AUTHOR
212
eeefd598 213Andy Grundman, <andy@hybridized.org>
1763fe29 214
11f9b043 215=head1 CONTRIBUTORS
216
217Simon Elliott <simon@browsing.co.uk> (support for wildcards)
218
1763fe29 219=head1 COPYRIGHT
220
221This program is free software, you can redistribute it and/or modify it under
222the same terms as Perl itself.
223
224=cut