How can I display the resulting path when using mod_rewrite? - php

I am having a heck of a time trying to get an apache mod_rewrite rule to work. The thing that is making the process the most difficult is that I have no way of knowing what the final output string is. I continue to get 404 pages, but that doesn't tell me much except that I did something wrong. Is there some method of echoing out the final rewrite rather than redirecting me to a 404?
. . . And just in case someone feels like helping me out with my original problem, I'm trying to make it so that anyone who goes to /server/root/to/folder/public_html/ gets redirected to /server/root/to/folder/public_html/destinationFolder/. Below is one of the hundreds of variations that I've tried:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond $1 !^(favicon\.ico|assets)
RewriteRule ^public_html/(.*) destinationFolder/$1 [L]
</IfModule>

You are using system paths. Apache mod_rewrite only works with URLs (PT flag is implied in .htaccess files), that's your first error.
public_html is normally the root directory. For example: http://mydomain.com
Then, a complete rule set could be something like this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^(favicon\.ico|assets) [NC]
RewriteRule ^(.*)/?$ DestinationFolder/$1 [L]
Maps silently
http://mydomain.com/Anything
To:
http://mydomain.com/DestinationFolder/Anything
Except when anything is file favicon.ico or folder /assets
For permanent redirection, replace [L] with [R=301,L]
This is just an example. The rules and parameters have to be modified to meet the real requirements.

Related

htaccess and pretty links

I'm trying to write a simple blog which is working fine untill i get to the pretty links thing.
what i'm looking to do is use URLs like mysite.com/blog/this_post and pass that into the index.html file as a url parameter so index.html?blog=this_post
Been searching everywhere and found a bunch of htaccess code but most didn't work. I did find one solution that tries to work but for some reason isn't doing it correctly. (with and without the Options +FollowSymLinks part)
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^blog/(.*) /blog/index.html?blog=$1
when I use this i get /blog/index.html?blog=index.html in the url instead of keeping the /blog/this_post and porting that into the index.html as expected. Could something on the server be set incorrectly? everything else with the blog is working like a charm but so nothing wrong with the script its just getting the pretty links to work.
Looked at an older site that has wordpress and coppied over that htaccess code but it does that same thing. All the other searches on here and other sites point to the same solution above or the wordpress but for some reason it's passing index.html to the script and not the last url segment "this_post" as expected.
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /blog/
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /blog/index.html [L]
</IfModule>
# END WordPress
what should happen is the user types in
mysite.com/blog/this_post
which remains in the address bar correct? but the htaccess file pulls this_post and passes it as an argument to the index.html script. which is what the examples above should do. why it's changing the address bar to
mysite.com/blog/index.html?blog=index.html
i'm not sure why
side note, since i got this before...yes i'm aware of using the .php extention but .html is a client ask that they're not budging on.
edit-the link for possible duplicate was one I already found and tried to get the current RewriteRule but it's still not working.
The best way is to made something simple like this:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([^/]*)\.html$ index.php?blog=$1 [L]
Options -MultiViews
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
then you can do URL like:
mysite.com/this_post
what is equal to:
mysite.com/index.php?blog=this_post
Like that you can do both calls and will work fine.
Generaly you need first decide how you want your SEO URL to look like and then you need to setup .htaccess regex and rules.
NOTE: you can't use .html for GET calls. You can use .php files for your works and use $_GET['blog'] to pickup your data from URL.
Seem to have found the combo that works, the [NC, L] flag combo keeps giving me a crash error so i left it just [NC]. Having it in the root account directory seems to not work also so i moved into the web directory (public_html) and that works for now.
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^blog/(.*) /blog/index.html?blog=$1 [NC]
Still not sure why the L flag gives me a server crash on the pages or why having it in the root doesn't work but moving it up into the public_html folder does, is it possibly a server configuration problem that i'm overlooking?

what is this line doing in this .htaccess file and do the other lines in this file look safe?

