On Sat, 8 Mar 2003 [EMAIL PROTECTED] wrote:

> Hi -
>
> I'm not much of a mod_perl scripter (yet), but having been
> totally defeated my mod_rewrite, I am trying to use mod_perl
> to push clients into using https when accessing a particular
> server (I am using named-based virtual hosting).
>
> I want to do something like this (the real one will be
> more complicated - but this is a baby test):
>
> -in httpd.conf-
>
> PerlTransHandler +MyApache::ForceSecure
>
> -handler-
>
> package MyApache::ForceSecure;
> use strict;
> use warnings;
> use Apache::RequestRec ();
> use Apache::Const -compile => qw(DECLINED);
>
> sub handler
> {
>   my $r = shift;
>   my $url = $r->url;
>   if ($url =~ m{^http://bcbk}i) {
>     $url =~ s/^http:/https:/i;
>     $r->url ($url);
>   }
>   return Apache::DECLINED;
> }
> 1;
>
> Which is great, but there is *no* $r->url. I know there is a $r->uri, but
> how can I get to the whole ball of wax: from http://...? I can't find
> it in the docs.
>
> Aloha => Beau;

Beau:

I _just_ went through this on my system. You would probably want to use
the following to change the URI as you wish:

    my $uri = APR::URI->parse($r->pool, $r->construct_url);
    $uri->scheme('https');
    my $new_uri = $uri->unparse;

However, the overall strategy is probably not what you want, due to the
way SSL works. When a browser requests a secure connection, the SSL
connection (to the secure port) is established _before_ even the HTTP
connection. Thus it is impossible to change the scheme (http vs https)
once you have arrived at your server. The only way to do this with a Perl
handler is to generate a 302 external redirect.

mod_rewrite can be complicated, sure, but I do think it's the way to
go in this situation. You need:

- two sub-domains in DNS, let's say www.my_domain.com and secure.my_domain.com
- a sub-directory /secure in your webdocs root (or something else able to matched with 
a regex)
- the following in your httpd.conf:

Listen 80
Listen 443
NameVirtualHost 12.34.56.789:80
NameVirtualHost 12.34.56.789:443

<VirtualHost 12.34.56.789:80>

    ServerName   www.my_domain.com
    RewriteEngine   on
    RewriteCond  %{REQUEST_URI}  /secure/
    RewriteRule  ^/(.*)$   https://secure.my_domain.com/$1 [R,L]

</VirtualHost>

<VirtualHost 12.34.56.789:443>

    ServerName   secure.my_domain.com
    RewriteEngine   on
    RewriteCond  %{REQUEST_URI}  !/secure
    RewriteRule  ^/(.*)$   http://www.my_domain.com/$1 [R,L]

</VirtualHost>

This allows you to have relative links on all your pages. All links on
www.my_domain.com will point to http://www. on port 80, and all links on
secure.my_domain.com will point to https://secure. on port 443. The server
will simply rewrite and redirect all links that do not match either
/secure/ or !/secure.

Hope this helps,

- nick

PS If you have more than one domain needing to use https, you can put it
on an arbitrary port so long as you configure the server (not apache) to
listen on it, and then hard-code the port number in the mod_rewrite rule.

-- 

~~~~~~~~~~~~~~~~~~~~
Nick Tonkin   {|8^)>

Reply via email to