URL rewrite for image path - .htaccess

The current path look like
http://mywebsite.com/upload/image/abc.jpg
How do i use .htaccess to rewrite it to
http://mywebsite.com/shared/abc.jpg
I'm using ZF2. Bellow are current .htaccess
RewriteEngine On
# The following rule tells Apache that if the requested filename
# exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]
# The following rewrites all other queries to index.php. The
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting, the base path will be prepended to
# allow proper resolution of the index.php file; it will work
# in non-aliased environments as well, providing a safe, one-size
# fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]
Can anyone help me? thank you.

You need a new rule for handling images:
RewriteEngine On
# The following rule tells Apache that if the requested filename
# exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^shared/(.+)$ /upload/image/$1 [NC,L,R=302]
# The following rewrites all other queries to index.php. The
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting, the base path will be prepended to
# allow proper resolution of the index.php file; it will work
# in non-aliased environments as well, providing a safe, one-size
# fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]

Related

Removing .php extension except sub directory called enquire

Please assist me to stop this from removing the ".php" extension in sub directories eg: https://www.example.com/enquire/contactmail instead of: https://www.example.com/enquire/contactmail.php
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
\#####exclude /cp folder####
RewriteCond %{REQUEST_URI} !^/enquire
RewriteCond %{REQUEST_FILENAME}\\.php -f
RewriteRule ^(.\*)$ $1.php
RewriteCond %{THE_REQUEST} ^\[A-Z\]{3,9}\\ /((?!cp)\[^.\]+)\\.php
RewriteRule ^/?(.\*)\\.php$ /$1 \[NC,L,QSA,R=301\]
RewriteRule ^enquire/(.\*)$ contactmail.php?s=$1 \[NC,L,QSA\]
RewriteRule ^enquire/(\[0-9\]+)$ contactmail.php?a=$1 \[NC,L,QSA\]
As I understand you have a working solution in place to rewrite incoming requests without ".php" extension to internal resources with that "file name extension".
And now you ask how you can add an exception from that, so that the internal rewrite does not get applied to requests, that target resources inside certain folders in the requested path, physical or virtual folders.
If that is correct then indeed you should implement an exception for those requests. Exceptions should get implemented before more general rules. So further up in the configuration file since that is processed from top to bottom.
That should roughly be what you are looking for:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
# exception for the /enquire request path
RewriteRule ^enquire/(\d+)$ contactmail.php?a=$1 [NC,END,QSA]
RewriteRule ^enquire/(.*)$ contactmail.php?s=$1 [NC,END,QSA]
# redirect requests that specify a ".php" extension
RewriteRule ^(.*)\.php$ $1 [NC,L,QSA,R=301]
# rewrite requests if a corresponding php file exists
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^ %{REQUEST_URI}.php
Just Use the blow .htaccess to remove the .php extension
IndexIgnore * # prevent directory listing
Order deny,allow
Allow from *
# ------------------------------------------
# Rewrite so that php extentions are not shown
RewriteEngine on
#.php URL Rewrite
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php

How to let TYPO3 do the error handling and redirecting for missing files

