[Catalyst] Catalyst Redirect to https

Bill Moseley moseley at hank.org
Fri Mar 26 13:03:38 GMT 2010


On Fri, Mar 26, 2010 at 12:46 AM, Octavian Rasnita <orasnita at gmail.com>wrot=
e:

>  *From:* Bill Moseley <moseley at hank.org>
>
> > > SetEnv HTTPS On
>>
>
>  > Does that header get to Catalyst?  Obviously, check that first.
> >
>
> I didn't know that HTTPS should be an HTTP header and not an environment
> variable so I have also added as a header.
>
> Sorry, I missed that you were setting the environment var -- I assumed you
were setting a header in your load balancer.  Obviously, the front-end web
server's environment is not shared with the back-end's environment.

You have the front-end load balancer add a header to SSL requests when being
proxied to the backend.  Then the backend looks for the this header and, if
set, sets $c->req->secure(1);

You just need some way for the front-end to tell you which requests are SSL
on the front end.  As mentioned, another approach is to use two different
ports on the backend.



>
> And finally, even though I forced $c->req->secure to be true,
> $c->uri_for_action still uses the http scheme and not https so in the ent=
ire
> application the redirects won't be done correctly and this is the big
> problem.
>
>
You need to set $request->secure(1) earlier in the request so that when
$base is created it has the correct scheme.

Here's a simple example application:

$ cat lib/ssl.pm lib/ssl/Controller/Root.pm
package ssl;
use Moose;
use namespace::autoclean -except =3D> 'meta';
extends 'Catalyst';

__PACKAGE__->setup();

after 'prepare_headers' =3D> sub {
    my $self =3D shift;
    $self->req->secure( $ENV{SSL} );
};

1;


package ssl::Controller::Root;
use Moose;
use namespace::autoclean -except =3D> 'meta';
BEGIN { extends 'Catalyst::Controller' }
__PACKAGE__->config->{namespace} =3D '';

sub hello : Local {
    my ( $self, $c ) =3D @_;
    $c->res->body( $c->uri_for( '/hello' ) );
};

1;


~/ssl$ script/ssl_test.pl /hello
http://localhost/hello

~/ssl$ SSL=3D1 script/ssl_test.pl /hello
https://localhost/hello


Don't get confused by that example where I'm checking $ENV.  You will want
to check a request header (or port) as that's how the front-end can
communicate with the back-end.

Note that Catalyst::Apache::Engine will check for $ENV{HTTPS} is "ON" but
for that to happen you would have to do something like  $ENV{HTTPS} =3D
$c->req->headers( 'HTTPS' ) very early in the request (or get Apache to set
it based on the request header.

I find it easier to just explicitly set secure(1) based on a header (or
port).


-- =

Bill Moseley
moseley at hank.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20100326/06a02=
df1/attachment.htm


More information about the Catalyst mailing list