mod_rewrite: args lost - apache

I want to do a easy(?) rewriting.
Here is my .htaccess:
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/batiments-[0-9]+/?$
RewriteRule ^batiments-([0-9]+)/?$ a_batiments.php?e=$1
I want this rewriting: http://xyz.com/batiments-123 ==> http://xyz.com/a_batiments?e=123
I obtain only the address: http://xyz.com/a_batiments, without the argument.
In the rewrite log, I see a line containing a split:
192.168.0.2 -(very long line suppressed) (3) split uri=a_batiments.php?e=123 -> uri=a_batiments.php, args=e=123
I understand the split is useful for the matching, but the args is never put back in the address. Why? What to do?

Try adding the [R] flag to the RewriteRule. That way the rewrite results in a HTTP redirection being sent to the client.

Related

htaccess rewrites causing side affects

I have the following in my .htaccess file.
RewriteEngine On
RewriteRule ^([^/]+)?$ /member/profile.php?user=$1 [L]
RewriteRule ^assets(/.*)?$ /member/assets$1 [L]
RewriteRule ^images(/.*)?$ /member/images$1 [L]
RewriteRule ^php(/.*)?$ /member/php$1 [L]
The desired effect is:
https://example.com/username -> https://example.com/member/profile.php?user=$1
This works, however, the issue is there are 2 undesired outcomes happening from this.
First: https://example.com and https://example.com/ return 404 errors but https://example.com/index.php works just fine.
Second: https://example.com/username/ ends up forwarding to https://example/member/php/?user=username and returning a 404 error.
I have also attempted
DirectoryIndex index.htm index.html index.php
But this seems to have no effect on the issue
My actual desired end result would look more like:
https://example.com -> https://example.com/index.php
https://example.com/ -> https://example.com/index.php
https://example.com/username -> https://example.com/member/profile.php?user=$1
https://example.com/username/ -> https://example.com/member/profile.php?user=$1
RewriteRule ^([^/]+)?$ /member/profile.php?user=$1 [L]
First: https://example.com and https://example.com/ return 404 errors but https://domain.name/index.php works just fine.
The first rule will catch the request (since it allows an empty URL-path) and will rewrite the request to /member/profile.php?user=. So, presumably it is your script that is triggering the 404?
In fact, it looks like you are missing a slash before ? to match an optional trailing slash (ie. /username or /username/), rather than making the entire pattern optional! ie. ^([^/]+)/?$
You would also need the NS (nosubreq) flag to prevent the subrequest by mod_dir for the DirectoryIndex (ie. index.php) also being caught by this rule. However, this rule is arguably matching too much, as it will also catch direct requests for index.php (and any other files you might have in the root). So, maybe you need to be more restrictive in what characters are allowed in usernames? For example, at a minimum, exclude dots (as well as slashes) with ^([^/.]+)/?$? Or allow only letters and numbers (and underscores), eg. ^(\w+)/?$. (\w is a shorthand character class that represents [0-9a-zA-Z_].)
Note that the first rule will also match assets, images and php - so these are valid usernames. Is that intentional? You could reverse the rules so this does not happen, but you would need to ensure that there are no usernames that match these strings.
NB: https://example.com and https://example.com/ are exactly the same request. (The browser effectively appends the slash after the hostname to make a valid HTTP request. See the following question on the Webmasters stack: Is trailing slash automagically added on click of home page URL in browser?)
Second: https://example.com/username/ ends up forwarding to https://example.com/member/php/?user=username and returning a 404 error.
I can't see how that would happen with the directives as posted. None of your rules would match /username/ (with a trailing slash), unless the username is "assets", "images" or "php" - but that still wouldn't result in the stated rewrite? However, /username/ would result in a 404 because nothing actually happens to rewrite the URL!
Your rules should perhaps be written like this instead:
RewriteEngine On
RewriteRule ^(\w+)/?$ member/profile.php?user=$1 [L]
RewriteRule ^assets(/.*) member/assets$1 [L]
RewriteRule ^images(/.*) member/images$1 [L]
RewriteRule ^php(/.*) member/php$1 [L]
The capturing subpattern in rules 2, 3 and 4 is not optional, so I've removed the trailing ?$.
I've also removed the slash prefix on the substitution string, to make it a relative file-path.
Which could also be further "simplified" to:
RewriteEngine On
RewriteBase /member
RewriteRule ^(\w+)/?$ profile.php?user=$1 [L]
RewriteRule ^((assets|images|php)/.*) $1 [L]

.htaccess rewrite rule ignoring string, multiple GET variables in url

