htaccess regex help - regex

Hi
I need some help (the solution and the explanation please)
In my application there is a php page called page.php which gets a parameter page by GET and delivers content accordingly.
What I want is:
Make this page the entry point, catch all and redirect it to page.php.
Use the URI as the page parameter value. (domain.com/string will become domain.com/page.php?page=string)
When I used ^(.*)$ page.php?page=$! it was working, except it also manipulated every resource that was called (js, css, images, etc..)
Thanks

You need to add RewriteCond statements to avoid any existing files.
RewriteEngine on
RewriteBase /
# Allow files that exists to bypass rewrites
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ page.php?page=$1 [L,QSA]

Related

.htaccess change wordpress hompage but keep the link

example.com/wp
or
example.com/wp/
<- This is what homepage link used to be like and I'm trying to keep it this way.
But I want the server to serve some static page from another subfolder as a front page (but to keep all the other wp contents at the same places)
My static page (several of them tbh) are stored in root/subf1/
I was able to redirect to the desired subfolder, but the path also shows up in the URL.
Is it possible to change example.com/subf1 to example/wp?
Here's my current htaccess. Maybe I need to create another one in a static page folder?
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteCond %{REQUEST_URI} !^/subf1/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /test/page/$1
RewriteCond %{HTTP_HOST} ^(www.)?example.com$
RewriteRule ^(/)?$ /subf1/index.html [L]
</IfModule>
RedirectMatch "^/wp$" "https://example.com/subf1/"
Thank you a lot for your time
RedirectMatch does only "external redirections", so you probably want internal redirection with a RewriteRule (without the R flag).
So instead of RedirectMatch try:
RewriteRule ^wp$ https://example.com/subf1/ [L]
PS: Generally it is good to go for redirect/redirectmatch instead of going for mod_rewrite, but if you are already using mod_rewrite directives it will be less confusing to stick to it and not mix direcitves from one or the other.

.htaccess rewriterule "loop"

I currently have this line in my .htaccess file making URLs "pretty" for pages.
RewriteRule ^([A-Za-z0-9-]+)/$ /directory/?type=page&title=$1 [L]
However, I sometimes have sub-pages (/page/sub-page/sub-page/), yet this line only supports one level (/page/).
How can I alter this code to support sub-pages (any amount) and make the title variable something like:
&title=page/sub-page/sub-page
/ being the seperator.
I know that this will definitely be a huge help:
RewriteRule loop in .htaccess not working
However, due to my lack of knowledge with regex and mod-rewrite, I don't know how to make it properly work with what I already have.
Try this:
AllowEncodedSlashes On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^([/a-z0-9-]+)/?$ /directory/?type=page&title=$1 [NC,B,L]
Don't worry about A-Z because of the NC flag.
After doing some regex research, and doing some testing, it seems like this is the answer to my problem:
RewriteRule ^(([a-zA-Z0-9-]+)/(([a-zA-Z0-9-]+)\/?)+)$ /directory/?type=page&title=$1 [L]
I altered my previous code and allowed support for multiple sub-directories. Then I placed it into a capture group and placed that data into the title variable.

Cannot undertand the mixed outcomes of an .htaccess re-write rule / regex

I have a simple website comprised of one page with a div that gets populated with ajax content based on the links the user selects. This site is running on an Apache server with an .htaccess file in the domain's root directory. Requests to www.mydomain.com are directed to scripts/index.php while requests for dynamic content (but not resource files) are directed to the same .php script with the requested content passed as a parameter (e.g., www.mydomain.com/myProject will be rewritten as scripts/index.php?dynContent=myProject).
My rewrite rules are below and for the most part they are performing those described tasks properly; however, I've encountered some URLs that do not match the second condition even though I would expect them to -- though this is the first time I've had to write rules for an .htaccess file so I don't really know what I'm talking about... A good example of a URL that fails the second condition is www.mydomain.com/about, but I've encountered many more just by testing random words/letters.
Can you tell me why www.mydomain.com/about fails the second condition? Also, if there is a more elegant way to achieve the objectives I described above, I would love to learn about it. Thank you!!
RewriteCond %{HTTP_HOST} ^(www.)?mydomain.com$ [NC]
RewriteRule ^(/)?$ scripts/index.php [L]
RewriteCond %{REQUEST_URI} .*[^index.php|.css|.js|.jpg|.html|.swf]$
RewriteRule .* scripts/index.php?dynContent=$1 [L]
This is because regex in your 2nd rules is incorrect.
Change your code to:
RewriteCond %{HTTP_HOST} ^(www\.)?mydomain\.com$ [NC]
RewriteRule ^(/)?$ scripts/index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !\.(php|css|js|jpe?g|html|swf)$
RewriteRule ^(.*)$ scripts/index.php?dynContent=$1 [L]

How to force mod_rewrite to skip real files

