-1

I have working code in .htaccess that accomplishes the following.

  1. redirect non-www to www (and https:)
  2. redirect http to https (and www)
  3. allow accessing URLs ending with /file1.htm etc at /file

However, as I discovered, the third rule was more of a hack that needed to be used in combination with removing all existing links to the .htm versions (which is outside your control). As a result, Google started crawling both versions and deciding which ones are canonical.

I want to modify the third rule to not just allowing access at /file, but rewriting the URL with a 301 message. There are several answers on Stackoverflow that have worked for others that are not working for me due to existing rules in the file, so I'm posting it as a new question.

How do I add a 301 redirect to all /file.htm links to /file without breaking the 3 existing rules?

RewriteEngine On
RewriteCond %{http_host} ^example.com [NC]
RewriteRule ^(.*)$ https://www.example.com/$1 [L,R=301]

RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.htm [NC,L]

Redirect 301 /output.php /
Matthew S
  • 843
  • 2
  • 12
  • 26
  • 1
    _“I want to modify the third rule”_ - no, you don’t. Using a 301 there makes no sense, you want to keep that an _internal_ redirect. You want to add a new rule, that rewrites requests for `/file.htm` to `/file` externally, and have that one use a 301 status code. – misorude Sep 09 '19 at 08:28
  • 1
    https://stackoverflow.com/a/38091661/10283047 – misorude Sep 09 '19 at 12:52
  • I tested the code from that answer, and it works as long as you don't add R=301 to the final rule. As soon as you add R=301, the rule breaks. – Matthew S Sep 10 '19 at 13:52
  • _Show_ what you tried, otherwise no one else here can know where you went wrong. – misorude Sep 10 '19 at 13:54
  • 1
    Trying to cram too many different condition checks into one gets messy real quickly. But this case you should be able to handle if you simply do this redirect first, and specify the full absolute HTTPS URL for the target. – misorude Sep 10 '19 at 14:14
  • That seems to break things again, unless I did it wrong. .htaccess: https://pastebin.com/X1KNZwFC Results: https://pastebin.com/VWKxCt8n As you can see, it redirects file.htm to the root of the domain now. – Matthew S Sep 10 '19 at 15:32
  • 1
    When HTTPS is off, you catch everything `(.*)`, but you rewrite it to just `/` in the HTTPS version - so you lose `faq.htm` at that point already, it doesn’t even get to that point any more where the `.htm` suffix could be removed. As I said, you’d need to do the latter first - do the redirect from `.htm` to suffix-less first, and explicitly specify the HTTPS version of the URL as result. – misorude Sep 11 '19 at 06:25
  • I must have misunderstood you and placed the wrong rule first. It seems to be working now. I also need to redirect /output.php to the root of the domain (with https and www). The current rule is `Redirect 301 /output.php https://www.example.com/`. How do I rewrite it to accomplish the redirect in a single hop? – Matthew S Sep 11 '19 at 08:25
  • `RewriteRule ^output\.php$ https://…` – misorude Sep 11 '19 at 08:28
  • That's resulting in a 404. .htaccess and output: https://pastebin.com/cMFdHxKu – Matthew S Sep 11 '19 at 08:44
  • `RewriteRule`, not `Redirect` … Plus you should at least add the `L` flag, so that it doesn’t go through all the rest of the rules in the same round of processing afterwards. – misorude Sep 11 '19 at 08:49
  • `RewriteRule 301 ^output\.php$ https://www.example.com/ [L]` results in a 500 server error for the entire site. `http://example.com/output.php 500 Internal Server Error' – Matthew S Sep 11 '19 at 08:54
  • 1
    The `301` does not belong there. You keep mixing the syntax of two different directives here. – misorude Sep 11 '19 at 08:57
  • Gotcha. Why was Redirect 301 not a good way to do it? That came from an answer here on Stackoverflow from years ago. – Matthew S Sep 11 '19 at 08:58
  • 1
    I don’t know, you asked for an alternative for a “one-hop” redirection - not sure how `Redirect 301 /output.php https://www.example.com/` would not have accomplished that in the first place. `Redirect` however has the “disadvantage” that it works based on checking for path _prefixes_ only, and appending any extra bits to the target again - so this would have caught requests for `/output.phpfoobar` as well, and redirected to `https://www.example.com/foobar` in that case, and that’s likely not what you’d want in the first place. – misorude Sep 11 '19 at 09:08
  • Thank you for your help. If you want to write up an answer, I'll mark this as answered. – Matthew S Sep 11 '19 at 09:15
  • Hm, which parts exactly? (Maybe write a self-answer, then you can focus on the parts that were new to you - might make more sense in this instance perhaps?) – misorude Sep 11 '19 at 09:30
  • Just the part where rule 3 needed to be replaced with new rules 3 and 4. Everything else, like reducing the number of 301 hops, was technically off topic :) – Matthew S Sep 11 '19 at 09:32
  • Ah, okay. Let me know if this is sufficient, or if anything else should be added. – misorude Sep 11 '19 at 09:38

1 Answers1

1

I want to modify the third rule to not just allowing access at /file, but rewriting the URL with a 301 message.

Using a 301 there makes little sense – you want to keep this one an internal redirect.

You should add a new rule, that rewrites requests for /file.htm to /file externally, and have that one use a 301 status code:

#1) externally redirect "/file.htm" to "/file"  
RewriteCond %{THE_REQUEST} /([^.]+)\.htm [NC]
RewriteRule ^ /%1 [NC,L,R=301]
#2) Internally map "/file" back to "/file.htm"
RewriteCond %{REQUEST_FILENAME}.htm -f
RewriteRule ^(.*?)/?$ /$1.htm [NC,L]
misorude
  • 3,381
  • 2
  • 9
  • 16
  • Thanks, you might want to write out both rules in the body of the answer for people who will be copying and pasting it in their .htaccess files. – Matthew S Sep 11 '19 at 09:45
  • Okay, I included the “counterpart” for the internal rewrite as well now. – misorude Sep 11 '19 at 09:47