Configuring Apache to not rewrite URLs for FILE + SLASH - apache

I have this problem where all URLs like context/path/file/anything/that/follows becomes context/path/file.php/anything/that/follows or context/path/file.xml/anything/that/follows.
I have the following rewrite rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^service/(.*)$ service.php?xyz=1 [L,QSA]
which should map any URL starting with service/... to service.php. Now, problem is, if an XML file named service.xml is in the same folder as the .htaccess, the URLs are mapped to that file instead. If a PHP file exists, they go to the PHP file. The XML file takes precedence, i.e. if there is both an XML file and a PHP file with the name service.* in the directory, the XML file gets chosen.
I have PHP 5.3, Apache 2.x, on Mac OS X 10.7 (Lion). This problem did not previously occur when I had OS X 10.6, So there must be some changes in the configurations provided by Apple. I just cannot figure out what.
Is there a way I could disable this functoinality?
Or am I entirely off-track, and donig something stupid?
BTW, this does not relate to mod_rewrite, as enabling or disabling it, or removing the rewrite rule from the .htaccess changes anything. The URL service/my/parameter still points to service.xml/my/parameter, even if mod_rewrite is disabled.
For now, I have just taken the query string out of the url, and parsed it manually inside the PHP file. But I know that is not the right way to do this.

This seems to be the MultiViews option enabled.
Try to add Options -MultiViews in the <Directory> section (or .htaccess).

Related

Apache 2.4 .htaccess friendly URL rewrite

Having some issues understanding the .htaccess file and getting it to work properly. .htaccess is recognized....i entered plain test at the top and got the internal server error. And it appears mod-rewrite is working...because I downloaded a test php file and it works.
I am using Apache 2.4.23 with no php pages
However i cant seem to get this to work right.
I am trying to take this url
http://example.com/ProjectTest/index.shtml?dynContent=Content1
and rewrite it like this
http://example.com/ProjectTest/Content1
I am also trying to do this generically across the site since ?dynContent=whatever will be a constant.....and trying to keep the same path.....like the below example
Change this
http://example.com/ProjectTest/ProjectFolder/index.shtml?dynContent=Content1
to this
http://example.com/ProjectTest/ProjectFolder/Content1
I am not very good with the .htaccess files
UPDATE: Ok...I got this to work.....not really sure why it works....but when I type in the test-dev/ProjectTest/apples or test-dev/ProjectTest/oranges it calls up the appropriate content.
This is what I used
RewriteRule ^ProjectTest/([^/\.]+)/?$ ProjectTest/index.shtml?dynContent=$1 [L]
and then I rewrote it to be this and now it works for any directory
RewriteRule ^(.*)/([^/\.]+)/?$ $1/index.shtml?dynContent=$2 [L]
Try this:
RewriteEngine On
RewriteCond %{QUERY_STRING} ^dynContent=(.+)$
RewriteRule ^/(.+)+/index.shtml $1/%1 [PT]
This requires mod_rewrite to be activated. The value of the bracket in dynContent=(.+) is stored in %1 and the bracket's value in ^/(.+)+/index.shtml is stored in $1. Both together creates your target path http://example.com/ProjectTest/ProjectFolder/Content1

apache configuration for react-router with browserHistory and baseName subdirectory

My application is in a subdirectory of the main web site. I have implemented basename and browserHistory and put the following recommended apache rewrite code into .htaccess in the app folder:
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.html [L]
This recommended apache rewrite works to return browserHistory URLs to the application index.html. For some reason (see below), it does not find the "style.css" and "brundle.js" that are EMBEDDED in the index page HTML. The only thing that I can see that I have different in the example .htaccess file is that I have a RewriteBase value of "/react_librivox_search" because my application is in that subfolder of the site.
RewriteBase /react_librivox_search
I have tested using various different beginning and ending slashes for paths and files in .htaccess, and the problem is not that.
The problem seems to be that the react application is setting a GET value for the files that includes a part of the PATH variable that is supposedly only a part of the react-router definition:
<Route path="/book/:id" component={BookDataDisplay}/>
Note that the additional path segment "/book/" is being appended to the base URL, and when files are not found in THAT directory (which does not really exist), the server returns "index.html" for the missing files, which accounts for the mime-type error for the librivox_search.css file and the "<" error for the bundle.js file.
The stylesheet http://jstest.dd:8083/react_librivox_search/book/librivox_search.css was not loaded because its MIME type, “text/html”, is not “text/css”. librivox_search.css (embedded in index.html)
SyntaxError: expected expression, got '<' bundle.js (embedded in index.html)
The same unexpected addition of "book" to the URL is at work here as well. Neither of the embedded index.html files is in that subdirectory. But I want to maintain that "book" in the path, since it identifies what KIND of data is being passed to the route . . . which distinquishes it from other kinds of data. I just do not want to have it sent to the SERVER (but perhaps that cannot be avoided), since the actual index.html embedded files are not there.
I suppose rewriting "/react_librivox_search/book" as "/react_librivxo_search" might work, but it seems to be a hacky way to go about it. And I don't want to have to put duplicate bundle.js files in multiple directories (that works, but
what a maintenance nightmare THAT would be, and no doubt bad practice).
Or is it recommended to put a separate .htaccess in a REAL "book" subfolder that returns "librivox_search.css" and "bundle.js" (in the base directory) depending on the file request?