I am trying to make .htaccess rewrite rule to map 4 different get variables and exclude one string. String is unchangeable ie. always will remain same.
Current url is:
/car.php?make=bmw&model=z4&year=2006&color=black_metallic
It should be like this:
car/bmw-z4-2006-black_metallic-for-sale
This is I've done so far
RewriteRule ^car/^([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$ car.php?make=$1&model=$2&year=$3&color=$4
Now I need to ignore string -for-sale at the end of the pretty url.
Any help greatly appreciated!
Try this
RewriteRule ^car/([^/-]+)-([^/-]+)-([^/-]+)-([^/-]+)/?$ car.php?make=$1&model=$2&year=$3&color=$4 [QSA,NC,L]
Your delimiter is hyphen not forward slash hence your RewriteRule should also handle that accordingly:
Options -MultiViews
RewriteEngine On
RewriteRule ^car/^([^-]+)-([^-]+)-([^-]+)-([^-]+) car.php?make=$1&model=$2&year=$3&color=$4 [L,QSA,NC]
Option MultiViews is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So /file can be in URL but it will serve /file.php.

I Cannot get rewriterule to work

I'm using VertrigoServ 2.27 on my laptop (localhost:8080).
Rewrite module is enabled and i tested it with alice.html and bob.html example
(http://stackoverflow.com/questions/6944521/url-rewriting-on-localhost)
and it works with .htacces inside www-subfolder. And I also put rubbish text inside .htaccess and
I got error from Apcheserver so rewrite mod is running and I cab use rules.
here is the rule: (inside /www/folder1/.htaccess)
Options +FollowSymLinks
RewriteEngine On
RewriteRule /(.*) /index.php?disp=$1 [QSA,L]
So when I put this url into browser my index page loaded ok.
http://localhost:8080/folder1/index.php
And the problem is here: When I request login via index.page(login page) and send url to localhost
server by cliking send-button
the url changed localhost:8080/login, it should be localhost:8080/folder1/login
how I can keep subfolder name in url?
and I want convert urls like this: www.best-food-of-the-usa.com/index.php?operation=top&state=arizona&
city=mesa&limit=10
to like this: www.best-food-of-the-usa.com/arizona/mesa/top10.html
Any help is appreciated. Thanks
\Jose
RewriteRule is behaving as the docs say.
From RewriteRule Directive Apache Docs
What is matched?
In VirtualHost context, The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string (e.g. "/app1/index.html").
In Directory and htaccess context, the Pattern will initially be matched against the filesystem path, after removing the prefix that lead the server to the current RewriteRule (e.g. "app1/index.html" or "index.html" depending on where the directives are defined).
If you wish to match against the hostname, port, or query string, use a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or %{QUERY_STRING} variables respectively.
So, when in Directory and htaccess context the prefix /www/folder1/ will be removed. Also remember when matching with RewriteRule in Directory and htaccess context, the pattern will never begin with /.
So, your RewriteRule Should be:
Options +FollowSymLinks
RewriteEngine On
RewriteRule (.*) /index.php?disp=$1 [QSA,L]

mod_rewrite this - multiple conditions or can I just pass all vars over together?

Due to a reverse proxy setup I'm having to pass an extra query var which the proxy can't using mod_rewrite. The proxy is at /search however I'm using /find on all pages as a mod_rewrite to /search to pas the query var s=gsacollection.
See example:
# Direct link to search which passes collection var
# eg http://www.domain.com/find
RewriteRule ^find$ /search?s=gsacollection [NC]
#Rewrite all query vars
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^find(.*)$ /search?%1 [NC,L]
I'm trying to capture multiple variables for mod_rewrite that are being sent. The issue is I don't always know which ones are being sent over. This is an attempt to blanket capture them. Suggestions?
I want to pass all the query strings after /find? to /search?
EG here are some sample URIs coming in:
find?q=test&sort=date:D:L:d1&num=10&s=gsacollection&l=en&start=10
find?q=tfsa&sort=date:D:L:d1&num=10&s=gsacollection&l=en&filter=0
find?q=tfsa&filter=0&num=10&s=gsacollection&l=en&sort=date%3AD%3AS%3Ad1
If a blanket capture won't work then I will have to look at setting up multiple RewriteCond rules, wondering if there's a way I can combine these in a way I can pass vars from each condition to build the rewrite rule (eg group)?
# Grab everything after /find and replace with /search if these query vars exist
RewriteCond %{QUERY_STRING} q=(.*) [AND]
RewriteCond %{QUERY_STRING} s=(.*)
RewriteRule ^find(.*)$ /search$1
Try using this code in your .htaccess file under $DOCUMENT_ROOT:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteOptions MaxRedirects=10
RewriteRule ^find/?$ search?s=gsacollection [QSA,L,NC]
Make sure you don't have any other conflicting mod_rewrite rule here. QSA flag will make sure to append all query parameters to merge with s=gsacollection parameter.

Apache Rewrite with Multiple Parameters

I need to rewrite the following types of URLs:
http://www.gocruise.co.uk/fusion/detailline3.pl?lineid=13&sid=6924&ccid=Fred+Olsen
into:
http://www.gocruise.co.uk/fred-olsen
using an Apache RewriteRule. I have been trying to get to grips with these rewrites as quick as i can but have run out of time. Any help will be much appreciated.
(the main bit im struggling with is how to manage the multiple parameters)
You probably want it the other way round: A request of /fred-olsen comes in, and you want to redirect the user to the longer URL. This is pretty simple:
# in the Server Configuration or VHost Configuration:
RewriteRule ^/fred-olsen$ /fusion/detailline3.pl?lineid=13&sid=6924&ccid=Fred+Olsen [R=301,L]
or:
# in the .htaccess file of the DocumentRoot
RewriteRule ^fred-olsen$ fusion/detailline3.pl?lineid=13&sid=6924&ccid=Fred+Olsen [R=301,L]
Unless lineid and sid are always going to be the same values, or they're not important to the code, I don't think it's going to work. Typically, url rewrites include all the parameters, so you'd end up with something like http://www.gocruise.co.uk/13/6924/fred-olsen
Alright, the following rules should do what you're asking. The other two parameters will be sent in the querystring. The only other way would be to add them into the URL, which it doesn't seem like that is what you want.
# http://www.gocruise.co.uk/fusion/detailline3.pl?lineid=13&sid=6924&ccid=Fred+Olsen
# redirects to ->
# http://www.gocruise.co.uk/Fred-Olsen?lineid=13&sid=6924
RewriteEngine On
RewriteCond %{REQUEST_URI} /fusion/detailline3.pl
RewriteCond %{QUERY_STRING} (.*)&ccid=(\w*)\+(\w*)$
RewriteRule (.*) /%2-%3?%1 [L,R=301]