By default the redirecting for known file storages, like the fileadmin directory is prevented by htaccess:
RewriteRule (?:typo3/|fileadmin/|typo3conf/|typo3temp/|uploads/|favicon\.ico) - [L]
But this also prevents the TYPO3 error handling and redirects module from taking action if a file does not exist.
Our editors have the wish to set up redirects for some deleted files and I wonder if there are any negative effects if I don't exclude fileadmin from the RewriteRule.
Why does this rule even exist by default?
Here is the complete TYPO3 default rewriting, to make the context easier to understand:
<IfModule mod_rewrite.c>
# Enable URL rewriting
RewriteEngine On
# Store the current location in an environment variable CWD to use
# mod_rewrite in .htaccess files without knowing the RewriteBase
RewriteCond $0#%{REQUEST_URI} ([^#]*)#(.*)\1$
RewriteRule ^.*$ - [E=CWD:%2]
# Rules to set ApplicationContext based on hostname
#RewriteCond %{HTTP_HOST} ^dev\.example\.com$
#RewriteRule .? - [E=TYPO3_CONTEXT:Development]
#RewriteCond %{HTTP_HOST} ^staging\.example\.com$
#RewriteRule .? - [E=TYPO3_CONTEXT:Production/Staging]
#RewriteCond %{HTTP_HOST} ^www\.example\.com$
#RewriteRule .? - [E=TYPO3_CONTEXT:Production]
# Rule for versioned static files, configured through:
# - $GLOBALS['TYPO3_CONF_VARS']['BE']['versionNumberInFilename']
# - $GLOBALS['TYPO3_CONF_VARS']['FE']['versionNumberInFilename']
# IMPORTANT: This rule has to be the very first RewriteCond in order to work!
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)\.(\d+)\.(php|js|css|png|jpg|gif|gzip)$ %{ENV:CWD}$1.$3 [L]
# Access block for folders
RewriteRule _(?:recycler|temp)_/ - [F]
RewriteRule fileadmin/templates/.*\.(?:txt|ts)$ - [F]
RewriteRule ^(?:vendor|typo3_src|typo3temp/var) - [F]
RewriteRule (?:typo3conf/ext|typo3/sysext|typo3/ext)/[^/]+/(?:Configuration|Resources/Private|Tests?|Documentation|docs?)/ - [F]
# Block access to all hidden files and directories with the exception of
# the visible content from within the `/.well-known/` hidden directory (RFC 5785).
RewriteCond %{REQUEST_URI} "!(^|/)\.well-known/([^./]+./?)+$" [NC]
RewriteCond %{SCRIPT_FILENAME} -d [OR]
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule (?:^|/)\. - [F]
# Stop rewrite processing, if we are in the typo3/ directory or any other known directory
# NOTE: Add your additional local storages here
RewriteRule ^(?:typo3/|fileadmin/|typo3conf/|typo3temp/|uploads/|favicon\.ico) - [L]
# If the file/symlink/directory does not exist => Redirect to index.php.
# For httpd.conf, you need to prefix each '%{REQUEST_FILENAME}' with '%{DOCUMENT_ROOT}'.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^.*$ %{ENV:CWD}index.php [QSA,L]
</IfModule>
RewriteRule (?:typo3/|fileadmin/|typo3conf/|typo3temp/|uploads/|favicon\.ico) - [L]
But this also prevents the TYPO3 error handling and redirects module from taking action if a file does not exist.
[…]
Why does this rule even exist by default?
Looks like here this rule might not be necessary here; you are right, the not file/not folder checks before the last rule would prevent anything existing in these folders from getting rewritten already.
I guess it is just used as a sort of “performance shortcut” here - doing a basic regex match on the requested URL is cheaper, than having to actually query the file system, “does this exist or not?”
So they apparently make the assumption here, that inside those “special” folders no rewriting will ever be necessary, they are data storage only.
So, yeah, if you want Typo3 handling your 404s for anything in these folders as well, then you should be able to remove/comment out this Rule.

htaccess redirecting to the wrong page when using multiple rewriterules

I have a htaccess file which looks like the following:
Options -Indexes
RewriteEngine On
# no php extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
# only allow rewriting to paths that dont exist
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# example.com/username
RewriteRule ^([\w\d_\-]+)/?$ profile.php?uid=$1 [L,QSA]
# example.com/username/$tab
RewriteRule ^([\w\d_\-]+)\/([\w]+)/?$ profile.php?uid=$1&tab=$2
# example.com/listen/$id
RewriteRule ^listen\/([\w\d_\-]+)?\/?([\w\d_\-]+)?$ track.php?id=$1&secret=$2 [L,QSA]
The way it is supposed to work is to redirect any URL looking like these:
1. example.com/example points to profile.php?id=example
or
2. example.com/example/tab points to profile.php?id=example&tab=tab
3. example.com/listen/example points to track.php?id=example
or
4. example.com/listen/example/code points to track.php?id=example&secret=code
The problem is that sometimes, a link which looks like the third one will point to the profile page. However, what's weirder, is that if example has a dash in it, it will point to the right place. This shouldn't be happening because my regex is matching after listen.
All help is appreciated.
Both of your listen/ rules should appear before other rules and moreover 2 RewriteCond are only being applied to next immediate RewriteRule.
You may use these rules to replace all of your code:
Options -Indexes
RewriteEngine On
# only allow rewriting to paths that don't exist
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# example.com/listen/$id
RewriteRule ^listen/([\w-]+)/?$ track.php?id=$1 [L,QSA,NC]
# example.com/listen/$id/secret
RewriteRule ^listen/([\w-]+)/([\w-]+)/?$ track.php?id=$1&secret=$2 [L,QSA,NC]
# no php extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
# example.com/username
RewriteRule ^([\w-]+)/?$ profile.php?uid=$1 [L,QSA]
# example.com/username/$tab
RewriteRule ^([\w-]+)/([\w-]+)/?$ profile.php?uid=$1&tab=$2 [L,QSA]
Also note that \w means [a-zA-Z0-9_] so no need to add \d_ in character class.

