I have a WordPress Multisite blog which is wholly behind HTTPS.
Now I need to force a single page to HTTP in order to embed an HTTP-only iframe
(HTTP embeds do not work inside HTTPS pages). With force I mean to redirect to HTTP in case the page is being loaded with HTTPS.
The site works fine with HTTPS, but attempting to access the page that should redirect to plain HTTP the server redirects the visitor to the site home.
Here are my current .htaccess
rewrite rules:
RewriteEngine On
# Redirect all to HTTPS if not some-page.
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^example.com # Check host as some subdomains are not used with HTTPS.
RewriteCond %{REQUEST_URI} !^/some-page(/.*)?
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]
# Redirect some-page to HTTP if HTTPS.
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^example.com
RewriteCond %{REQUEST_URI} ^/some-page(/.*)?
RewriteRule (.*) http://%{HTTP_HOST}/$1 [R=301,L]
# WordPress below here
RewriteBase /
RewriteRule ^index.php$ - [L]
# add a trailing slash to /wp-admin
RewriteRule ^wp-admin$ wp-admin/ [R=301,L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(wp-(content|admin|includes).*) $1 [L]
RewriteRule ^(.*.php)$ $1 [L]
RewriteRule . index.php [L]
What I expect those rules to do:
- If not HTTPS, redirect any page except
some-page.*
in example.com to HTTPS version. - If not HTTPS and accessing
some-page.*
don’t redirect. - If HTTPS and accessing
some-page.*
, redirect to HTTP.
What happens:
- All pages go to HTTPS as wanted.
- All requests to
some-page.*
just redirects toindex.php
, meaning all requests toexample.com/some-page
redirect toexample.com/
. This happens with both: HTTP and HTTPS requests. In the end the browser ends up to thehttps://example.com/
page.
Additionally:
- My
.htaccess
doesn’t contain anything else besides some Xdebug triggering options. - I tried moving the HTTPS rules below the WordPress rules: they dont trigger at all.
- I moved only the
some-page.*
-> HTTP redirection under the WordPress rules: no effect, other than HTTPS access tosome-page.*
works (doesn’t redirect to index). - Tried switching the HTTP/S rules around: no effect.
All pointers appreciated.
EDIT:
I tried to validate some WordPress stuff for this. For some reason WordPress might be the one doing the redirect. All attempts to access some-page.*
result in a wp_redirect
with the site home and status 301
to trigger.
I created the following if-else
statement to my WordPress configuration file but it has no effect (I presumed that some HTTP->HTTPS redirection was happening):
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
define( 'WP_SITEURL', 'https://example.com' );
define( 'WP_HOME', 'https://example.com' );
} else {
define( 'WP_SITEURL', 'http://example.com' );
define( 'WP_HOME', 'http://example.com' );
}
I also attempted to change my .htaccess
rules to the following as per some guide I read online:
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^example.com
RewriteCond %{REQUEST_URI} !^/some-page
RewriteRule !^some-page.* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} on
RewriteCond %{HTTP_HOST} ^example.com
RewriteCond %{REQUEST_URI} ^/some-page
RewriteRule ^some-page.* http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
But it didn’t seem to change anything.
EDIT 2:
Somehow it seems the .htaccess
is rewriting some-page.*
directly to index.php
. After I debugged and hooked into WordPress’ redirect_canonical()
, it shows nothing related to some-page.*
. Instead it only shows that it is redirecting https://example.com/index.php
to https://example.com/
. This probably explains the earlier wp_redirect
with 301
.
I tried to check the rewrites with http://htaccess.madewithlove.be/, and it says the rewrites (should) be working as expected.
EDIT 3:
Did some rewrite debugging. It all works fine, but for some reason the one where some-page.*
should be redirected to non-HTTPS, the server value %{HTTPS}
is off
on all rewrite attempts (even when loading the page with HTTPS), essentially making the rule useless. If I remove the HTTPS check, I get a rewrite loop (from HTTPS to HTTP and so on when on some-page.*
URLs.).
Same result with SERVER_PORT
rewrite conditional. All requests seem to come as 80
.
When would be an appropriate time to check for the connection port/HTTPS?