Apache RewriteRule pattern - apache

I writing an .htaccess file for the web resources management.
I would like to this pattern of URI to use for static resource
^.*/web-console/static/(.*)$
And, my RewriteRule is below.
RewriteRule "^.*/web-console/static/(.*)$" "resources/floworks-web-console-1.0/static/$1" [L]
And, I request below URI
http://myhost/shop/web-console/static/css/default.css
But the Apache server hasn't match URI.
And if I delete "/web-console" Apache works fine.
Below is the RewriteRule
RewriteRule "^.*/static/(.*)$" "resources/floworks-web-console-1.0/static/$1" [L]
What is a problem?
Appendix
this is my directory structure
web base - /data/web
site base - /data/web/shop
htaccess - /data/web/shop/.htaccess
router script - /data/web/shop/route.php
static resources - /data/web/shop/resources/floworks-web-console-1.0/static
css file - /data/web/shop/resources/floworks-web-console-1.0/static/css/default.css
So, I wish response static resources if URI is started /shop/web-console/static
And, other case is pass to router script using "RewriteRule .* route.php [L]"

You should be able to do it like this. If you have this .htaccess in a sub folder shop, you should add rewritebase.
RewriteEngine On
RewriteBase /shop/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule "^web-console/static/(.*)$" "resources/floworks-web-console-1.0/static/$1" [L]

I found myself.
RewriteRule "web-console/static/(.*)$" "resources/floworks-web-console-1.0/static/$1" [END]
I'd change that flag from L to END
Thanks.

Related

htaccess rewrite root url to subfolder with accessing other folder?

I have following folder structure in apache server.
Public_html
-->admin
--->admin_login.php
-->website
--->index.php
since the index.php inside the website folder,
i have given following code in .htaccess
RewriteCond %{REQUEST_URI} !^/website/
RewriteRule ^(.*)$ /website/$1 [L,NC]
so that the when the user enter root url , it will appear "www.myurl.com" instead of "www.myurl.com/website/"
but the issue is, i could not be able to access admin_login.php.
is there anyway to modify .htaccess, to come website/index.php in main url and able to access admin_login.php(both)?
Thanks in Advance
You need to add an exception to existing rule like this:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/(website|admin)/ [NC]
RewriteRule .* website/$0 [L]
Negative condition %{REQUEST_URI} !^/(website|admin)/ will match every URI except URIs that start with /website/ or /admin/. This will allow you to directly open www.myurl.com/admin/admin_login.php.
With your shown samples and attempts please try following .htaccess rules file. Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^index\.php/?$ website/index.php [QSA,NC,L]

htaccess redirect API to sub folder

