I need a mod_rewrite to redirect all http requests to https, but I want do exclude some URLs
# force https
RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} ^secure\. [NC]
RewriteCond %{REQUEST_URI} !gateway_callback [NC]
RewriteRule ^. https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,QSA]
All URLs which match gateway_callback must be excluded
This URL should not be redirected, but it does!?
http://secure.localhost/da/gateway_callback/29/
Have tried to flush DNS cache in the browser, but the URL is still redirected to https
The main problem with your config is that the REQUEST_URI variable contains everything after and including the forward slash. The third RewriteCond statement needs to be updated to something like the following:
RewriteCond %{REQUEST_URI} !^/da/gateway_callback/.*$ [NC]
This should match the example you have provided. If the URI does not always start with /da/ then you might need to put in a wildcard:
RewriteCond %{REQUEST_URI} !^/[^/]+/gateway_callback/.*$ [NC]
where the [^/]+ matches one or more characters which is not a forward slash.
I would recommend always using the regex anchors wherever possible as it removes ambiguity. The original RewriteCond attempting to match REQUEST_URI does not use them, which can confuse admins at a casual glance.
Also note that all related examples for the RewriteCond and RewriteRule directives in the official documentation use the start anchor.
Could the trailing slash be keeping you from matching? I'm never clear on whether the trailing slash is preserved or not. I suggest changing your 3rd condition to
RewriteCond %{REQUEST_URI} !/gateway_callback/\d+/?$ [NC]
Related
i am still new to htaccess. I have a static website, that has a content inside several directories. I use this to redirect 301 all html pages to its https non-www version.
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule (.*) https://example.com/$1 [L,R=301]
I want the website to be dynamic. So after it redirects to https non-www version, i want it to grab the resources from a specific php files. But, i don't know how to do that, while also do the first 301 redirect.
I try to grab the resources by using something like:
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule (.*) https://example.com/$1
RewriteRule (.*)/(.*)/(.*)\.html$ https://note.mathpro.id/$2.php?name=$3 [L,R=302]
This URL http://example.com/category/uncategorized.html retrieves the content from https://example.com/category.php?name=uncategorized, but doesn't redirect it to https://example.com/category/uncategorized.html as it intially did.
Can anyone help?
... i don't know how to do that, while also do the first 301 redirect.
These are two entirely separate tasks that requires two different rules. You should not modify the first (canonical redirect) rule. (For some reason, you have removed the flags argument, ie. [L,R=301] - The L flag is required for the redirect to function as intended.)
RewriteRule (.*)/(.*)/(.*)\.html$ https://note.mathpro.id/$2.php?name=$3 [L,R=302]
This should not be an external redirect, it should be an internal rewrite. In order words, you want the (visible) URL to remain as /category/uncategorized.html. You don't want the end user to see /category.php?name=uncategorized.
For some reason you also have three capturing subpatterns in the RewriteRule pattern (.*)/(.*)/(.*)\.html$, whereas your example URL /category/uncategorized.html only has two?
Your regex should also be more restrictive. The "problem" with the very generic .* is that it is "greedy" and consumes everything, including slashes. So this regex will also match /foo/bar/baz/zip/bah/yop.html. (But which parts will it match/capture exactly?)
Try the following instead:
# 1. Canonical redirect (UNCHANGED)
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule (.*) https://example.com/$1 [L,R=301]
# 2. Rewrite to handler
RewriteRule ^([^/]+)/([^/]+)\.html$ $1.php?name=$2 [L]
This assumes the .htaccess file is located in the document root.
However, a minor problem with the above rewrite is that it rewrites the URL regardless of whether the "handler" (eg. category.php) exists or not. This isn't necessarily a big deal, but it means the 404 is triggered on category.php (the rewritten file-path), not /category/uncategorized.html (the originally requested URL from the user).
To resolve this, you can check whether the target file exists first. For example:
# 2. Rewrite to handler if it exists
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^/]+)/([^/]+)\.html$ $1.php?name=$2 [L]
So we're trying to redirect an old subdomain to our new domain, and keep the rest of the URL intact. We're trying to move it all to a subdirectory.
This is easy with the following...
RewriteCond %{HTTP_HOST} ^test\.example\.com/$ [NC]
RewriteRule ^(.*)$ https://example.com/test-path/$1 [R=302,L]
However, some of the previous sites URLs were actually test.example.com/test-path/ already, so we'd like to have these ones not double up on the /test-path/
That rule is turning URLs like this...
test.example.com/test-path/some-page
into
test.example.com/test-path/test-path/some-page
So now we're trying the following...
RewriteCond %{REQUEST_URI} !/test-path/
RewriteCond %{HTTP_HOST} ^test\.example\.com/$ [NC]
RewriteRule ^(.*)$ https://example.com/test-path/$1 [R=302,L]
And while this will redirect to example.com/test-path/, it is now losing whatever came after the normal URL.
test.example.com/test-path/other-path
is being redirected to
example.com/test-path/
Hopefully that makes sense on what we're trying to do. Redirect a subdomain to a new domain into a subdirectory, and not double the request-url directory.
Edit:
With that most recent attempt, it also doesn't seem to care if the url contains /test-path/ at all. It still redirects anyway.
RewriteCond %{HTTP_HOST} ^test\.example\.com/$ [NC]
RewriteRule ^(.*)$ https://example.com/test-path/$1 [R=302,L]
I assume this is just a typo in your question(?), but you have an erroneous slash at the end of your hostname - this will never match.
To avoid duplicating the /test-path when it is present on the requested URL, but still redirect to /test-path, you can capture this as an optional URL-path that is then thrown away if it has matched. For example:
RewriteCond %{HTTP_HOST} ^test\.example\.com [NC]
RewriteRule ^(?:test-path/)?(.*) https://example.com/test-path/$1 [R=302,L]
I've removed the slash and the trailing $ on the CondPattern so that it will match (and consequently canonicalise) FQDN, that end in a dot.
(?:test-path/)? is a non-capturing group (so no backreference is created) that captures test-path/. This group is then made optional with the trailing ?.
Aside:
RewriteCond %{REQUEST_URI} !/test-path/
RewriteCond %{HTTP_HOST} ^test\.example\.com/$ [NC]
RewriteRule ^(.*)$ https://example.com/test-path/$1 [R=302,L]
This won't do anything if /test-path/ is present anywhere in the requested URL. So, if you are seeing a redirect then it would seem "something else" is doing that!
With that most recent attempt, it also doesn't seem to care if the url contains /test-path/ at all. It still redirects anyway.
As I say, something else must be doing that. A possible conflict with other directives perhaps? Are you mixing redirects from both mod_alias and mod_rewrite?
Note that these redirects should go at the top of the .htaccess file.
I have a redirect rule that redirects a url of pattern /abcd/* to http://myweb.com/abcd/*.
I want to apply this redirect except /abcd/index.html.
I have tried this.
RewriteCond %{THE_REQUEST} !^/abcd/index
RewriteCond %{REQUEST_URI} !^/abcd/index [NC]
RewriteRule ^/abcd/(.+)$ http://myweb.com/abcd/$1 [NC,R=301,L]
I am not sure if it is correct.
Please suggest me the correct way of doing this.
Try this rule without leading slash in RewriteRule:
RewriteCond %{REQUEST_URI} !^/abcd/index [NC]
RewriteRule ^abcd/(.+)$ http://myweb.com/abcd/$1 [NC,R=301,L]
Difference is ^abcd/(.+)$ instead of ^/abcd/(.+)$
Your 2 conditions were redundant so I reduced it to one.
.htaccess is per directory directive and Apache strips the current directory path (thus leading slash) from RewriteRule URI pattern.
Is it possible to have a generic / multi-domain httpd.conf line that will redirect any non-www request to its www equivalent?
By generic, I mean something that does not rely on hardcoded domain name, ie.
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^yourdomain.com [NC]
RewriteRule ^(.*)$ http://www.yourdomain.com/$1 [L,R=301]
I really don't want to edit httpd.conf every time I have another website added/removed from my server, esp. that websites are added/removed dynamically!
The mod_rewrite documentation has all the information you need, but there is a lot to read. There are two parts to what you want: first, you need to match any domain not starting with www.; then, you need to prefix www. to the current URL.
For the first part, there's this (which applies to both RewriteCond and RewriteRule):
You can prefix the pattern string with a '!' character (exclamation mark) to specify a non-matching pattern.
So "hostname doesn't begin www." could be tested like this:
RewriteCond %{HTTP_HOST} !^www\. [NC]
For the second part, there's this:
In addition to plain text, the Substition string can include [...] server-variables as in rule condition test-strings (%{VARNAME})
So the actual redirect can be made generic like this:
RewriteRule ^(.*)$ http://www.%{HTTP_HOST}/$1 [L,R=301]
Incidentally, it's also possible to do the opposite (redirect everything to not have the www.) because RewriteRule substitutions can also use this:
back-references (%N) to the last matched RewriteCond pattern
So you could capture everything in the hostname after the www. and use that as the target of the rule:
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]
I am having problems getring a simple redirect statement to take effect on my Godaddy account. I have the following statements in my .htaccess file:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.mydomain.net$ [NC]
RewriteRule ^(.*)$ http://mydomain.net/$1 [R=301,L]
RewriteCond %{HTTP_HOST} ^mydomain.net$ [NC]
RewriteRule ^/lists/$ / [R=301]
RewriteCond %{HTTP_HOST} ^mydomain.net$ [NC]
RewriteRule ^/blog/$ http://myotherdomain.net/ [R=301]
The 1st redirect ALWAYS work. The 2nd and 3rd ones however, NEVER work. I just get a 404 from the server. The Apache logs do not reveal any useful infomation - just a 404.
Any ideas, anybody?
Your help will be greatly appreciated.
Thanks
Per-directory Rewrites
When using the rewrite engine in .htaccess files the per-directory prefix (which always is the same for a specific directory) is automatically removed for the pattern matching and automatically added after the substitution has been done.
– http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriterule
So just leave the leading slash out of the pattern.
For simple redirects like that, better use the simple RedirectMatch directives:
RedirectMatch 301 ^/lists/$ http://mydomain.net/
RedirectMatch 301 ^/blog/$ http://myotherdomain.net/
If you insist on using rewriting make sure you add the L flag to your rules.
Apache mod_rewrite Flags says :
You will almost always want to use [R] in conjunction with [L] (that is, use [R,L]) because on its own, the [R] flag prepends http://thishost[:thisport] to the URI, but then passes this on to the next rule in the ruleset, which can often result in 'Invalid URI in request' warnings.
Simply remove the slashs at the beginning. It also might be useful to make the slashs at the end optional.
RewriteCond %{HTTP_HOST} ^mydomain.net$ [NC]
RewriteRule ^lists/{0,1}$ / [R=301]
RewriteCond %{HTTP_HOST} ^mydomain.net$ [NC]
RewriteRule ^blog/{0,1}$ http://myotherdomain.net/ [R=301]
Put the first one last. Once it encounters a redirect match, it runs it and ignores the rest.