.htaccess Cancel out repeditive tasks - .htaccess

I have a bit of problem, here my log:
1. strip per-dir prefix: C:/wamp/www/web.site/projects/test/ -> projects/test/
2. applying pattern '(.*)' to uri 'projects/test/'
3. RewriteCond: input='C:/wamp/www/web.site/projects/test/' pattern='!-f' => matched
4. RewriteCond: input='C:/wamp/www/web.site/projects/test//index.php' pattern='!-f' => not-matched
5. pass through C:/wamp/www/web.site/projects/test/
6. strip per-dir prefix: C:/wamp/www/web.site/projects/test/index.php -> projects/test/index.php
7. applying pattern '(.*)' to uri 'projects/test/index.php'
8. RewriteCond: input='C:/wamp/www/web.site/projects/test/index.php' pattern='!-f' => not-matched
9. pass through C:/wamp/www/web.site/projects/test/index.php
.
Question is, why wont it stop at Line 5? or why is line 9 not line 5 ? Is there a way to prevent this? Here the code i have in my .htaccess file.
.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule (.*) index.php [NC,L]
.
Can some one help me out here? I wan't faster loading times. Thank you in advance.

It seems that you've configured Apache to a simple thing: if there's a directory that is requested then try to serve "index.php" that is in this directory:
DirectoryIndex index.php
So here's what's happening: Apache rewrites everything fine, then sees it's a directory => it tries to server index.php. The behavior seems both normal and pretty common ;)

Related

Symfony 4 + AWS Cloudfront as PageCache + AWS ELB results in endless redirects on frontpage