I have an application that routes all requests through index.php.
Here's my setup:
I access the application at http://www.example.com/sample/
On the filesystem, the application sits in /home/chris/www/sample/
The web-accessible directory of the application lives at /home/chris/www/sample/app/web.
The DocumentRoot is set to /home/chris/www
/home/chris/www/sample/.htaccess is configured as follows:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/sample/(.+)$
RewriteCond %{DOCUMENT_ROOT}/sample/app/web/%1 -f
RewriteRule ^/sample/(.*)$ %{DOCUMENT_ROOT}/sample/app/web/%1 [L]
RewriteRule ^(.+)$ index.php?ws_page=$1 [L,NC,QSA]
I've tried multiple configurations, but haven't figured out why I keep getting 404's on calls to "real" files.
Sample 404:
`http://www.example.com/sample/_css/960/reset.css`
(which I want to have rewritten to /home/chris/www/sample/app/web/_css/960/reset.css)
EDIT
I have already tried
RewriteCond %{REQUEST_URI} !-f
RewriteCond %{REQUEST_URI} !-d
RewriteCond %{REQUEST_URI} !-l
and they did not work, because the %{REQUEST_URI} prefix does not match the filesystem prefix of these files.
EDIT 2
To clarify, I want requests of the form
`http://www.example.com/sample/foo/bar`
to be rewritten to the filesystem object /home/chris/www/sample/app/web/foo/bar, but only if that filesystem object exists.
One of the biggest bear-pits in reading the mod_rewrite documentation in the difference in behaviour in a system (that this the main and vhost configs that apache reads on start-up and those directive processes in a per-directory context. See the Per-directory Rewrites subsection of the RewriteRule documentation for further details.
When using the rewrite engine in .htaccess files the per-directory prefix (which always is the same for a specific directory) is automatically removed for the RewriteRule pattern matching and automatically added after any relative (not starting with a slash or protocol name) substitution encounters the end of a rule set. See the RewriteBase directive for more information regarding what prefix will be added back to relative substitions.
and later
The removed prefix always ends with a slash, meaning the matching occurs against a string which never has a leading slash. Therefore, a Pattern with ^/ never matches in per-directory context. What you've done is to code around this.
Incidentally, this is why it is always safer to specify a RewriteBase, as the engine gets this wrong without this.
BTW, this second quote can be wrong because the prefix add-back occurs at the then of the rule set execution, and if you have a successful rule which is to a different relative branch (that is the target starts with a /) but without the [L] flag set, then the engine falls through to any subsequent rules with a leading / set. Most confusing, so my general advice is never rely on fall-through rules. Always force an immediate internal or external redirect on a successful substitution in a per-directory context as the engine has this and a couple of other bugs in this fall-through processing.
Have your code like this:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /sample
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+sample/(.+)\s [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond /home/chris/www/sample/app/web/%1 -f [NC]
RewriteRule ^ /sample/app/web/%1 [L]
# If the request is not for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
# If the request is not for a valid symlink
RewriteCond %{REQUEST_FILENAME} !-l
# If the request is not for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ index.php?page=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
These two rules will skip files (-f) and directories (-d) which actually exist.
Mad bonus points to whomever can explain to me why my the EOS anchor ($) was to blame for the RewriteRule not working.
I wound up with this:
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/sample/(.+)
RewriteCond %{DOCUMENT_ROOT}/sample/app/web/%1 -f
RewriteRule ^(.*)$ app/web/$1 [L,NC,QSA]
RewriteCond %{REQUEST_URI} !(^/sample/app/web)
RewriteRule ^(.+)$ index.php?ws_page=$1 [L,NC,QSA]
Many thanks to all who helped me diagnose this weirdness.

.htaccess rewrite rule preventing infinite loop

I have a directory named dollars that contains a file index.php. I would like for the url http://localhost/dollars/foo to translate to dollars/index.php?dollars=foo. This is the .htaccess file that I currently have in the dollars directorty:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !^index\.php
RewriteRule ^(.+)$ index.php?dollars=$1 [L]
The idea being that any request other than a request to index.php should use the RewriteRule.
However, this does not work.
I've been looking for a while trying to figure out how to create the redirect I want, but I don't even know if I'm on the right track. Regex were never my thing. Thanks for any help!
A often-used solution for rewrites is to just check that the path being requested doesn't point to an actual file/directory, and rewrite it if it doesn't - since the rewritten URL will then point to an actual file, no loop occurs.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Amber's answer should get things working for you, but I wanted to address what was going wrong in your specific case. You had the right idea, but %{REQUEST_FILENAME} actually ends up being a fully qualified path here, so your regular expression should check for index.php at the end, not the beginning.
Consequently, you should find that this will work more like you expect:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !index\.php$
RewriteRule ^(.+)$ index.php?dollars=$1
Swapping out the RewriteConds for those that Amber mentioned would be less problematic if you added other things to that directory, though, so I'd recommend using that in place of this anyway.