Forcing the rewriting of URLs by hiding .php AND .htm(l) extensions and redirecting to extensionless URLs

here is my configuration:
http://domain.com (obviously fictitious name...) hosted on a server running Apache with mod_rewrite enabled
folder named "foo": (located at http://domain.com/foo/ and in which I want to put my .htaccess file) containing only 3 types of files .php, .htm, .html
.php files (for the sake of the example I will refer to one of them: phpfile.php)
.htm files (for the sake of the example I will refer to one of them: htmfile.htm)
.html files (for the sake of the example I will refer to one of them: htmlfile.html)
within the foo folder, no file has an equivalent with another extension or without extension (ie eg neither phpfile.htm nor phpfile.html nor phpfile exist in foo, only php.file.php does exist)
Here is what I am trying to achieve:
when entering http://domain.com/foo/phpfile.php or http://domain.com/foo/htmfile.htm or http://domain.com/foo/htmlfile.html in my browser's address bar and hitting "Enter":
I get redirected with a 301 to http://domain.com/foo/phpfile or http://domain.com/foo/htmfile or http://domain.com/foo/htmlfile (depending on the file I've chosen), that is to say that those latters are the URLs now displayed in the address bar
when entering http://domain.com/foo/phpfile or http://domain.com/foo/htmfile or http://domain.com/foo/htmlfile in my browser's address bar and hitting "Enter":
I don't get redirected, nothing changes in the address bar but instead the server just serves me the phpfile.php or the htmfile.htm or the htmlfile.html, depending on which one I requested
I have been trying hard on this, and sofar I've came with this content for my .htaccess file (located in the "foo" folder), which is unfortunately only working in the last of the two cases, in which I am interested (ie serving "phpfile.php" when I request "phpfile", serving "htmfile.htm" when I request "htmfile" or serving "htmlfile.html" when I request "htmlfile"), and which is ignoring the 301 redirections:
Options +FollowSymLinks
RewriteEngine on
RewriteBase /foo
# Redirect permanently the requests for existing .php files
# to extensionless files (non present on the server)
# so that phpfile.php gets redirected to phpfile
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} \.php$
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)\.php$ $1 [R=301,NC]
# Redirect permanently the requests for existing .htm(l) files
# to extensionless files (non present on the server)
# so that htmfile.htm gets redirected to htmfile
# so that htmlfile.html gets redirected to htmlfile
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} \.html?$
RewriteCond %{REQUEST_FILENAME}\.html? -f
RewriteRule (.*)\.html?$ $1 [R=301,NC]
# Matching requests for non existing extensionless files
# with their existing equivalent on the server
# so that domain.com/foo/phpfile will display
# the contents of domain.com/foo/phpfile.php,
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)$ $1.php [L]
# so that domain.com/foo/htmlfile will display
# the contents of domain.com/foo/htmlfile.html,
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)$ $1.html [L]
# so that domain.com/foo/htmfile will display
# the contents of domain.com/foo/htmfile.htm,
RewriteCond %{REQUEST_FILENAME}\.htm -f
RewriteRule (.*)$ $1.htm [L]
Thank you in advance for any help/ advice.
There's a logic flaw in the first two rules in that it's the php or html file that exists. The URI check is also in effect a duplicate of the rewrite rule pattern and !f implies !-d. You can also fold these into a single rule:
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*?)\.(php|html?)$ $1 [R=301,NC]
The last two are OK, but I'd swap the order if html requests are more common than php
Why MultiViews doesn't help
Options +MultiViews implements a concept known as content negotiation, and in doing this Apache invokes a subquery to parse the filename root name. One of the things that it does is to scan the directory for known filename.extension combinations so in this case if xxx.php exists and your request is for xxx then it will substitute xxx.php and do an internal redirection, which then causes your first rule to fire, removing the .php extension and this causes the error that you see.
So (i) you need to disable multiviews, and (ii) ditto subqueries; (iii) detect and prevent retry loops. This is one solution which will do what you want:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /foo
RewriteCond %{ENV:REDIRECT_END} =1
RewriteRule ^ - [L,NS]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*?)\.(php|html?)$ $1 [R=301,NC,NS]
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)$ $1.html [L,E=END:1,NS]
RewriteCond %{REQUEST_FILENAME}\.htm -f
RewriteRule (.*)$ $1.htm [L,E=END:1,NS]
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)$ $1.php [L,E=END:1,NS]
I would like thank Everybody for this post as it really helped me a lot and I used something like the one below and works for me ...
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteBase /
RewriteCond %{ENV:REDIRECT_END} =1
RewriteRule ^ - [L,NS]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*?)\.(php|html?)$ $1 [R=301,NC,NS]
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule (.*)$ $1.html [L,E=END:1,NS]
RewriteCond %{REQUEST_FILENAME}\.htm -f
RewriteRule (.*)$ $1.htm [L,E=END:1,NS]
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.*)$ $1.php [L,E=END:1,NS]
This version works for me.
Thank you.
Cheers!

