My previously working HTAccess no longer works - regex

My HTAccess was working before. But I wanted to add an FTP section to the site. It is decided that all FTP will go in /ftp and all requests to /ftp/... will be internally redirected to /ftp.php?dir=... that handles authentication and such before using readfile(...). Being a n00b at regex, I assumed this would work: (only the ftp section was added and the |ftp added)
RewriteEngine On
# http://httpd.apache.org/docs/2.4/rewrite/flags.html
# Match page
RewriteCond %{REQUEST_URI} !^/?(cydia|firmware|scripts|site|ftp)
RewriteCond %{REQUEST_URI} !^/?(robots.txt|ftp.php)
RewriteRule ^/?(.*)$ /site/index.php?title=$1 [PT,L,QSA]
# Match FTP
RewriteCond %{REQUEST_URI} ^/?ftp
RewriteRule ^/?(.*)$ /ftp.php?dir=$1 [PT,L,QSA]
RewriteRule ^/*$ /site/index.php [L,QSA]
Basically, what I did was (I think) match /ftp as a true instead a false like above. However, this gives me a 500 Server Error throughout the site (indicating a problem in the HTAccess). I'm sure this is a simple error, but I'm hoping you can help me with this.

Your issue is that those too line will redirect everything starting with ftp (including ftp.php and this will create an infinite loop)
RewriteCond %{REQUEST_URI} ^/?ftp
RewriteRule ^?(.*)$ /ftp.php?dir=$1 [PT,L,QSA]
Try replacing them with this :
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} ^/?ftp
RewriteRule ^/?(.*)$ /ftp.php?dir=$1 [PT,L,QSA]

Related

Redirect all urls except one in .htaccess

I am trying to redirect all URLs on my site (let's call it www.site1.com) except one in my .htaccess file. I currently have the following in my .htaccess file:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/my/page$ [NC]
RewriteRule (.*) https://www.site2.com [R=302,L]
With the above, all requests to www.site1.com are redirected to www.site2.com, including the one that I do not want to redirect.
After some experimentation, I have found that the following works to redirect only a specific page:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/my/page$ [NC]
RewriteRule (.*) https://www.site2.com [R=302,L]
I'm not sure why the ! operator isn't working as I expect. Perhaps there is an error in my regex?
Some additional bit of information. This is a Drupal site running on a dedicated cPanel host. But I have been sure to put this new redirect rewrite rule before all the other Drupal-specific rewrite rules.
Any help would be greatly appreciated.
RewriteCond %{REQUEST_URI} !/(index.php) [NC]
RewriteRule ^(.*)$ index.php [NC,QSA,L,END]
You need to make sure you exclude the page you redirect to from you list of possible url that get redirected(to avoid the loop) and then you can add more before the RewriteRule.
RewriteCond %{REQUEST_URI} !/(index.php) [NC]
RewriteCond %{REQUEST_URI} !/(index_new.php) [NC]
RewriteRule ^(.*)$ index.php [NC,QSA,L,END]

Apache multiple rewrite conditions for a single rule

SOLVED: The problem was related to Symfony. See my answer below.
I recently changed the domain of my site, and I'd like to permanently redirect visitors to the new domain, excluding a few specific URLs that must remain accessible via the old domain. Here's what I tried. The issue is that redirection occurs, but the specified directories are not excluded.
RewriteCond %{HTTP_HOST} !^newdomain\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/[^/]+/example1/.*$ [NC]
RewriteCond %{REQUEST_URI} !^/[^/]+/example2/.*$ [NC]
RewriteCond %{REQUEST_URI} !^/[^/]+/example3/.*$ [NC]
RewriteCond %{REQUEST_URI} !/examplepage.html [NC]
RewriteRule ^/(.*)$ https://newdomain.com%{REQUEST_URI} [R=301,L]
I also tried placing the following at the top of my configuration file, no luck.
RewriteRule ^(example1|example2|example3)($|/) - [L]
Edit: It's also worth noting that these directives seem to work for examplepage.html, it's just the "directories" that don't work. This is Apache 2.4.7
The following example URLs should all be left out of the rewriting process (so pretty much anything containing "/example1":
https://olddomain.com/example1
https://olddomain.com/example1/action1
https://olddomain.com/app.php/example1/action1
For the sake of completeness, the above directives are in my apache.conf file. In addition, Symfony2 provides a default .htaccess file with the following rewrite directives. Could there be some sort of contradiction here?
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Determine the RewriteBase automatically and set it as environment variable.
# If you are using Apache aliases to do mass virtual hosting or installed the
# project in a subdirectory, the base path will be prepended to allow proper
# resolution of the app.php file and to redirect to the correct URI. It will
# work in environments without path prefix as well, providing a safe, one-size
# fits all solution. But as you do not need it in this case, you can comment
# the following 2 lines to eliminate the overhead.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
# Redirect to URI without front controller to prevent duplicate content
# (with and without `/app.php`). Only do this redirect on the initial
# rewrite by Apache and not on subsequent cycles. Otherwise we would get an
# endless redirect loop (request -> rewrite to front controller ->
# redirect -> request -> ...).
# So in case you get a "too many redirects" error or you always get redirected
# to the start page because your Apache does not expose the REDIRECT_STATUS
# environment variable, you have 2 choices:
# - disable this feature by commenting the following 2 lines or
# - use Apache >= 2.3.9 and replace all L flags by END flags and remove the
# following RewriteCond (best solution)
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^app\.php(/(.*)|$) %{ENV:BASE}/$2 [R=301,L]
# If the requested filename exists, simply serve it.
# We only want to let Apache serve files and not directories.
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule .? - [L]
# Rewrite all other queries to the front controller.
RewriteRule .? %{ENV:BASE}/app.php [L]
Try this instead:
RewriteCond %{HTTP_HOST} !^newdomain\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/example1 [NC]
RewriteCond %{REQUEST_URI} !^/example2 [NC]
RewriteCond %{REQUEST_URI} !^/example3 [NC]
RewriteCond %{REQUEST_URI} !/examplepage.html [NC]
RewriteRule ^/(.*)$ https://newdomain.com/$1 [R=301,L]
I think you are making the folder conditions overly complex. Also note that you can use $1 in the last line to just carry over the value caught in the () in the left side of the line. Makes no difference in this example, but would if you needed only part of the left hand side to be used in the destination URL on the right.
I figured it out. If anyone else runs into a similar issue, the problem is due to Symfony issuing an [INTERNAL REDIRECT] on all URLs to /app.php. /app.php is then passed through the gauntlet of rewrite conditions for a second round. Excluding app.php in your rewrite conditions will solve it.
RewriteCond %{HTTP_HOST} !^newdomain\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/example1/.*$ [NC]
RewriteCond %{REQUEST_URI} !^/example2/.*$ [NC]
RewriteCond %{REQUEST_URI} !^/example3/.*$ [NC]
RewriteCond %{REQUEST_URI} !/app.php [NC]
RewriteCond %{REQUEST_URI} !/examplehtml.html [NC]
RewriteRule ^/(.*)$ https://newdomain.com/$1 [R=301,L]

301 redirect www.root.com/subfolder to www.subfolder.com on same server

Hi people at Stackoverflow,
I've honestly searched here and tried stuff but since I'm really not an expert and nothing worked, I'm lost and need your help. I don't post here often because usually I find what I am looking for.
The situation
I have different sites running on the same server. Let's say that one of my websites is called Cats. It runs with CMSMS and resides in a subfolder of my root called cats.com.
In the root of my server there is a htaccess file with this code (generated by the server admin):
RewriteCond %{HTTP_HOST} ^www.cats.com$
RewriteCond %{REQUEST_URI} !^/cats.com/
RewriteRule (.*) /cats.com/$1
RewriteCond %{HTTP_HOST} ^cats.com$
RewriteCond %{REQUEST_URI} !^/cats.com/
RewriteRule (.*) /cats.com/$1
In the cats.com subfolder there is a htaccess file with rewrite code for pretty urls:
# RewriteBase /cats.com
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [QSA]
This works. When I request www.cats.com I see the contents of the /cats.com subfolder in my root but the URL base stays www.cats.com and all the URLS are extremely pretty.
However, due to a setup error (my bad) in my site's config file, the URL listed in Google is
http://www.root.com/cats.com
When I click the URL, I see the correct page but the address bar reads http://www.root.com/cats.com. The pretty URL rewrite works, but I want this url to rewrite to www.cats.com.
What I have tried
I have tried rewriting the Google listed URL with
attempt one
I tried this in both htaccess files, below and above the existing rewrite rules.
RewriteRule ^/cats.com(.*)$ http://www.cats.com [R=301,L]
RewriteRule ^/cats.com/(.*)$ http://www.cats.com/$1 [R=301,L]
Nothing happens. Everything stays the same.
attempt two
Again tried this in both htaccess files, below and above existing rewrite rules
Redirect 301 /cats.com http://cats.com
This results in an infinite loop in all occasions.
I hope my description is clear enough...
If anybody has any idea what might / should work I'd love to hear it.
Thank you for your help!
Change your rules in cats.com subfolder's htaccess file to this:
RewriteEngine On
RewriteBase /cats.com/
RewriteCond %{THE_REQUEST} /+(cats\.com)/(\S+) [NC]
RewriteRule ^ http://%1/%2 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [QSA,L]

regex mod_rewrite ?-mark sign causing bug

I'm trying to redirect old-style links from an old website to new style links in php.
I'm using:
RewriteEngine on
RewriteBase /
RewriteRule s\.cfm?id=5$ http://mysite.com/article5.php [B,L,R=301]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
However, if I use just s.cfm? everything works fine and redirects to article5.php. But if I try to redirect the id=5 part, I get page not found.
I tried just s.cfm?id and it causes the htaccess bug. So anything you put after question mark ?... causes a problem, I don't know why.
You can't match against the query string inside a RewriteRule, only the URI path is sent through the rule itself. If you need to match against the query string, then use the %{QUERY_STRING} var inside a RewriteCond:
RewriteCond %{QUERY_STRING} ^id=5$
RewriteRule ^/?s\.cfm$ http://mysite.com/article5.php [L,R=301]
Everything else is fine.

drupal multisite htaccess: rewrite all languages to default language on one subsite

I have a Drupal 6 multisite, with 2 domains (www.example.com and www.domain.com), sharing some common content.
The domain example.com is in three languages (EN, FR, NL). Languages are set by path prefix (/en, /fr, /nl). The other domain domain.com is just in one language (NL).
The problem: on many occasions domain.com is shown in the wrong language, even if no path prefix is filled in. Somehow it seems to default to EN, though it doesn't always do that - behaviour doesn't seem to be very consistent.
The solution (at least I hope): since I'm not a Drupal developer (I inhereted the site from a former colleague) I have no idea how to fix this in Drupal, so I thought the best way to fix it would be to add some rewrite rules to .htaccess.
I'm no htaccess/regex expert either, and can't get it working. You can find my current rewrite rules below, any help or suggestions are most welcome.
Some examples:
www.domain.com/fr/some-title needs to be rewritten to www.domain.com/nl/some-title
www.domain.com/node/1975 needs to be rewritten to www.domain.com/nl/node/1975
These are the rewrite rules that were already there:
# Rewrite URLs of the form 'x' to the form 'index.php?q=x'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
I tried adding this:
RewriteCond %{HTTP_HOST} ^(www.)?domain.com$ [NC]
RewriteRule ^/(.*)$ /nl/$1
and would expect this just to prepend /nl/ to all paths (thus not being a full solution since /fr/some-title would become /nl/fr/some-title) - however, a quick test shows me that:
/fr/some-title is rewritten to /nl/some-title (which is what I need, but not what I expected)
/some-title is not rewritten
The question: any ideas what might be wrong? Or could this be caused by other (Drupal) settings? Or is there a better way to solve my problem?
Just for the sake of completeness: the live website is www.cinemazuid.be
If this rule
RewriteRule ^/(.*)$ /nl/$1
is in your .htaccess file, I am surprised that it works as the leading / is always stripped out, so it should theoretically never match any request.
If your desire is to force a default language of NL for those requests that do not specify a language, then add the following rules to the top of your .htaccess file, before any existing rules
#if request is for existing file or directory
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
#then stop processing
RewriteRule .* - [L]
#replace fr with nl. This rule
RewriteRule ^fr/(.*)$ /nl/$1 [L,R=301]
#if the request does not have a language of en or nl
RewriteCond %{REQUEST_URI} !^/(en|nl)/ [NC]
#redirect with nl as default language
RewriteRule .+ /nl%{REQUEST_URI} [L,R=301]
If you do not want to redirect, just drop the R=301
I edited code above to replace /fr/some-title with /nl/some-title/.
The L flag tells mod_rewrite to stop processing further rules, which is usually what you want, unless you have another rule that needs to further process the current request.
#redirect /fr/* and /en/* to /*
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com$ [NC]
RewriteRule ^(en|fr)/(.*)$ /$2 [R,L]
#internally rewrite /* to /nl/*
RewriteCond %{HTTP_HOST} ^(www\.)?domain\.com$ [NC]
RewriteCond $1 !^nl/$ [NC]
RewriteRule ^(.*)$ /nl/$1
#drupal code
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]