I've created a .htaccess file, and can get the server to serve me a custom 404 page. However, when i try and do a re-write, it doesn't work.
The htaccess file is located in the root directory.
RewriteEngine On
RewriteRule /htaccessTest/index.php /htaccessTest/phpinfo.php
ErrorDocument 404 /htaccessTest/errors/404_message.php
I'm not sure as to why this isn't working. I've checked phpinfo, and under Apache2, it states that mod_rewrite has been loaded.
I'm really stumped here. Not sure what's going on!
Any help would be great!
Update 1
As per what was highlighted below, i found that it still didn't work! I've made some changes, and now all I get is the 404 error message, unless I navigate to the index page.
Here are the changes:
ErrorDocument 404 /htaccessTest/errors/404_message.php
RewriteEngine On
RewriteRule ^htaccessTest/test\.php$ /htaccessTest/phpinfo\.php$ [L,NC]
And i access it using the url:
localhost/htaccessTest/test.php
(ignore the lack of http://, I've removed so that it didn't think it was a link).
Any further ideas?
Thanks
Try your rule without leading slash:
ErrorDocument 404 /htaccessTest/errors/404_message.php
RewriteEngine On
RewriteRule ^htaccessTest/index\.php$ /htaccessTest/phpinfo.php [L,NC]
Better to use line start/end anchors to avoid matching unexpected text in an URI.
dot needs to be escaped in a regex which otherwise matches any character.
.htaccess is per directory directive and Apache strips the current directory path (thus leading slash) from RewriteRule URI pattern.
Finally found the answer after hacking around with it.
It seems to be the first part of the Rewrite.
There is a difference with the first and second section that I didn't realise, which is that the URL sort of "resets" when using Rewrite.
This is explained easier by giving you the now re-worked example.
Original:
RewriteRule ^htaccessTest/test\.php$ /htaccessTest/phpinfo\.php$ [L,NC]
New:
RewriteRule ^test.php /htaccessTest/phpinfo.php
As you can see, the first part references htaccessTest. You don't need this part, as the url was "already in" this file structure. Your url being: "localhost/htaccessTest/test.php"
The second part stays roughly the same, I just removed the Regex stuff and the [L,NC]. The [L, NC] will probably come in handy later, but for simplicity sake I removed it.
The result is this:
ErrorDocument 404 /htaccessTest/errors/404_message.php
RewriteEngine On
RewriteRule ^test.php /htaccessTest/phpinfo.php
Thanks for the help guys! (Especially #anubhava)
Related
I'm having a terrible time and not sure if I'm overthinking it. I'm trying to create a rest API in php (may not matter). I want to have the uri in the format /api/research/data/2020. I created the directory "research" but nothing below that. In the htaccess file, I have
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^/api/research/data/$ /api/research/index.php [NC,L]
I keep getting results that /api/research/ does not exist (it's true, it doesn't). I have tried to be literal and I have tried various pattern matching. I have googled around and tried a lot of things but nothing seems to be getting me what I need.
Main question: does /api/research/ need to exist? Does /api/research/data/ ? Or if not, what might I be doing wrong?
Thank you!
UPDATE May 26, 2020: I finally got this working:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^mobile/list/?$ RestController.php?view=all [nc,qsa]
RewriteRule ^mobile/list/([0-9])+/? RestController.php?view=single&id=$1 [nc,qsa]
1) The main issue I was having was starting off with ^/ instead of just ^. As soon as I made that change, it cleared right up. I do NOT need to create any of these directories.
2) The .htaccess file needs to be at the public_html level. I had it in a subdirectory trying to match the target.
I would recommend to rewrite using wildcards and then filter the endpoints of the API in PHP:
# .htaccess
RewriteEngine On
RewriteRule ^(.*)/(.*)/?$ index.php [nc,qsa]
this is going to be a silly question I guess but I don't see what is going on here. I want to match a certain set of URIs via a regex in an .htaccess file.
I want the following
All files that don't contain a .
all files ending on .htm / .html
all files ending on .php
So:
^[^.]+$
works to match all files with no dot in the URI.
\.html?$
matches all .html / .htm files
(^[^.]+$)|(\.html?$)
seems to work combining both
(^[^.]+$)|(\.html?$)|(\.php$)
fails to combine things with the match files ending on php case. test.jpg for example matches now while it should not.
I must be missing something obvious.
What is it? Thanks.
Update: here is the entire context I was using:
### REWRITE RULES ###
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (^[^.]+$)|(\.html?$)|(\.php$) bootstrap.php [L,QSA]
bootstrap.php contains:
echo "testing bootstrap";
Querying a non existing .jpg
http://localhost/test.jpg
gives me this output:
testing bootstrap
...
Update 2:
After testing the first answer below I found that using the simple:
RewriteRule \.php$ bootstrap.php [L,QSA]
fails in the same way as the above. It matches test.jpg. There is nothing crazy in the server configuration or .htaccess file though... This is all there is in the .htaccess file except what I posted already:
AddType application/x-httpd-php .html
AddType application/x-httpd-php .xml
DirectoryIndex index.php
ErrorDocument 404 /errors/404.php
Answer: (Couldn't anwer my own question for 8 more hours...)
Thanks everyone for helping me out.
Special thanks to #mario who helped me solve this by his comment below.
It was a silly question indeed. Here is what was happening:
rewrite.log:
strip per-dir prefix: D:/Web_Root/test.jpg -> test.jpg
applying pattern '\.php$' to uri 'test.jpg'
pass through D:/Web_Root/test.jpg
strip per-dir prefix: D:/Web_Root/errors/404.php -> errors/404.php
applying pattern '\.php$' to uri 'errors/404.php'
RewriteCond: input='D:/Web_Root/errors/404.php' pattern='!-d' => matched
rewrite 'errors/404.php' -> 'bootstrap.php'
...
So the problem was that my 404 document ended on *.php which was why *.jpg matched for the not found file. Ah Bats, I would have searched this one for a long time...
So this does it:
RewriteRule ([^4]?[^0]?[^4]\.php) bootstrap.php [L,QSA]
Well, the complete question's answer is:
RewriteRule (^[^.]+$)|(\.html?$)|([^4]?[^0]?[^4]\.php) bootstrap.php [L,QSA]
Again: Thanks people.
[Ok, this was not the specific solution here, but I'll make it a faux answer.]
When mod_rewrite rules go wrong, it sometimes helps to enable the RewriteLog. It needs to be configured in the httpd.conf or VirtualHost section and thus is a bit effort. But there Apache will list the order and processing actions it performs and the URL. This can be helpful to see if the regex is understood by Apache and does behave as it should.
Note that it can sometimes remain empty - if the actual error source are Alias and Redirect rules or even FileMatch sections. In this case the error.log or even just the access.log might contain some hints however.
If all fails, you might have luck with temporarily enabling Nanoweb instead of Apache. It comes with a similar mod_rewrite implementation, which however uses PHPs preg_match PCRE backend. (Not telling why I know that.)
okay, so it looks like your rewrite IS working...you can see your "testing bootstrap" message. That "cannot modify header" warning is not related. That means you are trying to do something like session_start() or header() or something after you already output something (probably that 'testing bootstrap' message)
Does this work for you?
(^[^.]+$)|\.(html?$|php$)
*Edit:
I misunderstood what you were trying to do. What about this:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} ^[^.]+$ [OR]
RewriteCond %{REQUEST_FILENAME} ^.*\.(html?|php)$
RewriteRule ^(.*)$ bootstrap.php [L,QSA]
I've been working on a script for debugging mod_rewrite, and when testing their regex system I've had some strange results. I'm wondering if this is normal behavior for the mod_rewrite regex engine or if some part in my code is causing it.
Requested URL: http://myurl.com/path/to/something
.htaccess has: RewriteRule to where
Using my debugging system, the following is what happens when that RewriteRule is used:
path/to/something -> where/to/something
Shouldn't it be path/where/something???
Here's the full .htaccess file
RewriteEngine On
RewriteBase /ModRewriteTester
RewriteRule .* - [E=ORIG:$0]
RewriteRule to where
RewriteRule .* - [E=MODD:$0]
RewriteRule .* index.php
Then I've got a php script that's reading in the environmental variables $_SERVER['REDIRECT_ORIG'] and $_SERVER['REDIRECT_MODD'], that's where I'm getting the previously stated paths.
If anyone knows a better way to explicitly show how mod_rewrite's regex engine works I'm open to it. The initial question still stands though...
Your rule:
RewriteRule to where
...will rewrite a URL that matches to and replace it with the URL representing what would be a request to /where. It's possible in certain circumstances for mod_rewrite to try and re-add what Apache believes to be PATH_INFO, which could create a situation like the following:
path/to/somewhere -> PATH_INFO = /to/somewhere
path/to/somewhere -> /where
(append PATH_INFO) -> /where/to/somewhere
To check if this is the case in your scenario, you can add the DPI flag to the RewriteRule to discard the PATH_INFO if it exists. This would look like this:
RewriteRule to where [DPI]
In this case, you would end up with just the URL /where. If you wanted to replace to with where while retaining the rest of the URL, you would need a rule more like this:
RewriteRule (.*?/)?to(/.*)? $1where$2
As far as debugging your rule set goes, if you have access to the Apache configuration you're much better off using the RewriteLog directive with a sufficiently high RewriteLogLevel. If you don't have access to the configuration, you're pretty much limited to doing something similar to what you're trying to do now.
I've got a really quirky issue going on with ExpressionEngine. I've got a live test site here.
Essentially, if you attempt to comment on the index's 'Question of the Day,' you get a proper redirect, but the comment never gets to the database.
If I remove my .htaccess and set the site's index page in my control panel to index.php, then all is well. But with the .htaccess and index.php removed, things go haywire.
Here are the comments of my .htaccess file:
RewriteEngine on
RewriteCond $1 ^(weblog|member|search|site|rss|search|contact|show|commentary|include|about|blog|tags|preview|P[0-9]{2,8}) [NC]
RewriteRule ^(.*)$ /skad/index.php?/$1 [L]
Any tips to troubleshoot this or ideas where I could be going wrong? If it's any help, you can see a screenshot of my folder structure.
Thanks so much for any answers or simply help that you can give.
More: Also, here are headers for a successful post on a blog entry and a failing post on the index.
Update: I did recently find something else strange. With identical backend settings:backend settings http://droplr.com/1sMXc9+
And identical code:identical code http://droplr.com/1sN09A+
I get http://localhost:8888/skad as one form action and http://skadaddlemedia.com/v2/v2/index.php as the other form action.
At this point, I'm completely lost as to what is going on.
the "?" after index.php in the RewriteRule suggests that you are on a server running PHP as a CGI script and thus requires the "forced query strings", correct? This may be ancillary to the problem in the question, but it can complicate things to have this requirement. Looks like you're hosted at Site5... I have no experience with them but you might try the workarounds suggested here: http://expressionengine.com/wiki/Workaround_for_Forced_Query_Strings/
Try changing [L] to [L,QSA] to see if it helps.
I'm not sure but i think that CI and EE are pretty much the same as to the way the htaccess works so this may help you out. It is by a CI guru named Ethan, can't remember the last name, but he is very active in the CI community. Anyway the way that your HTACCESS file is has really been abandoned the new way to do it is a lot easier and you don't have to state your excluded folders it is the best thing since sliced bread for users of MVC or any frameworks i just love it.
# Customized error messages.
ErrorDocument 404 /index.php
# Set the default handler.
DirectoryIndex index.php
# Various rewrite rules.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
</IfModule>
i can gurentee you that if it is a htaccess issue this bugger will fix it but the bext thing is you dont have to do a thing to it just drop it in and you never have to edit it again i swear by it. so freaking good like fried chicken in the summer yummy!
remember test it first by just dropping it in place of your current one you wont need all that crazy other stuff you got there in yours promise.
In the httpd.conf file I have AllowOverride FileInfo. In the .htaccess file in top level of my webserver with all the other files, I have this:
RewriteEngine On
RewriteRule ^downloads/?$ index.php?page=downloads [L,NC]
But it doesn't work. mywebsite/downloads and mywebsite/downloads/ always give a 404 not found. Any idea why? Thanks. (mywebsite/index.php?page=downloads does work).
And I'm restarting apache every time I change it.
And when I put the code above in httpd.conf, the website won't even load at all, just blank, spinning safari wheel forever.
Its fine if I just do RewriteEngine On, but if I do anything else (RewriteBase, RewriteRule), the web browser spend ages trying to load and finally giving this error:
Safari can’t open the page “http://mk12.gotdns.com/” because the server where this page is located isn’t responding.
Anyone have any idea what's wrong?
EDIT: I'm able to make, for example, css files forbidden with rewrite, and it works, but any rule that goes from downloads to index.php?page=downloads makes the server not respond (see above), it doesn't matter what page, the website won't load at all. Any ideas..?
The best way to debug rewrite rules is to enable rewrite logging so you can see what's going wrong.
It Worked!! I was putting the code in the wrong spot. It was in httpd.conf, but at the end. Move it into <Directory> and its good. Thanks for your help!
EDIT: Also, I found that It won't work if the flags are like this: [L, NC]. It has to be [L,NC] (no spaces).
So the two problems where that it wasn't inside <Directory "/Library/WebServer/Documents">, and there were spaces between the flags. Hopefully this will help someone else in the future.
Have you tired adding a slash in front of the "download" like below
RewriteRule ^/downloads/?$ index.php?page=downloads
EDIT: Try the code below:
RewriteEngine On
RewriteBase /
RewriteRule ^downloads/?$ /index.php?page=downloads
I would try removing the trailing slash and question mark after downloads, and the leading slash before index.php.
RewriteEngine On
RewriteBase /
RewriteRule ^downloads$ index.php?page=downloads.