5

I've never encountered something such as this before. I was attempting to simply redirect the page to the HTTPS version if it determined that HTTPS was off, but instead it's displaying an HTML page rather than actually redirecting; and even odder, it's displaying it as text/plain!

The VirtualHost Declaration (Sort of):

ServerAdmin admin@example.com
DocumentRoot "/path/to/files"
ServerName example.com
SSLEngine On
SSLCertificateFile /etc/ssh/certify/example.com.crt
SSLCertificateKeyFile /etc/ssh/certify/example.com.key
SSLCertificateChainFile /etc/ssh/certify/sub.class1.server.ca.pem
<Directory "/path/to/files/">
    AllowOverride All
    Options +FollowSymLinks
    DirectoryIndex index.php
    Order allow,deny
    Allow from all
</Directory>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule .* https://example.com:6161 [R=301]

The Page Output:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://example.com:6161">here</a>.</p>
<hr>
<address>Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/1.0.0e DAV/2 Server at example.com Port 443</address>
</body></html>

I've tried moving the Rewrite stuff up above the SSL stuff hoping it'd do something and nothing happens. If I view the page with via HTTPS, it displays fine like it should. It's obviously detecting that I'm trying to rewrite the path, but it's not acting.

The Apache error log does not indicate anything to me that might have gone wrong.

When I remove the RewriteRules:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
Reason: You're speaking plain HTTP to an SSL-enabled server port.<br />
Instead use the HTTPS scheme to access this URL, please.<br />
<blockquote>Hint: <a href="https://example.com/"><b>https://example.com/</b></a></blockquote></p>
<p>Additionally, a 404 Not Found
error was encountered while trying to use an ErrorDocument to handle the request.</p>
<hr>
<address>Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/1.0.0e DAV/2 Server at example.com Port 443</address>
</body></html>

I get the standard "you can't do this because you're not using SSL" response, which is also provided in text/plain rather than being rendered as HTML. This would make sense, it should only work for HTTPS-enabled connections, but I still want to redirect them to the HTTPS connection when it determines that it is not enabled.

Thinking I could circumvent the system:

I tried adding a ErrorDocument 400 https://example.com:6161 to the config file instead of using RewriteRules, and that just gave me a new message, still no cheese.

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="https://example.com:6161">here</a>.</p>
<hr>
<address>Apache/2.2.21 (Unix) mod_ssl/2.2.21 OpenSSL/1.0.0e DAV/2 Server at example.com Port 443</address>
</body></html>

How can I force Apache to actually redirect rather than displaying a "301" page that shows HTML in plain-text format?

animuson
  • 279
  • 1
  • 6
  • 20
  • How are you obtaining the HTML response? – Jon Lin Dec 16 '11 at 23:57
  • @Jon: When I load the page, that's what is displayed. Plain text. I'm not viewing the source. – animuson Dec 16 '11 at 23:58
  • What happens if you remove all the rewrite rules? Does the http version show the same as the https version? Try `RewriteRule .* https://example.com:6161$0 [R=301]` (probably won't work, but it's my best guess) –  Dec 17 '11 at 16:57
  • @Gerben: See the edit. If you connect via HTTPS, everything works fine. It's just the HTTP version that I want to redirect to the HTTPS version which doesn't work. – animuson Dec 27 '11 at 05:13
  • Does `http://example.com/` work at all in your case? If not, create a vhost just for `example.com` on http and place your rewrites in there. In the vhost for https your condition of https=off will always be false, i.e., https will always be on, and the conditional rewrites will never fire. HTH. – KM. Mar 06 '12 at 21:33
  • @KM: That output is what I get when visiting the the regular `http://` site. I can't create separate virtual hosts for the non-secure one because it's a custom port. Basically, `http://example.com:6161` and `https://example.com:6161` point to the same thing, but I want it to catch if it's non-secure and redirect, because you can't view anything unless your request was via SSL. – animuson Mar 06 '12 at 21:36
  • What browser are you using? I'm getting similar behavior in Opera sometimes (due to my settings) while I don't get it in other browsers that I use more rarely. Does the server return the status 301 as expected or does it end up returning 200 and that page? – 0xC0000022L Mar 06 '12 at 22:47
  • @STATUS: I'm using Firefox, which just displays the plain text (200 OK response code). I tried in Chrome which just ignored the content-type and redirected anyways, which is cool, but I don't normally use Chrome and I can't expect others to use it either. – animuson Mar 06 '12 at 22:49
  • Well, there we have it. If the browser doesn't get 301 it won't normally redirect. Your rewrite rule isn't honored or not the last to trigger. For one you might want to add an `L` (i.e. `[L,R=301]`) to be sure it is the last one and then skim over the config if there is something else pertaining to that particular URL. Also good would be to set the `mod_rewrite` engine to debug logging and see what you get from there. I'm doing something similar but with the default port and that works. However, your config looks like the global one, while I have vhosts defined. – 0xC0000022L Mar 06 '12 at 22:54
  • What `Content-type` is the server sending? It should be `text/html`. If it's `text/plain` instead, something could be wrong with your error-files. – Alexander Janssen Jan 25 '14 at 13:53

1 Answers1

1

First: With Apache you cannot have HTTPS and HTTP running on the same port.

See: Apache answer both HTTP and HTTPS on the same port

For handling both SSL and non-SSL traffic you have to define two virtual hosts.

See: Redirect http to https apache on different port

For the redirect from non-SSL virtual host to SSL virtual host we use this:

<VirtualHost *:80>
        RewriteEngine on
        RewriteCond  %{HTTPS} !=on
        RewriteCond  %{HTTP_HOST} ^(.*)$
        RewriteRule  ^(.*)/? https://%1$1 [L,R]
</VirtualHost>

Remains the problem that explicitly sending a non-SSL request to the SSL-enabled port ( http://mydomain.com:443/ ) gives the:

You're speaking plain HTTP to an SSL-enabled server port

page as plain text (in a Firefox browser). Explicitly sending a SSL request to the non-SSL port ( https://mydomain.com:80/ ) gives a:

ssl_error_rx_record_too_long error

(in the Firefox browser).

Why is this occurring?

Peter
  • 11
  • 1