apache not serving static content correctly - php

I have been working on my own mvc framework to further my web app learning, but am having trouble serving static resources. I am trying to have a single entry point into the application, aka a front controller, so in my project / I have an .htaccess file that redirects all requests to the app/ folder where another .htaccess passes the request uri to index.php (in app/) who delegates the request to the appropriate controllers.
However, when I try to serve up static content, such as javascripts or cascading style sheets, I still get redirected through app/index.php. I am also getting "favicon.ico does not exist in /var/www" errors in /var/log/apache2/errors.log (maybe because of symlink to ~/www?). I do not expect to because of the following .htaccess file in the root directory of my project root:
<IfModule mod_rewrite.c>
Options -Indexes +FollowSymLinks
RewriteEngine On
RewriteBase /
# ----------------------------------------------------------------------
# Suppress the "www." at the beginning of URLs
# ----------------------------------------------------------------------
# The same content should never be available under two different URLs - especially not with and
# without "www." at the beginning, since this can cause SEO problems (duplicate content).
# That's why you should choose one of the alternatives and redirect the other one.
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
#----------------------------------------------------------------------
# Route static resources to respective files
#----------------------------------------------------------------------
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond public/$0 -f
RewriteRule ^.+\.(jpg|gif|png|ico|css|js)$ /public/$0 [L]
#----------------------------------------------------------------------
# Redirect all other requests to the app folder
#----------------------------------------------------------------------
RewriteRule ^$ app/ [L]
RewriteRule (.*) app/$1 [L]
</IfModule>
and here is the .htaccess in my app/ folder:
<IfModule mod_rewrite.c>
RewriteEngine On
# ensure request is not path to filename or directory
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# redirect all requests to index.php?url=PATHNAME
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
Why can't I serve static content correctly? This would make sense to me if I wasn't trying to sent all static requests to public/, which is where my css, jpg, png, js, etc files reside. But I have a RewriteCond rule in there to send the requests for such files to the public dir... Confusing?

Assuming, from what I understood, that your project structure is the following:
/
/.htaccess
/app/.htaccess
/app/index.php
/public/static.js (for example)
Here is what I come up with, hoping it'll solve your problem:
the .htaccess in the root folder:
<IfModule mod_rewrite.c>
Options -Indexes +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
RewriteRule ^public/.+\.(jpg|gif|png|ico|css|js)$ - [L]
RewriteRule ^(.*)$ app/$1 [L]
</IfModule>
And the .htaccess in the app folder is unchanged.
Every request starting with public and being a file with the listed extensions won't be redirected which is done with the dash character.
The last rule allows to redirect a request to the app/index.php file.
I think the resulting behaviour is the expected one:
static files in the public directory are not redirected,
files with another extension in the public directory will be
redirected to app/index.php (maybe for some error treatment),
requests not starting with public will be redirected to
app/index.php.

Related

Multiple Rewrite Rules for .htaccess, Redirect to www while including index.php

