Another SSL problem - mixed content warning w/CSS

I tracked down the source of the mixed-content warnings to the link to the CSS file. So as a test, I enabled SSL on the page below and linked to a blank CSS file that didn’t have SSL enabled. But I still get the mixed-content warning. Should I simply enable SSL on the CSS file and hard-code the link as “https://mysite.com/main.css”?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Test Page</title>
<link href="../main.css" rel="stylesheet" type="text/css" />
</head>
<body></body>
</html>

Was there an http:// image or other reference in the stylesheet before you blanked it out? Maybe it was still cached when you retried after clearing it. You shouldn’t need to hard code the https:// link if the contents of the CSS file are OK.

I tried it in five different browsers. No warnings in IE8 or Safari, but warnings in Firefox, Chrome, and IE6.

Cars,

Dan is correct. Using a RELATIVE link in an https script makes the relative links https, too. I agree with his assessment that it’s likely that some file is being called from cache (which you can prevent in a PHP - or HTML - script).

Regards,

DK

Neither of the code examples below prevented the problem.

<?php header("Expires: 0"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("cache-control: no-store, no-cache, must-revalidate"); header("Pragma: no-cache");?>
  <META HTTP-EQUIV="Expires" CONTENT="Sat, Aug 26 2000 12:00:00 GMT">
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">
<META HTTP-EQUIV="Cache-Control" CONTENT="no-cache">

Here is the code from the test folder’s HTACCESS file:

RewriteEngine On
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REQUEST_URI} test
RewriteRule ^(.*)$ https://%{HTTP_HOST}/test/$1 [R=301,L]

I tried modifying the page in the test folder to include an image from outside the folder, and deleting the link to the CSS file. Firefox still gives me the insecure warning, and IE6 has the lock icon disappear as soon as the image loads. But Firefox’s Page Info window shows the image as coming from a secure URL.

Cars,

The Last Modified date needs to be set to something in the past, not the current time.

Your RewriteRule is supposed to rewrite test (not secure) to test/test (secure)? It doesn’t do that?

The css file link should be relative which, from an https page, should also be to the https server.

Regards,

DK

DK, I changed the last rule to this

RewriteRule ^(.*)$ https://&#37;{HTTP_HOST}/$1 [R=301,L]

and if I type www.mysite.com/test in the browser, it changes to https://www.mysite.com/ and ignores the subdirectory.

My site’s hosting comany provides separate SSL and non-SSL folders, but the server I use has these symbolically linked so I can serve SSL and non-SSL files from the same folder.

I think I’ve tracked down the reason why the relative links aren’t being served securely. Below is the code from the site’s HTACCESS file in the root folder:

RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^(folder1/file1.php|folder2/file2.php|index.shtml|)$ https://%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{SERVER_PORT} ^443$
RewriteRule !^(folder1/file1.php|folder2/file2.php|index.shtml|)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 

This code seems to force non-SSL on all relative links to images and CSS files. If I comment out this code, the relative links in the test folder’s pages are served securely. The reason I would even consider having separate HTACCESS files in subfolders is because I’ve tried lines like the one below and the folders are simply ignored.

RewriteRule ^(folder3|folder4|folder1/file1.php|folder2/file2.php|index.shtml|)$ https://%{HTTP_HOST}/$1 [R=301,L]

Cars,

Instead of using

RewriteEngine On
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REQUEST_URI} test
RewriteRule ^(.*)$ https://%{HTTP_HOST}/test/$1 [R=301,L]

that should have been

RewriteEngine On
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^test/(.*)$ https://%{HTTP_HOST}/test/$1 [R=301,L]

Why? Because testing for test in the RewriteCond would match with the string ‘text’ ANYWHERE in the URI (and it appeared to me that you wanted to match test in the first directory position). test/ may have a problem with that but you can move the / into the atom if you need to.

ARGH! Why would they create separate folders then link them on the server? Oh, well, not my problem, is it? :lol:

RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^(folder1/file1.php|folder2/file2.php|index.shtml|)$ https://%{HTTP_HOST}/$1 [R=301,L]

RewriteCond %{SERVER_PORT} ^443$
RewriteRule !^(folder1/file1.php|folder2/file2.php|index.shtml|)$ http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 

It looks like “selective” force https otherwise force http protocol. Nice that they’re at least that smart! Unfortunately, this will cause secure server warnings for your support files (css, et al) so you may want to add a RewriteCond (to both) to only do this on your page scripts (php and shtml files), e.g., RewriteCond %{REQUEST_URI} \.(php|shtml|html|yadda-yadda)$.

RewriteRule ^(folder3|folder4|folder1/file1.php|folder2/file2.php|index.shtml|)$ https://%{HTTP_HOST}/$1 [R=301,L]

With the regex you’re using for folder3 and folder4 (and {blank}?), you WILL have problems with a trailing / in the URL (which may also be inserted by Apache depending upon its configuration).

Regards,

DK

