.htaccess redirect; How to copy value? - .htaccess

I've the following in .htaccess:
RedirectMatch 301 /Search/[my_value]/m(.*) /Search?city=[my_value]
[my_value] is always the same in both URLs. How can I also copy [my_value] from the first URL to the other URL?

Just use the placeholder reference as documented in the alias module:
RedirectMatch 301 ^/?Search/([^/]+)/m(.*)$ /Search?city=$1
Or you can instead use a simple rewriting rule as offered by the rewriting module:
RewriteEngine on
RewriteRule ^/?Search/([^/]+)/m(.*)$ /Search?city=$1 [R=301]
Both approaches can be used in the http servers host configuration, or, if really required, in dynamic configuration files (.htaccess style files). You should however definitely prefer the first option.
You really should start to read the documentation of the tools you use. Your question is answered in there:
Alias module: https://httpd.apache.org/docs/current/mod/mod_alias.html#redirectmatch
Rewrite Module: http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriterule

RedirectMatch uses Regular Expressions
This directive is equivalent to Redirect, but makes use of regular expressions, instead of simple prefix matching.
The supplied regular expression is matched against the URL-path, and if it matches, the server will substitute any parenthesized matches into the given string and use it as a filename.
This means, to capture part of the request, you must put it in parenthesis (...), and then use this as $1, $2, etc. in the target URL.
As #arkascha already has shown, to use [my_value], you capture it with (.+?) and add it in the target as city=$1. The second part m(.*)$ could be used as $2. But if you don't need it in the target, you can just remove the parenthesis and say m.*$, e.g.
RedirectMatch ^/Search/(.+?)/m.*$ /Search?city=$1
When everything works as it should, you may change the status code to 301. Never test with 301.

Related

How to redirect double URL to single URL with htaccess

Google Search Console is showing 404 Page Not Found error for
https://example.com/page/https://example.com/page/
and the link is coming from an external website.
I want to redirect with .htaccess:
https://example.com/page/https://example.com/page/
to
https://example.com/page/
Can anyone can help me in this regard?
Try the following mod_rewrite directives at the top of your .htaccess file:
RewriteEngine On
RewriteRule ^(.*?)https?:/ /$1 [R=301,L]
This just removes any trailing part on the URL-path that starts http:/ (or https:/).
UPDATE: The ? in the capturing subpattern (.*?) makes it non-greedy, so it only captures up to the first occurrence of https:/ and discards the rest, rather than up to the last occurrence (greedy) and looping (redirect loop) until all occurrences of https:/ were removed.
Additional notes:
First test with 302 (temporary) redirect to make sure it works. Only change to 301 when confirmed, to avoid caching issues.
The URL-path that is matched by the RewriteRule pattern has already had sequences of slashes reduced to single slashes, so you can't match // (double slash) here (but I don't think you need to).
If there are query strings involved then you may need a slightly different approach and another directive, since the query string itself (as opposed to the URL-path) might contain the "repeated URL" that needs to be removed (we would need to see an example first). The RewriteRule pattern matches against the URL-path only, not the query string.
On Windows: If the (scheme and) colon (:) appears in the first path segment (ie. the malformed link is for the document root) then Apache will generate a 403 Forbidden before .htaccess is able to redirect. There is nothing you can do to avoid this since it is a limitation of the OS (colons are not allowed in filesystem paths - the 403 occurs when Apache tries to map the URL to a filesystem path). This does not happen on Linux. For example: https://example.com/https://example.com/.
UPDATE: If you are not seeing a redirect, just a 404 then you may need to enable additional pathname information (PATH_INFO) on your URLs. For example, at the top of your .htaccess file:
AcceptPathInfo On

How can i 301 redirect a subfolder and everything after it?

I am trying to redirect a subfolder as well as anything after it to the home page.
For example:
example.com/subfolder/extra-stuff > example.com
The extra-stuff is constantly changing and auto generated, so I want the redirect to remove that as well.
I am using:
Redirect 301 /subfolder(.*) http://www.example.com
However, this will result in http://www.example.com/extra-stuff.
Is there a way I can say if /subfolder(and anything else after subfolder) redirect to home?
Thanks for any suggestions!
The Redirect directive uses simple prefix-matching and everything after the match is copied onto the end of the target URL (which is what you are seeing here). However, the Redirect directive also does not support regex syntax, so a "pattern" like (.*) on the end will actually match the literal characters (, ., * and ) - which shouldn't have worked in your example?!
You'll need to use RedirectMatch instead (also part of mod_alias), which does use regex, and is not prefix matching.
For example:
RedirectMatch 301 ^/subfolder http://www.example.com/
Any request that starts /subfolder will be redirected to http://www.example.com/ exactly.
You'll need to clear your browser catch before testing.
You tagged your question "Magento" (which is probably using mod_rewrite). You should note, however, if you are already using mod_rewrite for rewrites/redirects then you should probably be using mod_rewrite instead of mod_alias to do this redirect, since you can potentially get conflicts.
For example, the equivalent mod_rewrite directive would be:
RewriteRule ^subfolder http://www.example.com/ [R=301,L]
Note there is no slash prefix on the RewriteRule pattern. This would need to go near the top of your .htaccess file.

htaccess url rewrite, but duplicate content + variable suffix

