nginx redirect ignoring slash - regex

I have some URLs that looks like this:
http://www.mywebsite.com/stuff/web-design-development
http://www.mywebsite.com/web-design/
http://www.mywebsite.com/web-design/secondary-page
Basically, I need anything from /web-design, with or without slash, and including anything after a slash (like the third URL) redirected to /. But the problem I'm having is that my redirect affects the first URL, because it has "web-design" in it.
Here's what I have:
if ($request_filename ~ web-design/.+) {
rewrite ^(.*) http://www.mywebsite.com permanent;
}
Any idea how I can correct this?

A simple location block will match all these
location /web-design {
return 301 $scheme://www.mywebsite.com;
end
This will match any thing that starts with /web-design and redirect it.
Here's why return and not rewrite and here's the location directive documentation.
Also keep in mind that 301 responses are cachable, if you are experiencing weird behaviour consider clearing your cache because maybe your browser cached an old 301 when the configuration wasn't correct yet.

I was able to solve this by simplifing my rewrites.
Instead of using if statements, I just did:
rewrite ^/web-design/?$ http://www.mywebsite.com/ permanent;

Related

RedirectMatch: redirects to wrong URL

I switched a Shop-CMS and put a lot of old URL into the .htaccess to redirect old products to their new location.
But some redirects are wrong:
RedirectMatch 301 ^/products/catxy/313? https://www.example.com/products/catxy/product-1/
RedirectMatch 301 ^/products/catxy/314? https://www.example.com/products/catxy/product-2/
RedirectMatch 301 ^/products/catxy/319? https://www.example.com/products/catxy/product-3/
When I go to example.com/products/catxy/319 I get redirected to product-1 and not to product-3
As I understand the regex above it means starting with /products/catxy/319[MAYBEMORE] -> redirect to product-3
I can't write ^/products/catxy/319$ because there are a lot of different endings for 319 (all variations of that product id).
I don't know either if it would be better to use mod_rewrite in my situation.
Problem is presence of ? in the end of pattern: ^/products/catxy/313?, which is making last digit optional so your first rule matches anything that starts with:
/products/catxy/313
or
products/catxy/31
You probably means to keep trailing slash optional and have your rules like this:
RedirectMatch 301 ^/products/catxy/313(?:/.*)?$ https://www.example.com/products/catxy/product-1/
RedirectMatch 301 ^/products/catxy/314(?:/.*)?$ https://www.example.com/products/catxy/product-2/
RedirectMatch 301 ^/products/catxy/319(?:/.*)?$ https://www.example.com/products/catxy/product-3/
Remember to clear your browser cache before testing the changes.

htaccess redirect if URI matches and doesn't have anything after it

I'm having a bit of an issue with a 301 redirect to fix some client site requirements.
Here's the scenario:
If I go to website.com/case-studies I would like it to redirect to website.com/case-studies/any/any/any, however, if we have something like website.com/case-studies/technology/any/any it shouldn't redirect.
I have tried Redirect 301 /case-studies /case-studies/any/any/any but this basically put me in a loop of /any * 30 appearing in the address bar.
You will need to a regex based directive and use anchors. So use RedirectMatch instead of Redirect:
RedirectMatch 301 ^/case-studies/?$ /case-studies/any/any/any
Regex ^/case-studies/?$ will match /case-studies or /case-studies/ but it won't match anything beyond that.
Make sure to clear your browser cache when testing this change.

Rewrite URL on .htaccess

I have urls like www.example.com/de/something and I need to redirect to www.example.com everything that starts with /de/.
At the moment I have done this
redirect 301 /de http://example.com
and it redirect all links but just removing /de part and result is www.example.com/something.
How to fix this?
Thanks
redirect directive matchs rest of the uri and appends it to the target, you can use RedirectMatch to redirect a specific uri
redirectMatch 301 ^/de/? http://example.com
If you want /de/ in the target you should have specified so, becasue Redirect will include in the target everything "after" what you have matched.
For a different virtualhost as the destination you want this:
Redirect 301 /de/ http://example.com/de/
or
Redirect 301 /de http://example.com/de
If what you want is redirect inside the same virtualhost /de to /, then use a negative lookahead.
RedirectMatch ^(?!de) http://example.com/
If the context is .htaccess, for virtualhost It would be:
RedirectMatch ^/(?!de) http://example.com/
Note: I use /de/ originally because that's what you describe in your question, and also I match slashes in the target. Both source and target without slashes would be fine too for cases like /desomething or /de/something. In any case, always match slashes or the lack of them.
Note2: Do not use .htaccess to redirect unless you are not the admin of the site. It just complicates things and adds unnecessary overhead since the file/s need to be checked a number of times per hit.

.htaccess regex for redirectin specific url-endings

ATM we are investigating a bug in our webapp which produces duplicated urls for specific content. The duplicated urls get a suffix -X where X is an integer.
The right urls look like this:
http://www.foo.bar/entity/some-special-name
The duplicates look like this:
http://www.foo.bar/entity/some-special-name-1
Till we found the bug, we urgently need a workaround based on mod_rewrite which redirects the duplicate-urls to the originals. Has someone an idea, how I can achieve this kind of redirect? How would a regex look like? The redirect should only fire for urls in the /entity/ subdirectory.
You can use this redirect rule in your site root .htaccess to remove invalid URLs:
RedirectMatch 301 ^/(.+)-\d+/?$ /$1
If you just want to fix /entity/ URLs then use this rule:
RedirectMatch 301 ^(/entity/.+)-\d+/?$ /$1

Rewriting a URL to a query string on Apache and Nginx

I'm trying to set up some path rewrites on two separate servers, one using mod-rewrite on Apache and one using HttpRewriteModule on Nginx. I don't think I'm trying to do anything too complex, but my regex skills are a little lacking and I could really use some help.
Specifically, I'm trying to transform a formatted URL into a query string, so that a link formatted like this:
http://www.server.com/location/
would point to this:
http://www.server.com/subdirectory/index.php?content=location
Anything extra at the end of the formatted URL should be appended to the "content" parameter in the query string, so this:
http://www.server.com/location/x/y/z
should point to this:
http://www.server.com/subdirectory/index.php?content=location/x/y/z
I'm pretty sure this should be possible using both Apache mod-rewrite and Nginx HttpRewriteModule based on the research I've done, but I can't see to get it working. If anyone could give me some pointers on how to put together the expressions for either or both of these setups, I'd greatly appreciate it. Thanks!
In nginx you match "/location" in a rewrite directive, capture the tailing string in the variable $1 and append it to the replacement string.
server {
...
rewrite ^/location(.*)$ /subdirectory/index.php?content=location$1 break;
...
}
In Apache's httpd.conf this looks quite similar:
RewriteEngine On
RewriteRule ^/location(.*)$ /subdirectory/index.php?content=location$1 [L]
Have a look at the examples at the end of this page: https://httpd.apache.org/docs/2.4/mod/mod_rewrite.html
Search string: (.+)/location/(.*)$
replacement string: $1/subdirectory/index.php?content=location/$2
For Apache, in the htaccess file in your document root, add:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/subdirectory/index\.php$
RewriteRule ^(.*)$ /subdirectory/index.php?content=$1 [L]
In nginx, you want to first make sure requests for /subdirectory/index.php get passed through, then rewrite everything else:
location ~ /subdirectory/index\.php$
{
}
location /
{
rewrite ^(.*)$ /subdirectory/index.php?content=$1 break;
}
This would probably be the best way to do it in nginx:
location ^~ /location/ {
rewrite ^/(location/.*)$ /subdirectory/index.php?content=$1 last;
}
For more details, see:
http://nginx.org/r/location
http://nginx.org/r/rewrite