Our site was hacked recently, and is serving files that look like this:
www.example.com/some-spam-name
These paths are redirecting to some spam affiliate page.
There are thousands of them.
I've started investigating, and the first thing I have checked is the .htaccess file:
It looks like this:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^example\.com$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.com$
RewriteRule ^secraksj$ "https\:\/\/example\.karansv\.com\/a\/3845\/RFcFd3FM" [R=301,L]
RewriteOptions inherit
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
The obvious thing that stands out is:
RewriteRule ^secraksj$ "https\:\/\/example\.karansv\.com\/a\/3845\/RFcFd3FM" [R=301,L]
Can someone explain what this is doing, I can see the regex, ^secraksj$ but don't quite understand how this rewrite is operating.
If I remove the line in question from the .htaccess file, do you think the rest of the file looks fairly standard? I'm trying to take things one step at a time, and right now I'm trying to fix the .htaccess file.
I would like to know if I remove this line, if you can see anything else in the .htaccess file that an attacker might be using to exploit the site.
I found this:
My site was hacked, htaccess file compromised, what should it look like?
But the syntax is different in this RewriteRule.
RewriteRule ^secraksj$ "https\:\/\/exampledomain\.karansv\.com\/a\/3845\/RFcFd3FM" [R=301,L]
This redirects requests for example.com/secraksj to https://example.karansv.com/a/3845/RFcFd3FM.
Whilst ^secraksj$ is a "regex", it only matches the literal string "secraksj".
And the preceding RewriteCond directives simply make sure that the redirect only occurs when accessing the example.com host (and no other parked/addon domain).
do you think the rest of the file looks fairly standard?
Yes, except for the RewriteOptions inherit directive. This might be OK, but do you specifically need this? This inherits mod_rewrite directives from any parent config file.
The remainder of the .htaccess file is a standard (WordPress) front controller pattern.
But the syntax is different in this RewriteRule.
The directives in the linked question aren't actually valid, so I wouldn't use those directives as a reference.

Ignoring a subfolder with .htaccess

In my public_html I have 2 Folders, wordpress and tickets. I currently have the /wordpress directory working via mod_rewrite so that the URL's look nice. I'd like to setup an instance of OSTicket, and upon navigating to example.com/tickets to start the configuration, I'm hit with a Wordpress 404 error.
My root .htaccess looks like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_URI} !^/tickets/.*
RewriteRule ^tickets - [L,NC]
RewriteRule ^index\.php$ /wordpress/index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wordpress/index.php [L]
</IfModule>
I also have a .htaccess in the tickets folder, with;
RewriteEngine off
If anyone has some insight or perhaps something I should look into it would be most appreciated, thankyou all kindly.
The condition you have is the opposite of your match. They can't both be right. Drop the condition permanently, and amend the rule to this:
RewriteRule ^tickets(?:$|/) - [L]
That ensures /tickets-foo/ still goes to WordPress and that you're not matching case-insensitively when your filesystem is case-sensitive.
Temporarily rename the tickets dir. Create another one with only an index document in it, content is irrelevant but put something in. Visit example.com/tickets and you should see your aforementioned content.
I'm betting the issue is not in the .htaccess nor WordPress.

Specific redirection in .htaccess does not work