Specifically, I want to redirect all non-www pages to www, while also running an index.php file located in my root directory. To solve both of these problems I am using .htaccess.
I have already set up my site to run the PHP file to run in every directory. But the moment I add redirection from non-www to www it breaks.
The problem seems to be, that the multiple rewrite rules conflict with each other. Either one runs and the other does not, or the site just responds with a 500 error.
My question is, should multiple Rewrite rules be "combined" into one? Or am I just using those multiple rules wrong? (Or is it just some strange syntax thing I messed up? I have been working on this for a while haha)
Any help is very much appreciated.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L,QSA]
# Redirect to www.
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule (.*) https://www.example.com/$1 [R=301,L]
</IfModule>
I found this works:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L] #if not already index.php
RewriteCond %{REQUEST_FILENAME} !-f #only if NOT a FILE (directory / non-existent file)
RewriteRule . /index.php [L] #redirect to index.php
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule ^(.*) https://www.example.com/%{REQUEST_FILENAME} [R=301,L] #redirect to https://www
</IfModule>
This cannot possibly "work" as written, as there are a number of errors:
You are missing the opening <IfModule mod_rewrite.c> directive. However, this <IfModule> wrapper is not required anyway and should be removed.
Line-end comments are not supported by Apache. Specifically, the following line will result in a 500 error due to "bad flag delimiters":
RewriteCond %{REQUEST_FILENAME} !-f #only if NOT a FILE (directory / non-existent file)
(UPDATE: If you are not seeing a 500 error response here, it's possible you are on a LiteSpeed server; not Apache? On LiteSpeed, this line-end comment appears to work as intended!)
Your external redirect (at the end) that redirects to www never gets processed for anything other than requests for directories (including the root) or real files (except index.php). This redirect needs to go first, before the existing rewrites. However, see the next point...
You are incorrectly using REQUEST_FILENAME (the absolute filesystem path) in the target URL - this will result in a malformed redirect. You could use the REQUEST_URI server variable instead (full URL-path), but note that you also have a double slash issue. So, it would need to be rewritten like the following instead:
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]
Minor points:
The RewriteBase is not being used here and could be safely removed. (Unless you have other directives that use this?)
Summary
Bringing the above points together we have:
RewriteEngine On
# Redirect to https://www
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Stop here if already index.php
RewriteRule ^index\.php$ - [L]
# Only if NOT a FILE (non-existent file)
RewriteCond %{REQUEST_FILENAME} !-f
# Rewrite to index.php (in the document root)
RewriteRule . /index.php [L]
Note that this still rewrites directories to /index.php, contrary to what your comment stated.
Test first with a 302 (temporary) redirect to avoid potential caching issues.
You will need to clear your browser cache before testing.
After lots of tinkering/research, I found this works:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L] #if not already index.php
RewriteCond %{REQUEST_FILENAME} !-f #only if NOT a FILE (directory / non-existent file)
RewriteRule . /index.php [L] #redirect to index.php
RewriteCond %{HTTP_HOST} ^example.com$
RewriteRule ^(.*) https://www.example.com/%{REQUEST_FILENAME} [R=301,L] #redirect to https://www
</IfModule>
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin "*"
</IfModule>

How to add two index.php file in .htaccess file for Codeigniter