My document root (/var/www/html/) looks like this:
app/
client/
index.html
server/
api/
user/
get.php
classes/
models/
When the user navigates to any URL on my website that does NOT start with api/, they should load the index.html file inside of client.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond ^ app/client/index.html [QSA,L]
That code works correctly.
However, when the URL starts with api/, I want to direct the URL to the api folder under server/.
For instance, www.website.com/user would load the index.html file.
Whereas www.website.com/api/user/get.php would load www.website.com/server/api/user/get.php.
I know that I would need a special condition for api/ before my current condition.
RewriteRule ^api app/server/api [L]
That rule works when using www.website.com/api, but it does not work when there are slashes after api/. www.website.com/api -> www.website.com/app/server/api, www.website.com/api/test -> www.website.com/var/www/html/test.
Any ideas?
Have it this way:
RewriteEngine On
RewriteRule ^api(/.*)?$ app/server/api$1 [L,NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond ^ app/client/index.html [L]
Make sure to test it after clearing your browser cache.

htaccess pretty urls not working

Folder structure:
- assets
- all css / js
- calsses
- all models, db ant etc
- views
- admin
- app
- index.php
- customers.php
.......
my .htaccess
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} ^(www.)?localhost:8080$
RewriteRule ^(.*)$ /views/$1
RewriteRule ^(/)?$ /views/index.php [L]
address : localhost:8080/app/ - working fine, but then I try to add pretty url for example in my customers.php - localhost:8080/app/customers.php?id=5 change to localhost:8080/app/customers/id/5
htaccess added new line:
RewriteRule /id/(.*) customers.php?id=$1
It's not working, it always return 500 Internal Server Error there could be the problem?
plus Need all urls without .php extend
You'd have to include those conditions for every rule. You'd be better off just rewriting everything to, say views/router.php then using PHP to include the different controllers, or serve a 404 when the URL isn't valid.
RewriteRule !^views/router\.php$ views/router.php [NS,L,DPI]
I agree with Walf in that handling routes through a router class is a better idea (especially in the long run!) than using .htaccess redirects.
However, as your question seems to be more about why is this not working than about how you should do it, here is an explanation for what is going on.
I will be using these URLs as examples:
localhost:8080
localhost:8080/app
localhost:8080/app/customers/id/5
Your first rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{HTTP_HOST} ^(www.)?localhost:8080$
RewriteRule ^(.*)$ /views/$1
As you intended, this RewriteRule will match any URL which is not a file, not a directory, and made to localhost:8080.
localhost:8080 # not matched because it leads to a directory.
localhost:8080/app -> localhost:8080/views/app
localhost:8080/app/customers/id/5 -> localhost:8080/views/app/customers/id/5
Your next rule:
RewriteRule ^(/)?$ /views/index.php [L]
It is important to realize that RewriteCond statements apply only to the first RewriteRule following them, thus all that is being checked here is the path.
Side note: ^(/)?$, as you are not using $1, can be simplified to ^/?$.
localhost:8080 -> localhost:8080/views/index.php
localhost:8080/views/app # not matched
localhost:8080/views/app/customers/id/5 # not matched
As the L flag is specified, Apache will immediately stop the current iteration and start matching again from the top. The documentation is badly worded. Thus, localhost:8080/views/index.php will be run through the first rule, fail to match, be run through this rule, fail to match, and then as no other rules exist to check (yet) no rewrite will be done.
Now lets look at what happens when you add your broken rule.
RewriteRule /id/(.*) customers.php?id=$1
There are a few problems here. First, as you don't require that the URL start with /id/ the rule will always match a URL that contains /id/, even if you have already rewritten the URL. If you amended this by using ^/id/(.*), then you would still have issues as the string that the rewrite RegEx is tested against has leading slashes removed. Lastly and most importantly, customers.php does not exist in your root directory.
localhost:8080/views/index.php # not matched
localhost:8080/views/app # not matched
localhost:8080/views/app/customers/id/5 -> localhost:8080/customers.php?id=5
This is the last rule in your file currently, so now Apache will start over. customers.php does not exist in your directory, so it will be rewritten to views/customers.php. No other rules matched, but the URL has changed and so Apache will start over again, as /views/customers.php does not exist, it will be rewritten to /views/views/customers.php ... This pattern will repeat until you hit the maximum iteration limit and Apache responds with a 500 error.
You can solve this several ways. Here would be my preferred method, but only if you cannot use a router.
RewriteEngine on
# Rewrite the main page, even though it is a directory
RewriteRule ^/?$ views/index.php [END]
# Don't rewrite any existing files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .? - [S=999,END]
RewriteRule ^app/?$ views/app/index.php [END]
RewriteRule ^app/id/(.*)$ views/app/customers.php?id=$1 [END]
TL;DR Use a PHP based router. .htaccess rules can be incredibly confusing.
Please refer to the question, How to make Clean URLs
I think this is what you needed.
you can use RewriteRule ^(.*)$ index.php [QSA,L]
Having another crack.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{HTTP_HOST} !^(?:www\.)?localhost:8080$ [OR]
RewriteCond $0 =views
RewriteRule [^/]* - [END]
RewriteRule ^(app|admin)/([^/]+) views/$1/$2.php [DPI,END]
RewriteRule ^(app|admin)/?$ views/$1/index.php [DPI,END]
You may have to use L instead of END flags if your Apache is older. Set up an ErrorDocument for 404s, too.
Don't muck around with query strings, just parse $_SERVER['REQUEST_URI'] in PHP, e.g. start by exploding it on /. Then you'll have all the parameters of the original pretty URL. You can do that part in an include so each controller can reuse the same code.
I tried your structure and .htaccess file myself and found an endless loop in the apache logs. I bet you got something like this:
Mon Nov 28 19:57:32.527765 2016] [core:error] [pid 10] [client 172.18.0.1:35048] AH00124: Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
I could fix it by adding the last rule like:
RewriteRule id/(.*) /views/app/customers.php?id=$1
The leading / is not needed for the match and the target needs the full path. Note that I got the id double (e.g. 123/123) on the url: http://localhost:8080/id/123.
This is caused by one of the 2 previous rules (removing them fixes it) so you might need to change them.
Here is what you want :
RewriteEngine On
RewriteBase /app/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^\/?$ views/index.php [L]
RewriteRule ^([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)\/([a-zA-Z0-9]+)\/?$ views/$1.php?$2=$3 [L]
RewriteRule ^([a-zA-Z0-9]+)\/?$ views/$1.php [L]

mod_rewrite - Removing index.php from URL (in subfolder)

I'm trying to get an API working (locally, for now), which lives in a subfolder. I've been trying every example I can find, but all are ending up in 404 errors.
I have this URL:
http://127.0.0.1/~owner/personal/api/v1/index.php/tasks
I want to be able to use this:
http://127.0.0.1/~owner/personal/api/v1/tasks
Eventually, it will become this:
http://api.mydomain.com/tasks
I just can't seem to get my .htaccess rules setup correctly. This keeps getting suggested, but does nothing:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
What am I missing?
Update
I have setup my virtual hosts to use http://api.local/ instead of the previously used addresses.
Accessing http://api.local/index.php/tasks works.
Accessing http://api.local/tasks does not.
Maybe part of your problem is your development environment. You are using a local server to do this on with several subfolders deep and I think it's messing with your .htaccess depending on the location.
If your .htaccess is in the root of your website http://127.0.0.1/.htaccess then it's not going to work properly.
Make sure it's in the same directory as your index.php file and make sure /~owner/personal/api/v1/ is your document root for your dev environment as specified in your apache config file.
Then you can test out your htaccess rules and see how they work. Your current rule should be ok providing /tasks won't be a real directory in the root.
On another note,
I always suggest using your real domain name so you could see how it works as if it were in production. You can do that by modifying your HOST file on your PC and the site will only available to you and you can access via yoursite.com. This quick easy guide will show you.
Try specifying the rewrite base.
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]
You are using the parameters of RewriteRule backwards. You need this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?(.*?)/index.php(.+)?$ /$1$2
This means:
if it's not a file
and it's not a directory
and it looks like / (optional), possibly some more characters, then /index.php, then possibly some more characters, go to the URL without the /index.php part.
Note that I deleted the [L] for now -- it means "if the URL matches this rule, don't apply any more rules." You say you want to keep transforming it into http://api.mydomain.com/tasks, so you shouldn't use [L].

