3

I have WordPress 3.5.1 installed on Ubuntu 12.04 LTS. I'm running Apache 2.2.22. I can't share the domain that I'm working on, and must sanitize any config files and log outputs. While the website is public, any problems I'm working on in connection to the client cannot be made public.

  1. User lands on HTTP site.
  2. User goes to /order/ page and is redirected to the same page delivered over HTTPS.
  3. User clicks away from the order page, and the resultant URL is HTTPS. For example, say they click on the "About Us" link.
  4. The resulting HTTPS page loads all sorts of social media wingdings and libraries over HTTP.
  5. Warnings assail the visitor: "This site is not secure and you will surely die a vicious death! Abort! Abort!"

The solution I'm trying to implement is simple: Redirect all HTTP access to the /order/ page to HTTPS. Redirect all HTTPS access to non /order/ pages to HTTP.

(Side note: I'm not using .htaccess files. I'm declaring the rewrite rules in the <Document> block in each sites config file.)

The website is WordPress based and is using the standard mod_rewrite rules to make pretty URLs. Here is the HTTP vhost's rewrite rules:

# Rewrite Rules. Suddenly dragons!
RewriteEngine On

Redirect /order/ page to HTTPS

RewriteCond %{HTTPS} =off RewriteRule ^order/$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Wordpress Magicks Below

RewriteRule ^index.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L]

And now here's the SSL site's rewrite rules:

# Rewrite Rules. Suddenly encrypted dragons!
RewriteEngine On

Redirect all non /order/ page URLs to HTTP

RewriteCond %{HTTPS} =on RewriteCond %{REQUEST_URI} !^/order/$ RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Wordpress Magicks Below.

RewriteRule ^index.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L]

#The ugly result:

Every access to /orders/ across HTTP or HTTPS is redirected to the home page over HTTP. The RewriteLog for the SSL vhost shows this ugliness:

