I have following code in .htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)(/([^/]+))?(/(edit)+)(/([^/]+))?/?$ edit.php?secret=Y7qD7&category=$1&slug=$3&edit=$5&part=$7 [L]
RewriteRule ^([^/]+)(/([^/]+))?/?$ content.php?category=$1&slug=$3 [L]
RewriteRule ^(/)?$ content.php [L]
What I expect to achieve is
http://example.com/test/test1/edit/part to edit.php?category=test&slug=test1&edit=edit&part=part
http://example.com/test/edit/part to edit.php?category=test&slug=&edit=edit&part=part
(above rewrite is working as expected)
`http://example.com/test/test/` to `content.php?category=test&slug=test`
`http://example.com/test/` to `content.php?category=test&slug=`
(Please note that there is no "/edit/" & "/part/" in above 2 urls)
for above two rewrites, first one is working fine but the second one is not working as expected. The last one get rewrite to content.php?category=content.php&slug= which is not correct.
Also trailing slash should not make a difference for the rewrite.
Could somebody please show me what I'm doing wrong here?
I didn't check why the rule in your question doesn't work as expected, but you may try this instead:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/([^/]+)/?([^/]*)?/?([^/]*)?/?([^/]*)?/?
RewriteRule .* edit.php?key1=%1&key2=%2&key3=%3&key4=%4 [L]
Maps silently:
http://example.com/val1/ up to
http://example.com/val1/val2/val3/val4/ with or without trailing slashes
To:
http://example.com/edit.php?key1=val1&key2=val2&key3=val3&key4=val4
The maximum quantity of valN values passed in the incoming URL, is 4. The minimum is 1. That range can be adjusted modifying the rule, though.
When any valN is not present in the incoming URL, the value in the corresponding key-value pair in the query added to the substitution URL, will be empty.
However, the key will always be present in the query as all keys are fixed strings not passed by the incoming URL.
This rule-set is tested and working and it should be tested without any other rule that might get in conflict with it. I didn't check the other rules in the question and can't say if they work or if they could affect this one. That was not part of the question.
UPDATE
Redirecting to edit.php:
Mapping to edit.php is required only when there are 3 or 4 folders in the URL-path.
The modified rule-set is:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !edit\.php [NC]
RewriteCond %{REQUEST_URI} ^/([^/]+)/([^/]+)/([^/]+)/?([^/]*)?/?$ [NC]
RewriteRule .* edit.php?key1=%1&key2=%2&key3=%3&key4=%4 [L,QSA]
Maps silently:
http://example.com/val1/val2/val3/ up to
http://example.com/val1/val2/val3/val4/ with or without trailing slashes
To:
http://example.com/edit.php?key1=val1&key2=val2&key3=val3&key4=val4
The maximum quantity of valN values passed in the incoming URL, is 4. The minimum is 3.
Redirecting to content.php:
Mapping to content.php is very similar to the previous one, except is done only when the number of folders is 1 or 2.
So the rule-set is basically the same with less regex groups:
RewriteCond %{REQUEST_URI} !content\.php [NC]
RewriteCond %{REQUEST_URI} ^/([^/]+)/?([^/]*)?/?$ [NC]
RewriteRule .* content.php?key1=%1&key2=%2 [L,QSA]
Maps silently:
http://example.com/val1/ up to
http://example.com/val1/val2/ with or without trailing slashes
To:
http://example.com/content.php?key1=val1&key2=val2
The maximum quantity of valN values passed in the incoming URL, is 2. The minimum is 1.
The complete rule-set is like this:
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !edit\.php [NC]
RewriteCond %{REQUEST_URI} ^/([^/]+)/([^/]+)/([^/]+)/?([^/]*)?/?$ [NC]
RewriteRule .* edit.php?key1=%1&key2=%2&key3=%3&key4=%4 [L,QSA]
RewriteCond %{REQUEST_URI} !content\.php [NC]
RewriteCond %{REQUEST_URI} ^/([^/]+)/?([^/]*)?/?$ [NC]
RewriteRule .* content.php?key1=%1&key2=%2 [L,QSA]
Hope I understood what you want.
Related
I have been at this all day long, tried dozens of variations but can't quite seem to get this rewrite to work.
RewriteCond %{THE_REQUEST} /pwreset\.php\ [NC]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{THE_REQUEST} \s(.+?)/+[?\s]
RewriteRule ^(.+?)/$ https\:\/\/www\.example\.com\/support\/pwreset\.php [L]
The URL it returns is:
https://www.web-jive.com/support/pwreset.php/?key=cdc3b1aa842785f7345be501a30ddc83
What I need to be removed is the pwrest.php trailing slash before the question mark. Where am I going wrong on this?
The idea is to have the first URL below, redirect to the second:
https://example1.com/pwreset.php?key=cdc3b1aa842785f7345be501a30ddc83
https://example2.com/support/pwreset.php?key=cdc3b1aa842785f7345be501a30ddc83
EDIT
Per Mr. White's suggestion, I'm posting the whole .htaccess file.
RewriteEngine On
# Announcements
RewriteRule ^announcements/([0-9]+)/[a-z0-9_-]+\.html$ ./announcements.php?id=$1 [L,NC]
RewriteRule ^announcements$ ./announcements.php [L,NC]
# Downloads
RewriteRule ^downloads/([0-9]+)/([^/]*)$ ./downloads.php?action=displaycat&catid=$1 [L,NC]
RewriteRule ^downloads$ ./downloads.php [L,NC]
# Knowledgebase
RewriteRule ^knowledgebase/([0-9]+)/[a-z0-9_-]+\.html$ ./knowledgebase.php?action=displayarticle&id=$1 [L,NC]
RewriteRule ^knowledgebase/([0-9]+)/([^/]*)$ ./knowledgebase.php?action=displaycat&catid=$1 [L,NC]
RewriteRule ^knowledgebase$ ./knowledgebase.php [L,NC]
#Password reset
RewriteCond %{QUERY_STRING} ^key=[0-9a-f]{32}$
RewriteRule ^pwreset\.php$ https://www.web-jive.com/support%{REQUEST_URI} [R=302,L]
#Redirect to new support URL
RewriteCond %{HTTP_HOST} ^members\.web\-jive\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.members\.web\-jive\.com$
RewriteRule ^/?$ "https\:\/\/www\.web\-jive\.com\/support" [R=301,L]
RewriteCond %{HTTP_HOST} ^members\.web\-jive\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.members\.web\-jive\.com$
The output you are seeing (with the trailing slash on the URL-path) isn't the result of just the directives you posted, so maybe you have a conflict with other directives or you are seeing a cached response.
However, the rule you posted would seem to be far more complex than it needs to be.
1. https://example1.com/pwreset.php?key=cdc3b1aa842785f7345be501a30ddc83
2. https://example2.com/support/pwreset.php?key=cdc3b1aa842785f7345be501a30ddc83
Assumptions:
You don't need to match the key value; just the URL-path (ie. /pwreset.php)
example1.com and example2.com point to different places (the filesystem does not overlap).
To redirect from 1. to 2. try the following at the top of your .htaccess file in the root of example1.com:
RewriteEngine On
RewriteRule ^pwreset\.php$ https://example2.com/support%{REQUEST_URI} [R=302,L]
Any query string (eg. key=abc...) is passed through unaltered.
Note that this is a 302 (temporary) redirect. Only change it to a 301 (permanent) when you have confirmed it works OK.
If you need to check that a key= URL param is present and is set to a 32 hex string (which appears to be what your example represents) then include a condition before the above RewriteRule that checks against the QUERY_STRING server variable. For example:
RewriteCond %{QUERY_STRING} ^key=[0-9a-f]{32}$
RewriteRule ^pwreset\.php$ https://example2.com/support%{REQUEST_URI} [R=302,L]
If any other URL params are present on the request then the redirect will fail.
Aside:
RewriteRule ^(.+?)/$ https\:\/\/www\.example\.com\/support\/pwreset\.php [L]
This looks very cPanel-esque. There is no need to backslash colons, slashes and dots in the RewriteRule susbtitution argument. This is an "ordinary" string, not a regex. These characters have no special meaning here.
I am simply trying to rewrite automatically this:
From: mysite.com/channel.php?id=BBC&name=British Broadcasting Company &date=today
To: mysite.com/channel-britishbroadcastingcompany-today.html
I've tried with:
RewriteRule ^channel-(.*)-(.*)\.html$ /channel.php?id=1&name=$2&date=$3 [R]
But nothing happens.
Hope this simplest one will help you out. This will redirect if
1. REQUEST_URI is /channel.php
2. QUERY_STRING matches this pattern id=something&name=something&date=something
Redirect this to /channel-%1-%2.html here
1. %1 will hold value of name parameter
2. %2 will hold value of date parameter
RewriteEngine on
Options -MultiViews
RewriteCond %{REQUEST_URI} ^/channel\.php$
RewriteCond %{QUERY_STRING} id=.*?&name=(.*?)&date=(.*)
RewriteRule .* /channel-%1-%2.html? [R=301]
As per the requirement specified by OP to first redirect url on html page on the basis of some query parameters then rewriting the request on previous page. So the complete code of .htaccess will be like this.
RewriteEngine on
Options -MultiViews
RewriteCond %{REQUEST_URI} ^/channel\.php$
RewriteCond %{QUERY_STRING} id=.*?&name=(.*?)&date=(.*)
RewriteRule .* /channel-%1-%2? [R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/channel\-(.*?)\-(.*?)
RewriteRule .* /channel.php? [L]
Explanation of 2nd part which is added.
1. REQUEST_FILENAME if file does not exist as a file and directory.
2. REQUEST_URI If request_uri starts with such pattern channel-somewords-somewords
then rewrite request on /channel.php
If I understand the problem correctly, You currently have a file channel.php and what You want to achieve is get more "friendly" URLs for SEO and general aesthetics in the browser location bar but still have channel.php handle your requests.
If this is really the case then You need a two-way rewrite.
First, You need to take your original URL and redirect it to a new, pretty version.
Second, You need to rewrite this pretty URI internally and still feed it to channel.php behind the scenes.
RewriteEngine On
RewriteBase /
# This part rewrites channel.php?name=X&date=Y into channel-X-Y.html
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{REQUEST_METHOD} =GET
RewriteCond %{QUERY_STRING} (.*\&)?name=([^&]+)\&date=([^&]+)(?:\&(.*))?
RewriteRule ^channel.php$ channel-%2-%3.html?%1%4 [R,L,NE]
# This part rewrites it back into channel.php but keeps the "friendly" URL visible
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^channel-(.*)-(.*).html$ channel.php?name=$1&date=$2 [L,QSA]
Note that the first rule-set limits the rewrite to method GET - otherwise You will lose any submitted POST data.
It also allows for any other query-string parameters to surround name and date (the rest of query-string parameters will pass-through to .html URI and then will be picked back up by channel.php)
Also note the ENV:REDIRECT_STATUS rule - this is crucial, without that part You'll be stuck in redirect loop.
See
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^([a-z0-9-_.]+)/?$ index.php?id=$1 [NC,L]
RewriteRule ^([a-z0-9-_.]+)/([a-z0-9]+)/?$ index.php?id=$1&goto=$2 [NC,L]
What it's going to do is check the index.php and replace to some like, site/dir/index.php to site/dir/namehere than in index.php you can use explode() to separate the values of current url ang get the variables
I am assuming you are asking for rewrite although you are using redirect flag in your current rules, and also assuming BBC to be static in id variable then try with below,
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^channel-([^/]+)-([^/]+).html$ channel.php?id=BBC&name=$1&date=$2 [L]
We distribute different versions of a software product through a single download link. The delivery is based on the referer in conjunction with a default value, which works fine. In addition the user should be redirected to a 404-page, in case the wrong filename was used.
At the moment the .htaccess-file looks like this:
# stop directory listing
Options -Indexes
# turn rewrite engine on
RewriteEngine On
# force 404 if file name is missing or wrong
RewriteCond %{REQUEST_URI} !^(download_mac\.zip|download_pc\.zip)$
RewriteRule (.*) 404/index.html [L]
# an example based on the referer
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-a\.com [OR]
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-b\.com
RewriteRule ^(download_mac\.zip|download_pc\.zip)$ domain_ab/$1 [L]
# last rule if no referer matches
RewriteRule ^(download_mac\.zip|download_pc\.zip)$ default/$1 [L]
So I have one issue and one additional question with this file:
The first rule, to force 404, is very greedy and gets the error page every time, no matter what URL is called. I also tried single statements like RewriteCond %{REQUEST_URI} !^download_mac\.zip$ without any effect. How can I fix this?
How can I get rid of the filenames in any other rule? I tried things like RewriteRule ^(.*)$ default/$1 [L] but it gives me a hard time and an 500 Internal Server Error.
You can avoid repeating your filenames by using an Env variable like this:
RewriteRule ^(download_mac\.zip|download_pc\.zip)$ - [E=ALLOWED:$1,NC]
RewriteCond %{ENV:ALLOWED} ^$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ /404/index.html [L]
RewriteCond %{ENV:ALLOWED} !^$
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-a\.com [OR]
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-b\.com
RewriteRule ^ /domain_ab/%{ENV:ALLOWED} [L]
RewriteCond %{ENV:ALLOWED} !^$
RewriteRule ^ /default/%{ENV:ALLOWED} [L]
You can just move the rewrite rule to the end. The other rules handle the valid cases and if none of them matches the last rule applies
# an example based on the referer
RewriteCond %{HTTP_REFERER} ^http://([^.]+\.)*domain-[ab]\.com
RewriteRule ^download_(mac|pc)\.zip$ domain_ab/$0 [L]
# last rule if no referer matches
RewriteRule ^download_(mac|pc)\.zip$ default/$0 [L]
# force 404 if file name is missing or wrong
RewriteRule ^ 404/index.html [L]
Hello I have been searching the web for an answer to this but I can not find it. I am looking to use htaccess to strip a specific parameter from the url.
For example, I have the following urls:
www.mysite.com/product.php?product_id=123&session=sdfs98d7fs9f8d7
www.mysite.com/anotherurl.php?session=12312341341&someotherparam=123
I would need them to 301 redirect to:
www.mysite.com/product.php?product_id=123
www.mysite.com/anotherurl.php?someotherparam=123
Note the urls above are just examples. Ill need the session param removed from any and all urls no matter how many params are part of the url or where session is located.
I think I need a way to the url string up to session=blah and the url string after session=blah, then combine both parts and redirect to the new url.
Any help is greatly appreciated, thanks.
UPDATED
In short, what you want is just to remove the key-value pair session=xx from the query.
Here is an option:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{QUERY_STRING} (.*)?&?session=[^&]+&?(.*)? [NC]
RewriteCond %{REQUEST_URI} /(.*)
RewriteRule .* %3?%1%2? [R=301,L]
I found a solution on another site
# case: leading and trailing parameters
RewriteCond %{QUERY_STRING} ^(.+)&session=[0-9a-z]+&(.+)$ [NC]
RewriteRule (.*) /$1?%1&%2 [R=301,L]
# case: leading-only, trailing-only or no additional parameters
RewriteCond %{QUERY_STRING} ^(.+)&session=[0-9a-z]+$|^osCsid=[0-9a-z]+&?(.*)$ [NC]
RewriteRule (.*) /$1?%1 [R=301,L]
not tested, but should work:
RewriteCond %{QUERY_STRING} product_id=([0-9]+)
RewriteRule .* product.php?product_id=%1
i have a strange apache mod_rewrite problem. I need to hide a sub-directory from the user, but redirect every request to that sub-directory. I found several quite similar issues on stackoverflow, but nothing really fits, so i decided to post a new question.
My .htaccess looks like this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(.*)?$ foo/$1 [QSA,L]
The document-root only contains the following folder/files:
/foo/bar/index.html
I would now expect that example.com/bar and example.com/bar/ would just show me the contents of index.html.
Instead example.com/bar/ show me the content as expected but example.com/bar redirects me with a 301 to example.com/bar/foo/ an then shows the contents. I really don't get why there is a 301 redirect in this case.
When i put something this
RewriteCond %{REQUEST_URI} !^[^.]*/$
RewriteCond %{REQUEST_URI} !^[^.]*\.html$
RewriteCond %{REQUEST_URI} !^[^.]*\.php$
RewriteRule ^(.*)$ $1/ [QSA,L]
on top of that rule it seems to work, but that would require me to list every used file extension...
Is there any other way i can omit the redirect, the folder "bar" should never be seen by an outside user.
Thanks in advance!
1st rewrite rule is redirect from /foo/(.) to ($1) and second - from (.) to $1.
just idea, this has not been tested.
Better late than never...
Got it working with a simple RewriteRule which append a / to every url that doesn't have on.
# only directories
RewriteCond %{REQUEST_FILENAME} !-f
# exclude there directories
RewriteCond %{REQUEST_URI} !^/excluded-dirs
# exclude these extensions
RewriteCond %{REQUEST_URI} !\.excluded-extension$
# exclude request that already have a /
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*)$ /$1/ [R=301,L]