Mediawiki Subdirectory Installation

Possible Duplicate: MediaWiki on SubDirectory and SubDomain (However doesn't have an answer, nor any replies offering help)
Alright, I'm trying to configure MediaWiki to be installed to a sub-directory. I previously had it installed to a primary domain on http://www.example.com/ with a mod_rewrite using a Short URL of /wiki/Main_Title.
As a note, I'm also on HostGator shared hosting which has special rules for short urls.
My directory structure is as such:
/ (site root; location of .htaccess)
/wiki/ (mediawiki root; location of LocalSettings.php)
Here's what I tried,
.htaccess:
RewriteEngine on
RewriteBase /
RewriteRule ^(.*)\&(.*)$ $1\%26$2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^wiki/(.+)$ ./wiki/index.php?title=$1 [PT,L,QSA]
/wiki/LocalSettings.php:
## The URL base path to the directory containing the wiki;
## defaults for all runtime URL paths are based off of this.
## For more information on customizing the URLs please see:
## http://www.mediawiki.org/wiki/Manual:Short_URL
##
$wgScriptPath = "/wiki";
$wgScriptExtension = ".php";
$wgArticlePath = "$wgScriptPath/$1";
However, I do not get anything. I simply get a 403/Forbidden error; no 500 Internal Server Error, just a 403 - url http://www.example.com/. It's as if there's nothing being done. I've banged my head against the wall trying to figure this out. Any help is appreciated.
Thanks in advance!
What is the purpose of
RewriteRule ^(.*)\&(.*)$ $1\%26$2
You've lost me entirely on this one. Any URI with a second parameter will loop indefinitely and generate a 500 status return.
If you read the Rewrite documentation:
What is matched?
...If you wish to match against the ... query string, use a RewriteCond with the ... %{QUERY_STRING} variables
The & is normally part of the query parameter. It can appear in the RewriteRule pattern in the case of malformed URI (e.g. fred&q=1). By default, mod_rewrite will treat this as fred?q=1, but this converts it to the escaped %26 variant so this would be passed as a title fred&q=1 to MW (which is an invalid MW title by the way). I think that you should get rid of it or at least understand what you are trying to do here.
The last line should be
RewriteRule ^wiki/(.+) wiki/index.php?title=$1 [PT,L,QSA]
and keep the RewriteBase otherwise mod_rewrite can get confused.
This should work OK:-)
You're on the right track... if you're on a shared environment, then try this:
RewriteEngine on
# Comment to force base to be the subdir:
# RewriteBase /
RewriteRule ^(.*)\&(.*)$ $1\%26$2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^wiki/(.+)$ ./wiki/index.php?title=$1 [PT,L,QSA]
Two hints:
If you're not in a hosted environment (= if it's your own server and you can modify the virtual hosts, not only the .htaccess files), try to use the RewriteLog directive: it helps you to track down such problems:
# Trace:
# (!) file gets big quickly, remove in prod environments:
RewriteLog "/web/logs/mywebsite.rewrite.log"
RewriteLogLevel 9
RewriteEngine On
My favorite tool to check for regexp:
http://www.quanetic.com/Regex (don't forget to choose ereg(POSIX) instead of preg(PCRE)!)
My ticket to HostGator resolved the issue, albeit un-helpfully. I was hoping for a single .htaccess solution, rather than a double .htaccess redirect/rewrite. However, here's my solution.
/:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/$
RewriteRule ^.*$ http://www.example.com/wiki/
/wiki/:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?title=$1 [L,QSA]
I tried different solutions and what worked for me was changing .htaccess in mediawiki subfolder to
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wikifolder/index.php [L]
</IfModule>