I am looking for a simple rewrite or redirect from:
http://www.example.com/media-gallery/1234-abcdef.html
to
http://www.example.com/3d-media/videos/1234-abcdef.html
where "1234-abcdef.html" is dynamic suffix
If you want to redirect any path from media-gallery ending with ".html" you could use regexp.
For example like this:
RewriteRule ^media-gallery/(.*).html?$ 3d-media/$1.html [NC,L]
This should match a url starting with media-gallery/ and ending with .html.
the parentheses grab anything that's matched between them and $1 places the first matched pattern (we only have 1 in this case) in the result.
I haven't tested this, though.
If you want to build more complex rules, you can achieve that with regular expressions as well.
find by myself the solution:
Redirect any link with ???/Media-gallery/??? to ???/3d-media/videos/???
RedirectMatch permanent media-gallery/(.*) http://3dstreaming.org/3d-media/videos/$1

.htaccess rewrite /files/users/1/file.pdf to /view/?file=file.pdf

I am terrible with mod_rewrite however I need to rewrite any request to the folder /files/users/*/ (* is a wildcard) to /view/ and insert the filename into a query paramater like so:
/files/users/9/test.pdf becomes /view/?file=test.pdf
How would I go about this assuming that the .htaccess file will be located inside /files/users/?
I would really appreciate if you explained how your solution works as I am slowly trying to become familiar with mod_rewrite.
So, you wanna have all my trade secrets on a silver plate?
Well, I try my best. ;-)
First of all, you must know where the documentation is. Look here for the reference: mod_rewrite. Or mod_rewrite, if your Apache version is 2.2.
You will find an overview with lots of links at Apache mod_rewrite. There, you will find a nice introduction to rewriting URLs. Also look here for lots of standard examples.
Since mod_rewrite supports PCRE regular expressions, you might need perlre and/or regular-expression.info from time to time.
Now to your question
RewriteEngine On
RewriteRule ^(?:.+?)/(.*) /view/?file=$1
This might already be sufficient. It looks for a subdirectory (?:.+?) in /files/users and captures the name of a file (.*) in this subdirectory. If this pattern matches, it rewrites the URL to /view/?file= and appends the captured file with $1, which gives /view/?file=$1.
All untested, of course, have fun.
P.S. Additional info is here at SO at .htaccess info and .htaccess faq.
Put the directive below in your .htaccess file to rewrite /files/users/9/test.pdf to /view/?file=test.pdf. In practical terms this means that if you visit http://yourdomain.com/files/users/9/test.pdf then the visitor will be served the rewritten url which is http://yourdomain.com/view?file=test.pdf
RewriteRule ^[^/]+/(.*)$ /view/?file=$1 [L]
A RewriteRule directive is part of the Apache mod_rewrite module. It takes two arguments:
Pattern - a regular expression to match against the current URL path (note that the URL path is not the entire URL but eg. /my/path, but in a .htaccess context the leading slash / is stripped giving us my/path).
Substitution - the destination URL or path where the user will rewritten OR redirected to.
Explaining the rule
The pattern ^[^/]+/(.*)$:
^ - the regex must match from the start of the string
[^/] - match everything but forward slash
+ - repetition operator which means: match 1 or more characters
/ - matches a forward slash
(.*) - mathes any characters. The dot means match any character. The star operator means match ANY characters (0 or more). The parantheses means the match is grouped and can be used in backreferences.
$ - the regex must match until the end of the string
The substitution /view/?file=$1:
...means that we rewrite the URL path to the /view/ folder with the query parameter file. The query parameter file will contain our first grouped match from the pattern as we pass it the $1 value (which means the first match from our RewriteRule pattern).
The [L] flag:
...means that mod_rewrite will stop processing rewrite rules. This is handy to avoid unwanted behaviour and/or infinite loops.

.htaccess redirect replacing & sign with the search

RedirectMatch 301 /out/link http://www.link.com/?getparam1=something&getparam2=somethingelse&getparam3=more
When you click on mysite.com/out/link it goes to:
http://www.link.com/?getparam1=something/out/linkgetparam2=somethingelse/out/linkgetparam3=more
Basically its replacing the & sign, for the http 'get' params, with the /out/link part
Possibly try with the B flag
Escape non-alphanumeric characters before applying the transformation.
So you would have
RedirectMatch 301 /out/link http://www.link.com/?getparam1=something&getparam2=somethingelse&getparam3=more [B]
Just in case you absolutely want to avoid escaping all the ampersands &:
If you write a RewriteRule instead of a RedirectMatch directive, the ampersand in the query will not be replaced by the entire match ($0).
So, the two next lines appear same to the user: (note the second line has an unescaped &)
RedirectMatch ^/product-id/(.*) http://www.example.com/?foo=bar\&product_id=$1
RewriteRule ^/product-id/(.*) http://www.example.com/?foo=bar&product_id=$1 [R=301]
If you want the right-side URI visible to the user, use the [R] flag as indicated. If you ommit the flag, the user will be shown the left-hand URI (typically the more elaborate one, so maybe you dont need the flag).
It will act the same way, but it is likely to be less performant (google RedirectMatch vs. RewriteRule) for more on performance. Please keep in mind that all these Regex-Rules are evaluated for every single request on your webserver.

Resources