Getting rid of unwanted subdir suffix in URL with .htaccess - regex

I have a URL https://example.com/portfolio/portfolio/page/2/ which I need to redirect to https://example.com/contact/
My attempts are:
RewriteCond %{REQUEST_URI} ^/portfolio/portfolio/page/2/ [NC]
RewriteRule ^/?/page/2/(.*)$ /contact/$1 [R,L]
OR
Redirect 301 /portfolio/portfolio/page/2/ /contact/
Both fail and redirect to https://example.com/contact/page/2/ instead of just https://example.com/contact/
Any help would be appreciated.

Based on the additional information you gave in the comments to the question this is the simple rewriting rule you want:
RewriteEngine on
Rewrite /?portfolio/portfolio/page/2/?$ /contact [END]
In case you want to change the URL visible in the browser, then you need to implement an external redirection:
RewriteEngine on
Rewrite /?portfolio/portfolio/page/2/?$ /contact [R=301]
In case this results in an internal server error (http status 500) then chances are that you operate a very old version of the apache http server. Try using the [L] flag instead of the [END] then. You will see a corresponding entry in your http servers error log file in that case.
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only supported as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

Related

.httacces custom redirectioning

I want to redirect all invalid traffic to my index page.
Invalid traffic in this context means:
-Case 1. Nonexistent directories
-Case 2. Nonexistent files
-Case 3. Existing route but only directory: Like in example "validroute/images" or "validroute/images/"
Actually my working code is
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [R,L,QSA]
Options -Indexes
For cases 1 and 2 the conditions and the RewriteRule are redirecting correctly to my index.php
For the third case Im using the "Options -indexes" which avoids user to browse my directory and displays the forbidden error. I want to redirect this last case also to the index.php instead.
The nearest approach i got based on redirect 403 error using .htaccess was this
ErrorDocument 403 /index.php
Instead of redirecting ALL forbidden (403) when trying to display a valid "folder" (and ONLY in this case) i seek to redirect to index.
By setting the same redirects i expect the user not to be able to see my directories even if he tries to manually input different routes to see if the directory exists or not. Actually he has the hint because some are "forbidden" and others redirects to index.
This is NOT a duplicate of these because given answers didn't fit me or the issues are not what I intend:
.htaccess redirect - Options -Indexes
.htaccess option -indexes redirect?
.htaccess to redirect everything to index.php, but keep a copy of the website in a subdirectory
Maybe is not possible at all or maybe there is another command or maybe a proper regex combined to RewriteRule to fix the selection.
There is a layer above for the server at which i am not able to access or to see in any way, but as i was handling other kind of permissions (folder accesses by password) i noticed that this had its own way of working without allowing developer to modify this.
So i guess there is no way to override such from a higher lvl .htaccess without direct access to server.
I was using Plesk Obsidian.
So if you dont have full control on the server your configurations might generate some conflicts.

Redirect all urls to new domain but some specific urls

Good morning at all. I have a WordPress website and I want to redirect all urls to new domain but:
http://domain.it/?page_id=3668
http://domain.it/?team={name}-{surname}
I wrote this code in the htaccess file
#RewriteCond %{QUERY_STRING} !^team=([a-z-]+)$
#RewriteCond %{QUERY_STRING} !^page_id=3668$
#RewriteRule ^(.*)$ https://newdomain.it/ [L,R=301]
but it does not work correctly. In the Network tab of the Firefox developer tools, I see that there are some resources that are loaded from newdomain.it (for example css and images).
What I'm doing wrong?
This probably is what you are looking for:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^old\.example\.com$
RewriteCond %{QUERY_STRING} ^page_id=3668$ [OR]
RewriteCond %{QUERY_STRING} ^team=\w+-\w+$
RewriteRule ^ - [END]
RewriteRule ^/?(.*)$ https://new.example.com/$1 [R=301]
Is allows the two domains being served by the same http server, but that is not a requirement. If you operate two separate http servers then these rules belong into the one serving the old domain, obviously.
It is a good idea to start out with a 302 temporary redirection and only change that to a 301 permanent redirection later, once you are certain everything is correctly set up. That prevents caching issues while trying things out...
In case you receive an internal server error (http status 500) using the rule above then chances are that you operate a very old version of the apache http server. You will see a definite hint to an unsupported [END] flag in your http servers error log file in that case. You can either try to upgrade or use the older [L] flag, it probably will work the same in this situation, though that depends a bit on your setup.
This implementation will work likewise in the http servers host configuration or inside a dynamic configuration file (".htaccess" file). Obviously the rewriting module needs to be loaded inside the http server and enabled in the http host. In case you use a dynamic configuration file you need to take care that it's interpretation is enabled at all in the host configuration and that it is located in the host's DOCUMENT_ROOT folder.
And a general remark: you should always prefer to place such rules in the http servers host configuration instead of using dynamic configuration files (".htaccess"). Those dynamic configuration files add complexity, are often a cause of unexpected behavior, hard to debug and they really slow down the http server. They are only provided as a last option for situations where you do not have access to the real http servers host configuration (read: really cheap service providers) or for applications insisting on writing their own rules (which is an obvious security nightmare).

Redirect broken 404 pages with .htaccess and regular expressions