I am having the following setup:
Domain -> Cloudfront -> ELB -> #instances
This fails ONLY (!) on the index page, all sub pages are working fine!
If I remove the Cloudfront in the chain, everything works.
So the server error says "Too many redirects". I am using currently (for testing) the following .htaccess content ("official" example):
# Use the front controller as index file. It serves as a fallback solution when
# every other rewrite/redirect fails (e.g. in an aliased environment without
# mod_rewrite). Additionally, this reduces the matching process for the
# start page (path "/") because otherwise Apache will apply the rewriting rules
# to each configured DirectoryIndex file (e.g. index.php, index.html, index.pl).
DirectoryIndex index.php
# By default, Apache does not evaluate symbolic links if you did not enable this
# feature in your server configuration. Uncomment the following line if you
# install assets as symlinks or if you experience problems related to symlinks
# when compiling LESS/Sass/CoffeScript assets.
# Options FollowSymlinks
# Disabling MultiViews prevents unwanted negotiation, e.g. "/index" should not resolve
# to the front controller "/index.php" but be rewritten to "/index.php/index".
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
# 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 index.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]
# Sets the HTTP_AUTHORIZATION header removed by Apache
RewriteCond %{HTTP:Authorization} .
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
# Redirect to URI without front controller to prevent duplicate content
# (with and without `/index.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 ^index\.php(?:/(.*)|$) %{ENV:BASE}/$1 [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}/index.php [L]
</IfModule>
<IfModule !mod_rewrite.c>
<IfModule mod_alias.c>
# When mod_rewrite is not available, we instruct a temporary redirect of
# the start page to the front controller explicitly so that the website
# and the generated links can still be used.
RedirectMatch 307 ^/$ /index.php/
# RedirectTemp cannot be used instead
</IfModule>
</IfModule>
I enabled trace logging for htaccess mod rewrite with the following output if I open the index page with cloudfront.domain.com
[rewrite:trace2] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff233f70/initial] [perdir /var/www/html/web/] trying to replace context docroot /var/www/html/web with context prefixerror_log
[rewrite:trace1] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff233f70/initial] [perdir /var/www/html/web/] internal redirect with /index.php [INTERNAL REDIRECT]error_log
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] strip per-dir prefix: /var/www/html/web/index.php -> index.php
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] applying pattern '^(.*)' to uri 'index.php'
[rewrite:trace4] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] RewriteCond: input='/index.php::index.php' pattern='^(/.+)/(.*)::\\\\2$' => not-matched
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] strip per-dir prefix: /var/www/html/web/index.php -> index.phperror_log
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] applying pattern '^' to uri 'index.php'
[rewrite:trace4] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] RewriteCond: input='' pattern='.' => not-matched
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] strip per-dir prefix: /var/www/html/web/index.php -> index.php
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] applying pattern '^index\\\\.php(?:/(.*)|$)' to uri 'index.php'
[rewrite:trace4] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] RewriteCond: input='200' pattern='^$' => not-matched
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] strip per-dir prefix: /var/www/html/web/index.php -> index.php
[rewrite:trace3] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] applying pattern '^' to uri 'index.php'
[rewrite:trace4] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] RewriteCond: input='/var/www/html/web/index.php' pattern='-f' => matched
[rewrite:trace1] ... [cloudfront.domain.com/sid#55e9fedd93e0][rid#55e9ff166a68/initial/redir#1] [perdir /var/www/html/web/] pass through /var/www/html/web/index.php
The comments in the .htaccess files say that you should comment the lines if the error with "too many redirects" occurs. But this is not working for me. Cause the problem only occurs with cloudfront in front of the webserver.
Also this setup was working fine with Symfony 3.4!
Any .htaccess server gurus out there who can tell me what is possibly causing the problem?
I fixed it by myself.
The problem seems to be that Cloudfront is adding a slash to the REQUEST_URI, which leads to a duplicate / on the index page and a redirect to itself and so on.
So my hotfix was to put that at the beginning of the index.php file to remove // from the REQUEST_URI:
$_SERVER['REQUEST_URI'] = '/' . ltrim(#$_SERVER['REQUEST_URI'], '/');

.htaccess subdomain Rewrite rule is not working

I am making a website builder an I would like to make urls prettier.
The url would be for example:
https://ccc-bb.example.com => https://example.com/project/show/ccc/bb
This is my .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine On
# prevents files starting with dot to be viewed by browser
RewriteRule /\.|^\.(?!well-known/) - [F]
# front controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\-(.*)$ https://example.com/project/show/$1/$2 [L]
When I use above (https://ccc-bb.example.com) it sends me to the subdomain empty folder. The folder has only the .htaccess file.
What am I missing? I've never edited an .htaccess file and Google didn't help me (or I don't know what should I looking for).
Your first rule for dotfiles is okay but would be better the other way around, since the second part can only match the start, but the first can only match in subdirectories.
RewriteRule ^\.(?!well-known/)|/\. - [F]
Your other rule's problem is that you are expecting it to match the subdomain. RewriteRules do not operate on the entire string you see in your browser's address bar, only the path part, and in .htaccess they see even less as the leading directory is stripped off, too. To access the info you want, use a RewriteCond:
RewriteCond %{HTTP_HOST} ^([^-]++)-([^-.]++)\.example\.com$
RewriteRule ^(?!project/show/).* project/show/%1/%2/$0 [L,DPI]
(You don't need to include \.example\.com$ if your main domain contains no hyphens.)

htaccess rewrite rules with regexp and inifite redirect

I have a hard time to create rewrite rule for a redirect using part of an old URL for WP. Example:
Old URL:
http://www.example.com/news/index.php/2014/11/07/my-blog-post-from-old-site
or
http://www.example.com/news/index.php/2014/11/07/my_blog_post_from_old_site
New URL:
http://www.example.com/2014/11/07/my-blog-post
New URL should to have only dates and first three elements of a permalink after stripping from dashes.
My solution came after combining answers from here https://stackoverflow.com/a/32852444/1090360 and here https://stackoverflow.com/a/1279758/1090360
Somehow part for replacing underscores with dashes creates infinite redirect and a server freezes. If I will remove part with replacing underscores to dashes all the rest works as should.
Here are my .httaccess rules
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
#replace underscores with dashes
RewriteRule ^(/news/.*/[^/]*?)_([^/]*?_[^/]*)$ $1-$2 [N]
RewriteRule ^(/news/.*/[^/]*?)_([^/_]*)$ $1-$2 [R=301,L,NC]
#redirect to new URL
RewriteRule ^news/index\.php/([^-]+-[^-]+-[^-]+).* /$1 [R=301,L,NC]
#WP standard stuff
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
I think, this is an expensive way to replace underscores with dashes. But this works at least in my test environment. The first rule replaces dashes one by one. The second rule then removes the prefix from the requested URL.
RewriteBase /
# replace underscores with dashes
RewriteRule ^(news/index.php/.+?)_(.*) $1-$2 [L]
# strip "news/index.php"
RewriteRule ^news/index.php/(.*) /$1 [R=302,L]
I played a bit more with your original approach using the N|next flag and crashed my server too. Looking into the error.log, it seems this infinite loop is created by Apache by adding a "path info postfix", which enlarges the URL with the original URL. And so it keeps replacing underscores with dashes on and on.
You can prevent this path info postfix with another flag DPI|discardpath, which gives the following rule
RewriteRule ^(news/index.php/.+?)_(.*) $1-$2 [N,DPI]
This seems to work too. Although I must admit, I don't really understand this "path info postfix" thing. There's also an entry in Apache's Bugzilla, Bug 38642: mod_rewrite adds path info postfix after a substitution occured
Never test with 301 enabled, see this answer Tips for debugging .htaccess rewrite rules for details.

htaccess RewriteRule doesn't work

I am working in yii framework and try to rewrite url using htaccess file
this is my file
(at first step I am trying to work with a simple rule)
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^carguide$ MainModel/index/304 [NC,L]
# otherwise forward it to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
# otherwise forward it to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
I want to rewrite url carguide to mainModel/index/304,
but no meter what i tried the yii receive the orliginal url and raise 404 error.
here is the log file:
strip per-dir prefix: C:/xampp/htdocs/cars/carguide -> carguide
applying pattern '^carguide$' to uri 'carguide'
RewriteCond: input='C:/xampp/htdocs/cars/carguide' pattern='!-f' => matched
RewriteCond: input='C:/xampp/htdocs/cars/carguide' pattern='!-d' => matched
rewrite 'carguide' -> 'MainModel/index/304'
add per-dir prefix: MainModel/index/304 -> C:/xampp/htdocs/cars/MainModel/index/304
strip document_root prefix: C:/xampp/htdocs/cars/MainModel/index/304 -> /cars/MainModel/index/304
internal redirect with /cars/MainModel/index/304 [INTERNAL REDIRECT]
add path info postfix: C:/xampp/htdocs/cars/MainModel -> C:/xampp/htdocs/cars/MainModel/index/304
strip per-dir prefix: C:/xampp/htdocs/cars/MainModel/index/304 -> MainModel/index/304
applying pattern '^carguide1$' to uri 'MainModel/index/304'
add path info postfix: C:/xampp/htdocs/cars/MainModel -> C:/xampp/htdocs/cars/MainModel/index/304
strip per-dir prefix: C:/xampp/htdocs/cars/MainModel/index/304 -> MainModel/index/304
applying pattern '.' to uri 'MainModel/index/304'
RewriteCond: input='C:/xampp/htdocs/cars/MainModel' pattern='!-f' => matched
RewriteCond: input='C:/xampp/htdocs/cars/MainModel' pattern='!-d' => matched
rewrite 'MainModel/index/304' -> 'index.php'
add per-dir prefix: index.php -> C:/xampp/htdocs/cars/index.php
strip document_root prefix: C:/xampp/htdocs/cars/index.php -> /cars/index.php
internal redirect with /cars/index.php [INTERNAL REDIRECT]
strip per-dir prefix: C:/xampp/htdocs/cars/index.php -> index.php
applying pattern '^carguide$' to uri 'index.php'
strip per-dir prefix: C:/xampp/htdocs/cars/index.php -> index.php
applying pattern '.' to uri 'index.php'
RewriteCond: input='C:/xampp/htdocs/cars/index.php' pattern='!-f' => not-matched
pass through C:/xampp/htdocs/cars/index.php
I tried to change the flags, add a RewiteBase.
As I can see you don't need to use .htaccess to create a particular rewrite rule for each page of your site. It's enough to use simple .htaccess as proposed here and then configure your rewrite rules using Yii's URL manager.
UPDATE
If your controller's name is mainModel and your action's name is index (in terms of Yii the route is mainModel/index) and you want this page to be accessable through http://yoursite/carguide then your configuration of URL manager in protected/config/main.php could look like this:
'urlManager' => array(
'urlFormat' => 'path',
'showScriptName' => false,
'rules' => array(
'carguide' => 'mainModel/index',
)
),
UPDATE
Please refer to this page for configuration properties supported by Yii's URL manager class.

Converting relative URL requests to absolute URL request using mod_rewrite

I have made use of a simple rewrite rule in my .htaccess file to make my URL's pretty. What was once like this:
http://somedomain.com/product-details.php?product=MQ==&hash=123456789
Is now this:
http://somedomain.com/secure/123456789/MQ==/rings/details/blue-diamond-topaz-ring.php
This is all very well, but I have many a PHP file that has all JS and CSS links as relative. Because of the above new pretty URL, these links to JS and CSS are now 5 or 6 directories too deep.
My Question: By means of mod_rewrite, is there a way I can make a request for css/style.css or js/somescript.js rewrite to something like http://www/somedomain.com/css/style.css for example?
I have Googled my heart out and done my homework, and while I can find a million references to rewriting URL's, none seem to work in the same manner for requesting such scripts. I tried this but to no avail:
RewriteRule ^/css/(.*)$ http://localhost/dev/css/$1 [R=302,L]
I assumed that would send ALL requests like /css/somefile.css to http://localhost/dev/css/somefile.css
Any help or guidance is well and truly appreciated.
UPDATE: Here is the rewrite portion of my .htaccess file:
RewriteEngine on
Options +FollowSymLinks
RewriteBase /eterniti-mygate/
RewriteRule ^([^-]*)-article-([^-]*)\.php$ /in-the-news.php?action=$1&article=$2 [L]
#rings rewrite rule
RewriteRule ^secure/([^-]*)/([^-]*)/rings/details/([^_]*)\.php$ ring-details.php?product=$2&hash=$1 [L]
RewriteRule ^css/(.*)$ http://localhost/eterniti-mygate/css/$1 [R=302,L]
UPDATE: Here is the log file output for the rewrites
Please see my log file at https://docs.google.com/leaf?id=0B-NRfZvE6xi7MmI0N2ZjNzEtYWZlYy00NjJiLWJhMjQtYzAyYzY4ZWIxN2U0&hl=en_GB
It appears to not be rewriting the request from the base, but rather from the virtual directory (eg /secure/ring/details/). I have set the rewriteBase to /eterniti-mygate/ which is a folder on my wamp server root.
When using rewriterule remove the leading (back)slash, so try this:
RewriteRule ^css/(.*)$ http://localhost/dev/css/$1 [R=302,L]
This should be useful
RewriteCond %{REQUEST_FILENAME} \.css
RewriteRule ^css/(.*)$ http://localhost/dev/css/$1 [L]
When a .css file is called, you rewrite (if the file is under css/) to http://localhost/dev/css/<pathorname>.
Take care that <pathorname> can include subdirectories.
Also the [R=302] might just not be needed. Internal redirection should be enough.
If that does not work, you can see what happens with :
RewriteLog "/var/log/apache2/rewrite.log"
RewriteLogLevel 2
(you can push log level to 4 if you still can't understand.)
' Edit with the log details
Line 20 : [perdir C:/wamp/www/eterniti-mygate/] add path info postfix: C:/wamp/www/eterniti-mygate/secure -> C:/wamp/www/eterniti-mygate/secure/af192eaa6808acab8947ce59a32f8d17/MQ==/rings/details/css/reset.css
Line 21 : [perdir C:/wamp/www/eterniti-mygate/] strip per-dir prefix: C:/wamp/www/eterniti-mygate/secure/af192eaa6808acab8947ce59a32f8d17/MQ==/rings/details/css/reset.css -> secure/af192eaa6808acab8947ce59a32f8d17/MQ==/rings/details/css/reset.css
We are trying to serve secure/af192eaa6808acab8947ce59a32f8d17/MQ==/rings/details/css/reset.css
'^([^-]*)-article-([^-]*)\.php$'
'^secure/([^-]*)/([^-]*)/rings/details/([^_]*)\.php$'
'^css/(.*)$'
Won't match. Knowing that the caret (^) means : beginning of the string/URL (http://mysite.com excluded), you can't detect something that is not like css/<something>END (FYI: $ means ends of string/URL). Remove it from your rule and it should match <anything>css/<something>END and the rule will apply.

Resources