I have a specific problem with my mod_rewrite configuration that I cannot resolve. I am no admin, therefore I'm kindly asking for a collective advice :) Please note - it's not a general question about redirection, but very specific one.
Story
I have a shared hosting with access to FTP and ability to create my own .htaccess files. This shared hosting had plenty of files and directories before I created the website, so logical step for me was to place everything inside new-site folder.
Then I had to create custom rewrite rules so that everything under example.com points to new-site.
CONFIG
So I came up with the following config.
# (...) other rules
# 1. Make sure that /new-site/ is not a duplicated content
RewriteCond %{REQUEST_URI} ^/new-site/
RewriteRule ^/new-site/(.*)$ /$1 [R=301,L]
# 2. Make sure that example.com is internally handled by files in '/new-site'
RewriteCond %{REQUEST_URI} !^/new-site/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /new-site/$1
RESULTS
Rule marked with 2. works fine, my site is accessible as I want. However I didn't want https://example.com/new-site/ to be found on the server by bots and treated by a duplicated content, so I added rule 1..
This rule, however, doesn't seem to have any effect! I looked it up with CURL and request is handled immediately with a 200 status. I'm banging my head against the wall and experimenting with other variants of it, but everything fails.
What I'm after is pretty darn simple:
Make every request to the root domain be handled by website which is stored in /new-site/
Make sure that direct call to https://example.com/new-site/(.*) is redirected with 301 status back to the domain root.
What am I doing wrong?
EDIT
I've noticed that my setup seems to be doing far better if I remove a child .htaccess file under /new-site/ subfolder. I didn't mention it in my original question because there is nothing special about it (just some SEO rewrites).
RewriteEngine on
DirectoryIndex index.php
RewriteRule ^products$ products.php
# (...) similar rewrites
Old answer: RewriteRule does not accept leading slash. Try to change to
RewriteRule ^new-site/(.*)$ /$1 [R=301,L]
Edit:
Version that is provided by you will forward to the cyclic redirection. To avoid it, I think, you can use such .htaccess
RewriteEngine on
RewriteRule ^new-site/ - [R=404,L]
# 2. Make sure that example.com is internally handled by files in '/new-site'
RewriteCond %{REQUEST_URI} !^/new-site/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /new-site/$1 [L]
Direct asking /new-site/* wil receive 404 error, while url exaple.com/* wil be redirected to /new-site
And notice that if there are files with the same name, for example, /r.jpg and /new-site/r.jpg, the last never be achieve
Your first rule never matches because it must not begin with a leading slash.
With RewriteRule, you only need a leading slash if you're directly in httpd.conf or before Apache v2.4 i think.
While you have a good idea, your first rule will cause an infinite redirection loop if it's working. You have to use THE_REQUEST to match direct user request only.
You can put this code in /.htaccess
# 1. Make sure that /new-site/ is not a duplicated content
RewriteCond %{THE_REQUEST} \s/new-site/([^\s]*)\s [NC]
RewriteRule ^ /%1 [R=301,L]
# 2. Make sure that example.com is internally handled by files in '/new-site'
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^((?!new-site/).*)$ /new-site/$1 [L]
Also, you'll have to add this line in /new-site/.htaccess (to avoid automatic override)
RewriteOptions InheritBefore

Making RewriteRule to mock reddit's or Rails?

For fun I want to make a reddit clone in php. I have mostly java experience but know my way around php, if that matters at all. I also have very limited experince with Rails 3 and I believe how rails deals with URLs is also close to how I want to handle it.
So far in a .htaccess I have:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /index.php/$1 [L]
This routes every page to index.php where I parse the URI and handle requests with a switch. I know this isn't scalable in the long run but I want to get off the ground.
My next stepis to add a / automaticly at the end of a URL like localhost/r/all so it becomose localhost/r/all/ I want and have tried to make a RewriteRule like:
RewriteRule ^/?(.+)$ /$1/ [R]
This gives a 500 error. I think it is because it gets stuck in an infinite loop of redirect because /$1/ will equal ^/?(.+). So I need something like:
RewriteRule ^/?(.+)Does not end in a forwardlash$ /$1/ [R]
How can I do this? I see that the ! charecter can be used to denote a condition it should not match, but I am having trouble getting this to work.
Any Advice is appreciated.
EDIT:
getenv("DOCUMENT_ROOT") //gives /var/www
I have /var/www/index.php living, well in /www.
My .htaccess file which I am making these changes to lives in /var.
I have .htaccess in /var because in my httpd.cong I have this:
<Directory /var>
AllowOverride All
</Directory>
I first tried to have it as
<Directory /var/www>
and putting .htaccess in www but it is never read. I know it is not read becuase I put garbage in it and there is no error. But, if I have garbage in it when it is in /var and the Drectory directive specifies /var I get an error.
Try this (untested):
# Turn mod_rewrite on, yada yada yada
RewriteEngine On
RewriteBase /
# We'll want to do the redirect before rewriting anything
# Files obviously don't have a trailing slash, and directories require one - so
# we only need to check if the file exists
# I'm not actually sure if mod_rewrite understands non-capturing groups though
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^/?((?:.+?)[^/])$ http://%{HTTP_HOST}/$1/ [L,R=301]
# Do the rewrite
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.+)$ /index.php/$1 [L]
I get the feeling that the problem with your attempt is likely to be the order of the rules, a missing RewriteCond on the redirect RewriteRule and/or that you didn't put a L flag in the redirect RewriteRule - but the above regexes make me happier than yours do, because they are a little more specific about what they match.
I'm not actually sure if mod_rewrite supports all the regex features I have used above, so if you continue to get an error that might be why - come back here if you do have a problem and I'll look at it more closely.

Categories