68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (3) [perdir /var/www/example.com/htdocs/] add path info postfix: /var/www/example.com/htdocs/order -> /var/www/example.com/htdocs/order/
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (3) [perdir /var/www/example.com/htdocs/] strip per-dir prefix: /var/www/example.com/htdocs/order/ -> order/
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (3) [perdir /var/www/example.com/htdocs/] applying pattern '(.*)' to uri 'order/'
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (4) [perdir /var/www/example.com/htdocs/] RewriteCond: input='on' pattern='=on' => matched
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (4) [perdir /var/www/example.com/htdocs/] RewriteCond: input='/order/' pattern='!^/order/$' => not-matched
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (3) [perdir /var/www/example.com/htdocs/] add path info postfix: /var/www/example.com/htdocs/order -> /var/www/example.com/htdocs/order/
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (3) [perdir /var/www/example.com/htdocs/] strip per-dir prefix: /var/www/example.com/htdocs/order/ -> order/
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (3) [perdir /var/www/example.com/htdocs/] applying pattern '^index\.php$' to uri 'order/'
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (3) [perdir /var/www/example.com/htdocs/] add path info postfix: /var/www/example.com/htdocs/order -> /var/www/example.com/htdocs/order/
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (3) [perdir /var/www/example.com/htdocs/] strip per-dir prefix: /var/www/example.com/htdocs/order/ -> order/
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (3) [perdir /var/www/example.com/htdocs/] applying pattern '.' to uri 'order/'
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (4) [perdir /var/www/example.com/htdocs/] RewriteCond: input='/var/www/example.com/htdocs/order' pattern='!-f' => matched
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (4) [perdir /var/www/example.com/htdocs/] RewriteCond: input='/var/www/example.com/htdocs/order' pattern='!-d' => matched
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (2) [perdir /var/www/example.com/htdocs/] rewrite 'order/' -> 'index.php'
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (3) [perdir /var/www/example.com/htdocs/] add per-dir prefix: index.php -> /var/www/example.com/htdocs/index.php
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (2) [perdir /var/www/example.com/htdocs/] strip document_root prefix: /var/www/example.com/htdocs/index.php -> /index.php
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b21380a0/initial] (1) [perdir /var/www/example.com/htdocs/] internal redirect with /index.php [INTERNAL REDIRECT]
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b213a778/initial/redir#1] (3) [perdir /var/www/example.com/htdocs/] strip per-dir prefix: /var/www/example.com/htdocs/index.php -> index.php
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b213a778/initial/redir#1] (3) [perdir /var/www/example.com/htdocs/] applying pattern '(.*)' to uri 'index.php'
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b213a778/initial/redir#1] (4) [perdir /var/www/example.com/htdocs/] RewriteCond: input='on' pattern='=on' => matched
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b213a778/initial/redir#1] (4) [perdir /var/www/example.com/htdocs/] RewriteCond: input='/index.php' pattern='!^/order/$' => matched
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b213a778/initial/redir#1] (2) [perdir /var/www/example.com/htdocs/] rewrite 'index.php' -> 'http://example.com/index.php'
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b213a778/initial/redir#1] (2) [perdir /var/www/example.com/htdocs/] explicitly forcing redirect with http://example.com/index.php
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b213a778/initial/redir#1] (1) [perdir /var/www/example.com/htdocs/] escaping http://example.com/index.php for redirect
68.231.66.6 - - [06/Jun/2013:16:37:42 --0700] [example.com/sid#7f67b220e020][rid#7f67b213a778/initial/redir#1] (1) [perdir /var/www/example.com/htdocs/] redirect to http://example.com/index.php [REDIRECT/301]

I'll truncate the logs to the important bits, and comment on them:

RewriteCond: input='on' pattern='=on' => matched #HTTPS is on, so that pattern matches
RewriteCond: input='/order/' pattern='!^/order/$' => not-matched #It *is* the order page, so the negative match isn't a match
add path info postfix: /var/www/example.com/htdocs/order -> /var/www/example.com/htdocs/order/
strip per-dir prefix: /var/www/example.com/htdocs/order/ -> order/
applying pattern '^index\.php$' to uri 'order/' # Wordpress pretty URLs are applied
add path info postfix: /var/www/example.com/htdocs/order -> /var/www/example.com/htdocs/order/
strip per-dir prefix: /var/www/example.com/htdocs/order/ -> order/
applying pattern '.' to uri 'order/'
RewriteCond: input='/var/www/example.com/htdocs/order' pattern='!-f' => matched
RewriteCond: input='/var/www/example.com/htdocs/order' pattern='!-d' => matched
rewrite 'order/' -> 'index.php' # I... wait... NOOOOO!! And we're sent back to the home page.

The biggest problem here is that I'm not familiar enough with mod_rewrite or regex to know why this is happening exactly and how to remedy it. Can someone beat me with a clue bat?

Stephen Ostermiller
  • 99,822
  • 18
  • 143
  • 364
Wesley
  • 254
  • 1
  • 14

1 Answers1

3

In the SSL config, move the first rule in the WordPress Magicks up above your rule handling redirection.

# Internal redirects, stop doing things!
RewriteRule ^index\.php$ - [L]

Redirect all non /order/ page URLs to HTTP

RewriteCond %{HTTPS} =on RewriteCond %{REQUEST_URI} !^/order/$ RewriteRule (.*) http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L]

What's happening is that when the last rule catches (because you're requesting /order/), an internal redirect to index.php occurs. The internal redirect starts the rewrite process again.. and since the URI (internally) is now /index.php instead of /order/, the 301 rule matches on the second pass.

Putting the RewriteRule ^index\.php$ - [L] at the top of the rule set stops the rewriting process on the internal redirect, and should get /order/ to actually serve some real content over SSL.

Stephen Ostermiller
  • 99,822
  • 18
  • 143
  • 364
Shane Madden
  • 201
  • 1
  • 4