I have two application inside WWW and I have created two index files id1.php and id2.php for two application app1 and app2
Structure
www\app1\application...
www\app2\application..
www\system\
location of id1.php and id2.php
www\app1\id1.php
www\app2\id2.php
I have created .htaccess as below
RewriteEngine on
RewriteCond $1 !^(id1|id2\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ app1/id1.php
With this I can open application app1, localhost\app1\welcome, but i can not open localhost\app2\welcome,
How can I add id2.php in .htaccess?
Assuming app1 and app2 are supposed to be in your public URLs, and match the physical directories you have in your web root, don't put any app-specific rewrite rules for them in your root .htaccess. They should each have their own .htaccess in their directories. Ensure each has a correct base, e.g. RewriteBase /app1/. Make sure you don't interfere with URLs beginning with those directories by either doing no rewriting in the root, or explicitly ignoring them.
In /.htaccess
RewriteEngine on
RewriteBase /
# always match app dirs and do nothing, so allow their own rewriting
RewriteRule ^(?:app1|app2)(?:$|/) - [L]
# any non-app rules go here
In /app1/.htaccess
RewriteEngine on
RewriteBase /app1/
# files
RewriteCond $0 !^(?:index\.php|robots\.txt)$
# directories
RewriteCond $0 !^(?:resources|some-other-dir)(?:$|/)
RewriteCond %{REQUEST_FILENAME} !-f
# do you really need to exclude dirs? are you allowing auto-index pages?
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .+ index.php [NS,L,DPI]

.htacces redirect assets to assets folder

I have my PHP site setup with a folder for each site (e.g Login), which has an Index.php file and site-specfic assets. However, some of the assets, which are required by every single page, are stored in a 'Assets' folder located directly under the highest level (does that make sense?).
I have played around with .htaccess and got this code
RewriteEngine on
RewriteBase /
RewriteRule ^(.*)$ http://janberktold.com/Assets/$1 [R=301,L]
However, my problem is: It redirects
localhost/Login/test.css
to
localhost/Assets/Login/test.css
instead of
localhost/Assets/test.css
How do I get my server to redirect to the correct path?
Try this
RewriteEngine on
RewriteBase /
# Rewrite if the file does not exists
RewriteCond %{REQUEST_FILENAME} !-f
# Rewrite only if the URI does not starts with Assets
RewriteCond %{REQUEST_URI} !^/Assets
# Rewrite any assets file
RewriteRule ([^/]*).(css|js|png|jpe?g)$ Assets/$1.$2 [L]
This should rewrite any assets files localhost/dir/file.css or localhost/dir/dir2/file.css to localhost/Assets/file.css
Replace your rules with:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(?:[^/]*/)*([^/.]+\.(?:jpe?g|gif|bmp|png|tiff|css|js))$ /Assets/$1 [R=301,L,NC]

Concrete5 admin site - no input file specified

My working Conrete5 site recently developed a "no input file specified" problem on ALL admin pages. The root of the problem appears to be that admin pages have an unnecessary /index.php in the URL. I.E.
www.example.com/index.php/login/do_login......
If the /index.php part is removed from the URL the page will load (though all referenced files will still have /index.php hence fail to load).
I have concrete running in a sub directory but the page urls are from root e.g.
www.example.com/concrete-page-title...
This is the .htaccess file in my root directory relaying concrete requests to the concrete sub-directory.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !(\.|/$)
RewriteRule (.*) http://www.example.co.uk/$1/ [R=301,L]
RewriteCond %{HTTP_HOST} ^example.co.uk$
RewriteRule ^/?(.*)$ http://www.example.co.uk/$1 [R=301,L]
# redirect concrete
RewriteCond %{REQUEST_URI} !^/concrete
# permit normal access to wordpress installation
RewriteCond %{REQUEST_URI} !^/news
RewriteRule ^(.*)$ concrete/$1 [L]
</IfModule>
I have pretty urls turned on, here is the .htaccess file in my concrete sub-directory (/concrete).
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}/index.html !-f
RewriteCond %{REQUEST_FILENAME}/index.php !-f
RewriteRule . index.php [L]
</IfModule>
Sidenote:
cgi.fix_pathinfo=1 (have changed to 0, no change)
And the site is not hosted with GoDaddy.
The sites been for a fair while now with no updates, despite my fiddling I have had no success so any suggestions greatly welcome.
Something that worked on a site where the server's PHP had been upgraded:
in config/site.php add:
define('SERVER_PATH_VARIABLE', 'REQUEST_URI');
define('DIR_REL', '');

use subdomain to access codeigniter's modules

I have a sales script based on codeigniter and it's working great
I built an api for it, and am using it via: http://www.mysite/api/getdata
so I want now to access this api via a sub domain, like: http://www.api.mysite/getdata
as I think the solutions is: to redirect all *.mysite.com to mysite.com and then modify the .htaccess, but I don't know is it true?
----------------------------------------Update----------------------------------------
My current .htaccess File
<IfModule mod_rewrite.c>
# Check if mod_rewrite module loaded and we can work with SEO urls
SetEnv HTTP_MOD_REWRITE On
RewriteEngine on
# To redirect all users to access the site WITH the 'www.' prefix,
# (http://example.com/... will be redirected to http://www.example.com/...)
# adapt and uncomment the following:
# RewriteCond %{HTTP_HOST} ^yoursite\.com$ [NC]
# RewriteRule ^(.*)$ http://www.yoursite.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !=/favicon.ico
#RewriteRule ^(.*)$ index.php/$1 [L]
RewriteRule ^(.*)$ ./index.php [L]
</IfModule>
If you are using some kind of hosting service that lets you create a subdomain and point it to a document root, you can try creating a www.api.mysite domain and make the document root where mysite's /api directory is. That would get around the need to use an htaccess file. Alternatively, if you have access to your virtual host config, you can do the same thing, creating a vhost for www.api.mysite and point the document root to the /api directory.
If you don't have any control over that stuff, you'll need to setup the *.mysite.com to point to the same site as www.mysite and use an htaccess file. Something like this in the htaccess file in the document root should do the trick:
RewriteEngine On
RewriteCond %{HTTP_HOST} (www\.)?api.mysite [NC]
RewriteCond %{REQUEST_URI} !^/api/
RewriteRule ^(.*)$ /api/$1 [L]

Categories