htaccess redirect without .php extension

I recently changed a directory /old_dir/ to be /new_dir/ using this:
RedirectMatch 301 /old_dir/(.*) /new_dir/$1
Which seems to be working perfect for the url:
http://www.mysite.com/old_dir/test.php?var=xxxx
goes to
http://www.mysite.com/new_dir/test.php?var=xxxx
where test.php is the filename. But in many places I use:
http://www.mysite.com/old_dir/test?var=xxxx
which comes up with:
The requested URL /old_dir/test was not found on this server.
not using the .php extension takes advantage of some sort of apache plugin that knows it's a php handler, which seemingly messes up redirect because it says it doesn't exist now.
I am not sure how to fix this issue.
Edit: All the solutions are for this special case, but note that i have about 1000 other files that may not be php, or named the same.
For right now I just made a symbolic link in the old_dir with the name "test" to point to the new_dir's test.php. But I am still looking for a non-specific solution that includes my scenario.
Have you ever tried using mod_rewrite?
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^([^/]+)/([^/]+)$ $1/$2.php [QSA]
RewriteRule ^old_dir/([^/]+)/$ new_dir/$1.php [QSA]

mod_rewrite rules for existing files

I am defining mod_rewrite rule that will rewrite all requests to my /application.php if requested file not exists, and won't do any rewriting otherwise. It is simple:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule .* application.php [PT]
There is only one problem with the code. Assume I have foo.html file. Then requests like:
http://example.com/foo.html/some/other/string
will fall with 404 error.
Why?
will fall with 404 error. Why?
Because that URL doesn't exist. It's looking for the file string in the folder /foo.html/some/other and it's not there.
The behaviour that you want to exploit using the http://example.com/foo.html/some/other/string URL structure - treating the first entry as a file name, and the rest as a parameter to it - is called "pathinfo". It has nothing to do with mod_rewrite, but will be available if you enable the following in your Apache configuration:
AcceptPathInfo On
it looks like that setting is currently turned to "off" for you.
If you enable it, the part after the file name will be available to foo.html - in PHP, it would be in the
$_SERVER["PATH_INFO"]
variable.
Because this method doesn't require the rewrite module to be active, this is sometimes called "the poor man's mod_rewrite" - it works fine, but isn't quite as pretty as flexible as "real" rewriting.

How to prevent Apache / mod_rewrite from treating path as file with same name

I'm using WAMP Server, mostly configured as-is out of the box. I'm having trouble getting mod_rewrite to behave as expected locally (everything works fine on a production server).
I have a PHP file located at:
/ajax/graphs/get-graph.php
The way this file is normally invoked is via a bootstrap file loaded by
/index.php
I have a .htaccess file at the root with the following rules:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php [L]
So, basically, when my app requests via AJAX a call to /ajax/graphs/get-graph/it should be directed to /index.php.
The problem is, Apache/mod_rewrite sees the request path and loads /ajax/graphs/get-graph.php directly.
How do I prevent Apache from assuming that /ajax/graphs/get-graph/ is a valid file because a php file of the same name exists at that location?
It sounds like you've fallen into the trap of content negotiation ;-) As explained in the Apache documentation, there is an option called MultiViews which, when enabled, causes Apache to basically convert nonexistent directory names into their corresponding filenames.
The effect of MultiViews is as follows: if the server receives a request for /some/dir/foo, if /some/dir has MultiViews enabled, and /some/dir/foo does not exist, then the server reads the directory looking for files named foo.*, and effectively fakes up a type map which names all those files...
The intent is that you can have several versions of a file in different formats or languages, like
/some/dir
- foo.en.gif
- foo.en.png
- foo.en.jpg
- foo.fr.gif
- foo.fr.png
- foo.fr.jpg
and Apache will choose the best one based on the preferences provided by the browser.
To fix it, all you should need to do is add the directive
Options -MultiViews
in a <Directory> or <Location> block corresponding to /ajax/graphs. Or, if you don't have access to the main server configuration, you can put it in /ajax/graphs/.htaccess.