.htaccess: mod_rewrite

Here is what I'm trying to accomplish:
(this .htaccess file is located in mysite.com/test/):
http://mysite.com/test/admin go to http://mysite.com/test/admin/index.php
http://mysite.com/test/contact go to http://mysite.com/test/contact.php
http://mysite.com/test/salt-lake-city/ go to http://mysite.com/test/index.php/city=salt-lake-city
http://mysite.com/test/salt-lake-city/deals/ go to http://mysite.com/test/deals.php?city=salt-lake-city
To start, I have:
RewriteRule ^(.*)/(.*)\.php$ $2.php?city=$1 [L]
(this handles the last 2). But, when I try to add the admin clause:
RewriteRule ^admin/ admin/index.php [L]
RewriteRule ^(.*)/(.*)\.php$ $2.php?city=$1 [L]
It messes up (the css is out of whack) etc.
Any thoughts?
Well .. if I had to do these rewrite rules, I would do them like this:
Options +FollowSymLinks -MultiViews
RewriteEngine On
# do not do anything for already existing files
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
# admin rewrite
RewriteRule ^admin$ admin/index.php [L]
# rewrite /contact --> /contact.php (and similar)
# add .php extension if such file does exist
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ $1.php [L]
# OR
# alternatively specify their names directly
# plus it is more precise for the example you have provided
# (that's if you need to rewrite only specific pages)
RewriteRule ^(contact|about|something)$ $1.php [L]
# /salt-lake-city/ --> /index.php?city=salt-lake-city
RewriteRule ^([^/]+)/$ index.php?city=$1 [QSA,L]
# /salt-lake-city/deals/ --> /deals.php?city=salt-lake-city
RewriteRule ^([^/]+)/deals/$ deals.php?city=$1 [QSA,L]
To start, I have:
RewriteRule ^(.*)/(.*)\.php$ $2.php?city=$1 [L]
(this handles the last 2).
Sorry, but I do not see how "it will handle the last 2". I see no .php in the last two URL examples you have provided.
It messes up (the css is out of whack) etc.
Well -- let's see how it will work with my rules. In any case -- it may also depends how you wrote links to css/images/js.

Resources