I have been unpublishing old pages on my website. To avoid 404 pages, I'd like to redirect these pages to a generic page.
So for example this page:
https://www.portal-gestao.com/artigos/7380-7-t%C3%A1cticas-de-sobreviv%C3%AAncia-%C3%A0-crise-nas-vendas.html
Should redirect to:
https://www.portal-gestao.com/artigos/
I'm not very skilled with .htaccess or regular expressions, I've bee trying to redirect the pages with:
RewriteRule ^artigos/(.*)$ /artigos/$1 [R=301,L]
But something isn't working, can anyone help?
Late information... the site uses a Joomla CMS. See the UPDATE below.
To redirect requests for physical files that no longer exist you need to actually check that the file no longer exists, otherwise it will indeed "redirect everything" (as mentioned in comments).
For example, to redirect any requests of the form /artigos/<something>, that do not map to physical files, to /artigos/ you can do the following:
RewriteEngine On
REwriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(artigos/). /$1 [R=302,L]
The $1 backreference simply prevents you having to repeat the directory name.
The first condition that checks against the REDIRECT_STATUS environment is intended to ensure that only direct requests are redirected. This is probably only required if you are still on Apache 2.2 (as opposed to 2.4) since mod_dir will execute first, rewriting the redirected request to index.php (if it exists) and causing a rewrite loop. On Apache 2.4, mod_dir executes later.
Test with a 302 and only change to a 301 when you are sure it's working OK - to prevent caching issues.
You will need to clear your browser cache before testing.
However, a 404 would generally be a better response. The search engines will likely see the redirect to a common root as a soft-404 and users are more likely to be "confused" when they don't see the information they requested.
RewriteRule ^artigos/(.*)$ /artigos/$1 [R=301,L]
By itself, this would result in a redirect loop, as it simply redirects to itself.
UPDATE: it's not a file, it is an article in a Joomla CMS
If valid URLs do not map to physical files then you can't do this in .htaccess. In your case, a valid URL is determined by the Joomla CMS (as stored in the Joomla database). .htaccess is processed at the very start of the request, before control passes to PHP/Joomla. Directives in .htaccess can only look at the HTTP request and the physical filesystem.
Joomla uses a front-controller pattern. All URLs, that do not map to physical files (to exclude static resources like CSS, JS and images), are internally rewritten to index.php (the "front-controller"), this effectively "routes" the URL and decides what content should be returned.
What you are asking could only be done on a static website where URLs map to physical files on the file system.
You need to perform this redirect in Joomla itself, when Joomla has determined that the requested URL does not exist. (This is actually more efficient anyway as you only need to execute your code after a 404 has been determined, rather than on every single request, as it would be if you used .htaccess.)

I want to redirect example.com/chapter-foo.php to example.com/chapter.php

I have a site with some pages like that:
example.com/dogs-foo1.php
example.com/dogs-foo2.php
example.com/dogs-foo3.php
And then
example.com/cats-foo1.php
example.com/cats-foo2.php
example.com/cats-foo3.php
Now I have simplified the site with tab menus and I only have
example.com/dogs.php
example.com/cats.php
Now I want the people who try to go to: example.com/cats-foo1.php
be redirected to: example.com/cats.php
instead of getting a 404
Is there anyway, maybe with htaccess?
This probably is what you are looking for:
RewriteEngine on
RewriteRule ^/?cats-.+.php$ /cats.php [R=301]
For this to work you will need to enable the rewriting module into your http server. You should place it in the http servers host configuration. If you decide to use a dynamic configuration files instead (.htaccess) you need to enable their interpretation first (see the AllowOverride directive in the official documentation).
I would recommend however to go a step further and use URLs along the pattern https://example.com/cats, so without the trailing .php as is the standard these days. You need some additional internal rewrite rule for that:
RewriteEngine on
# external redirect from /cats-foo.php to /cats
RewriteRule ^/?cats-.+\.php$ /cats [R=301]
RewriteRule ^/?cats\.php$ /cats [R=301]
# internal rewrite
RewriteRule ^/?cat$ /cats.php [END]
This again can be generalized:
RewriteEngine on
# external redirect from /cats-foo.php to /cats
RewriteRule ^/?(\w+])-.+.php$ /$1 [R=301]
# internal rewrite
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(\w+])$ /$1.php [END]
If you experience a http status 500 with that rule in place chances are you operate a very old version of the apache http server. You will find entries in your http servers error log files complaining about the END flag. In that case replace it with the L flag and try again.
You probably will have to adjust those line, we don't know your specific situation. But the above should get you started along with reading the documentation of the tools you use, which you can start here: http://httpd.apache.org/docs/current/mod/mod_rewrite.html
And a general hint: you should always prefer to place such rules inside the http servers (virtual) host configuration instead of using dynamic configuration files (.htaccess style files). Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

Mod Rewrite rule to redirect all pdf request to another location

I'm trying to clean up our website. I'm using ISAPI Rewrite. I have figured out the regex I need to select the files in question.
^(?!.*?web_content.*?).*?\.pdf
I want to redirect all pdf requests to look in web_content/pdf/. So The pseudo rule I want is
redirect all requests to pdfs that aren't already being requested from
web_content/pdf. Drop off the original folder path.
/somefolder/this/mycool.pdf ==> /web_content/pdf/mycool.pdf
My question is how would I actually create the Mod rewrite rule? I don't know how to correctly do the replacement command. I also hope this rule wont affect external pdf links on our site.
This should work:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/web_content/pdf/
RewriteRule ^(.+\.pdf)$ /web_content/pdf/$1 [L]
Helicon ISAPI_Rewrite v3 is pretty much the same as Apache's mod_rewrite (except few advanced things), therefore almost all rules that work on Apache will work here as well.