This seems to work for both Rewrite Rules. When I add the folder that has the CSS and background images, I don’t receive any insecure warnings.

RewriteRule ^(folder3(.*)|folder4(.*)|folder1/file1.php|folder2/file2.php|index.shtml|)$...[R=301,L]


How do I eliminate that problem, so I can have SSL on just the DirectoryIndex pages in certain folders? Right now, the pages load as non-SSL if the link is simply www.mysite.com/folder1 (with or without the trailing slash).

Which problem? If you want everything that BEGINS WITH the list above, just eliminate the end anchor. If you want EVERYTHING in the folder1 subdirectory, treat it the same as folder3 and folder4, e.g., folder1(.*) will match EVERYTHING in folder1 (as well as anything in the DocumentRoot which begins with folder1, e.g., folder1.txt).

Regards,

DK

If I eliminate the final |, typing in www.mysite.com results in the site’s front page loading as non-SSL.

The main issue right now is that typing www.mysite.com/folder1/index.html loads as SSL but simply www.mysite.com/folder1 or www.mysite.com/folder1/ loads as non-SSL. I have a couple of folders where I want only the index page to load as SSL. I acknowledge that this may not be possible.

Cars,

Anything is possible. You just need to SPECIFY EXACTLY what you want then translate that to mod_rewrite code (using the examples above as a template). If you have problems with the code you create, post your SPECIFICATION, your mod_rewrite CODE and your test URIs.

Regards,

DK

Here is the Rewrite Rule I have in place. (The folder and file names are dummies to protect my client.)

Options -Indexes
RewriteEngine on

# redirect any subdomain of mysite.net (with any port) to www.mysite.com
RewriteCond &#37;{HTTP_HOST} ^([^.:]+\\.)*mysite\\.net\\.?(:[0-9]*)?$ [NC]
RewriteRule ^(.*)$ http://www.mysite.com/$1 [R=301,L]

# force https
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^(folder1/(.*)|images/(.*)|folder2/index.html|index.shtml|)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

RewriteCond %{SERVER_PORT} ^443$
RewriteRule !^(folder1/(.*)|images/(.*)|folder2/index.html|index.shtml|)$  http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 

Again, the problem is that to get SSL on folder2’s index page, I have to use the explicit URL. If I just use www.mysite.com/folder2, it loads as non-SSL.

But this change to the regex seems to get the results I want. Any way to simplify this?

(folder1/(.*)|images/(.*)|folder2/index.html|[COLOR="Red"]folder2/|[/COLOR]index.shtml|)

Cars,

Options -Indexes
RewriteEngine on

# redirect any subdomain of mysite.net (with any port) to www.mysite.com
[COLOR="Red"]# Sorry, {HTTP_HOST} will NOT match the {SERVER_PORT}
# nor is there a dot charccter immediately before the 
# :{SERVER_PORT} in a URL[/COLOR]
RewriteCond &#37;{HTTP_HOST} ^([^.:]+\\.)*mysite\\.net\\.?(:[0-9]*)?$ [NC]
RewriteRule ^(.*)$ http://www.mysite.com/$1 [R=301,L]

# force https
# redirects folder1/.*, images/.*, folder2/index.html, index.shtml and {null}
# to secure server
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^(folder1/(.*)|images/(.*)|folder2/index.html|index.shtml|)$ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 

# redirects NOT {above} to non-secure server
RewriteCond %{SERVER_PORT} ^443$
RewriteRule !^(folder1/(.*)|images/(.*)|folder2/index.html|index.shtml|)$  http://%{HTTP_HOST}%{REQUEST_URI} [R=301,L] 

Again, the problem is that to get SSL on folder2’s index page, I have to use the explicit URL. If I just use www.mysite.com/folder2, it loads as non-SSL.

That’s EXACTLY what your mod_rewrite is telling it to do.

But this change to the regex seems to get the results I want. Any way to simplify this?

(folder1/(.*)|images/(.*)|folder2/index.html|[COLOR="Red"]folder2/|[/COLOR]index.shtml|)

Yes, as before, you really don’t need the end anchor in your regex but that would only allow you to get rid of the pair of :kaioken:EVERYTHING:kaioken: atoms.

Regards,

DK

How should I change that portion of the code? Should I simply substitute {SERVER_PORT} for {HTTP_HOST} and strip the dot character?

What code would you recommend? I tried this

(folder1|images|folder2/index.html|index.shtml|)

but the server appeared to simply ignore the Folder1 and Images parts of the regex.

By “end anchor”, do you mean the final |? That’s the only way I can get SSL reliably on the site’s front page regardless of whether the filename is specified in the URL. And by “atoms”, do you mean the (.*) after Folder1 and Images? Again, without those, nothing in either folder gets served as SSL.

Card,

Regards,

DK


  1. /COLOR ↩︎

I read a regex reference and came up with this solution. Thanks for your help.

^(folder2/(index.html)?|index.shtml|)$