URL rewrite - parameter is empty - regex

I'm struggling to get a simple URL rewrite in my htaccess file to work. It looks like this:
RewriteRule ^getbars/([A-Za-z\d,]+)?$ getbars.php?guid=$1 [NC,L]
The idea is to redirect URLs such as /getbars/519f1dec603f9 to /getbars.php?guid=519f1dec603f9
For some reason, however, the guid parameter is empty when I try to get it in getbars.php
However, if I change it to
RewriteRule ^bars/([A-Za-z\d,]+)?$ getbars.php?guid=$1 [NC,L]
and load /bars/519f1dec603f9 in my browser instead, it seems to work OK.
What am I doing wrong?

Because the content negociation is enabled on your server (combined to PATH_INFO feature here)? If this is the case, the content negociation automatically "rewrites" getbars/* to getbars.php, before reading rewriting rules.
=> Can you try to add Options -MultiViews in your .htaccess?

Related

.htaccess URL rewrite issue with query parameters

I have a .htaccess rule that goes like this
RewriteRule ^account/(.*) myaccount.php?p=$1 [NC,L]
This works fine for URLs like https://www.example.com/account/abcd.
However, now I want to pass query parameters to this URL, something like https://www.example.com/account/abcd?ab=1&cd=2.
Can't figure out the exact .htaccess rule that can accommodate this.
Any pointers?
Use:
RewriteRule ^account/(.*) myaccount.php?p=$1 [QSA,NC,L]
With QSA:
QSA|qsappend
When the replacement URI contains a query string, the
default behavior of RewriteRule is to discard the existing query
string, and replace it with the newly generated one. Using the [QSA]
flag causes the query strings to be combined.
http://httpd.apache.org/docs/current/rewrite/flags.html

htaccess redirect from top to subdirectory

I have a web server with the following (simplified) layout:
/
www/ # will hold html and PHP files (web content)
doc/ # some documentation
lib/ # some libraries
I would like to use htaccess to "redirect" every request to www.mydomain.com/page to www.mydomain.com/www/page.php.
I have tried the following:
Options +FollowSymlinks
RewriteEngine On
RewriteRule ^(.*)$ www/$1.php
But it produces a 500 Internal Server Error.
For debugging purposes, I created a www/test.php page which echoes every GET variable, and I modified my .htaccess:
RewriteRule ^(.*)$ www/test.php?page=$1
just to check whether I'm matching the right things.
The expected behaviour when performing a request against www.mydomain.com/somepage would be page=somepage, instead I get page=www/get.php.
Why this behaviour? How can I accomplish what I need?
You have to exclude the path you are rewriting to :
RewriteRule ^((?!www).*)$ www/test.php?page=$1 [NC,L]
otherwise you will get an infinite loop error because www/test.php also matches the rewrite pattern (.*)

301 redirect directory with query parameters

I'd like to redirect everything in /bar/ to a new subdomain but still pass in any query parametes from the original URL. E.g
Original URL examples:
http://www.foo.com/bar/
http://www.foo.com/bar/index.php
http://www.foo.com/bar/index.html
http://www.foo.com/bar/test.php?id=123&utm_source=google
Should redirect to:
http://bar.foo.com/
http://bar.foo.com/
http://bar.foo.com/
http://bar.foo.com/?id=123&utm_source=google
This is what I currently have:
RewriteEngine On
RewriteRule ^bar/?(.*)$ https://bar.foo.com/? [R=301,L]
However, it doesn't pass in the query parameters I need in the 4th example above. I know the ? prevents query parameters being passed in so this will most likely need to be removed I assume but not sure what to replace it with?
Cheers
Add a new rule like this:
RewriteEngine On
RewriteRule ^bar(/|$) https://bar.foo.com/ [NC,R=301,L]
QUERY_STRING will automatically be carried over to target URI.
Make sure there is no trailing ? in the target URI which strips existing query string.

Yet another mod_rewrite query -- Cannot rewrite to pretty url and keep query strings

I'm literally at the end of my tether with this. I've researched many other questions and answers on stackoverflow but still can't find the solution i need. I'm starting to think what i want to do is not possible.
So... the problem is this. I want to turn the following:
e.g.
www.mydomain.com/visa-information/country.php?country={COUNTRY-NAME}&passport={PASSPORT-NAME}
To the following pretty url:
www.mydomain.com/visa-information/{COUNTRY-NAME}-visa-for-{PASSPORT-NAME}-citizens/
I have a partially successful rule in my htacces file as so:
RewriteRule ^/visa-information/([A-Za-z-]+)-visa-for-([A-Za-z-]+)-citizens/?$ visa-information/country.php?country=$1&passport=$2 [NC]
which works fine and does what i want if i enter the url into the browser address bar, but the real problem i'm having is getting it to re-direct to the pretty url via a form i have on pretty much every page of the site.
I've tried various re-direct rules like the one below:
RewriteCond %{QUERY_STRING} country=([A-Za-z-]+)&passport=([A-Za-z-]+) [NC]
RewriteRule visa-information/country.php visa-information/%1-visa-for-%2-citizens/? [R,NC,L]
But no luck. I've also tried adding the QSA flag to the above re-direct rule, but it just ends up with an endless loop.
I have tried using a location php re-direct header at the top of the country.php page to re-direct after form submission like so:
if(isset($_GET['country']) && isset($_GET['passport'])) {
header("Location: " . $dir . "/visa-information/" . $currentCountry . "-visa-for-" . $currentPassport . "-citizens/");
exit();
}
I was expecting the above to work like entering the pretty url directly into the browser works, but it doesn't, just gives me a 404 error.
Any help is greatly appreciated.
Thanks
Jordash
EDIT
My local directory structure is as follows:
/webserver/mydomain.com/visa-information/etc...
On the live server it will be:
mydomain.com/visa-information/etc..
As i am using an Apache Alias on my local machine i have set RewriteBase as:
RewriteBase /webserver/mydomain.com/
I currently have the following set of RewriteRules adapted from what anubhava gave me:
RewriteCond %{REQUEST_URI} visa-information/country.php [NC]
RewriteCond %{QUERY_STRING} country=([A-Za-z-]+)&passport=([A-Za-z-]+) [NC]
RewriteRule visa-information/ visa-information/%1-visa-for-%2-citizens/? [R=301,L,QSA]
# internal redirect from pretty URL to old URL
RewriteRule ^visa-information/([A-Za-z-]+)-visa-for-([A-Za-z-]+)-citizens/?$ visa-information/country.php?country=$1&passport=$2 [NC,L]
This currently gives me an endless re-direct loop, both when entering the pretty url in the browser bar, and when using my form, however if i disable the top 3 rules then i find i can enter the pretty url into the address bar and the rewrite works, but not from the form submission of course.
I really don't know what i'm doing wrong. Why is there an endless loop?
Not sure how first rule is working for you since RewriteRule doesn't match leading slash in .htaccess. Also to redirect old url to pretty URL you need to use THE_REQUEST variable that represents original request received by Apache from your browser. Replace your code with this:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
# external redirect from old URL to pretty URL
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+visa-information/country\.php\?country=([^\s&]+)&passport=([^\s&]+)\s [NC]
RewriteRule ^ /visa-information/%1-visa-for-%2-citizens/? [R=301,L]
# internal redirect from pretty URL to old URL
RewriteRule ^visa-information/([a-z-]+)-visa-for-([a-z-]+)-citizens/?$ /visa-information/country.php?country=$1&passport=$2 [NC,L,QSA]
Looks like the issue was actually with my php form and not the mod_Rewrite rules. The form "action" was pointing to the same form page (as in $SERVER['PHP_SELF']) which works fine without the rewrite rules, but causes an endless loop when they are activated.
I simply made a search_action.php page and then redirect the form there using a php header to the pretty url:
header("Location: " . $dir . "/visa-information/" . $currentCountry . "-visa-for-" . $currentPassport . "-citizens/");
exit();
The mod_rewrite rule I had originally works fine and now the user can get to the desired page with the pretty url from the form or by tyoing directly into the browser address bar.
I'm not sure it's actually possible to action a form to the same page whilst rewriting the query string, without using an intermediary action page from the form, or Javascript. I'm sure many of the more experienced programmers will have known this already, but not me unfortunately.

RewriteCond %{QUERY_STRING} in mod_rewrite (dynamic to static URL) not working

As I have encountered very luck with managing to get querystrings to redirect correctly previously just passing querystring parameters, and the over-arching advice across this site and webmasterworld for querystring redirection seems to be "deal with it as a RewriteCond querystring", I'm trying to use the following type rule for a set of about 10 URLs.
Example URL:
http://www.example.org/training_book.asp?sInstance=1&EventID=139
What I have so far:
RewriteCond %{QUERY_STRING} ^training_book.asp\?sInstance=1&EventID=139
RewriteRule /clean-landing-url/ [NC,R=301,L]
So, what I want to happen is
http://www.site.org/training_book.asp?sInstance=1&EventID=139 301> http://www.site.org/clean-landing-url
but instead what is happening is this:
http://www.site.org/training_book.asp?sInstance=1&EventID=139 301> http://www.site.org/training_book.asp/?sInstance=1&EventID=139
It's appending a forward slash just before the querystring, and then resolving the full URL (obviously, 404ing.)
What am I missing? Is it a regex issue with the actual %{QUERY_STRING} parameter?
Thanks in advance!
EDIT -
Here's where I am so far.
Based upon the advice from #TerryE below, I've tried implementing the following rule.
I have a set of URLs with the following parameters:
http://www.example.org/training_book.asp?sInstance=1&EventID=139
http://www.example.org/training_book.asp?sInstance=2&EventID=256
http://www.example.org/training_book.asp?sInstance=5&EventID=188
etc.
which need to redirect to
http://www.example.org/en/clean-landing-url-one
http://www.example.org/en/clean-landing-url-two
http://www.example.org/en/clean-landing-url-three
etc.
This is the exact structure of the htaccess file I have currently, including the full examples of the "simple" redirects which are presently working fine (note - http://example.com > http://www.example.com redirects enforced in httpd.conf)
#301 match top level pages
RewriteCond %{HTTP_HOST} ^example\.org [NC]
RewriteRule ^/faq.asp /en/faqs/ [NC,R=301,L]
All URLs in this block are of this type. All these URLs work perfectly.
#Redirect all old dead PDF links to English homepage.
RewriteRule ^/AR08-09.pdf /en/ [NC,R=301,L]
All URLs in this block are of this type. All these URLs work perfectly.
The problem is here: I still can't get the URLs of the below type to redirect. Based upon advice from #TerryE, I attempted to change the syntax as below. The below block does not function correctly.
#301 event course pages
RewriteCond %{QUERY_STRING} sInstance=1EventID=139$
RewriteRule ^training_book\.asp$ /en/clean-landing-url-one? [NC,R=301,L]
The output of this is
http://staging.example.org/training_book.asp/?sInstance=1&EventID=139
(this is currently applying to staging.example.org, will apply to example.org)
(I had "hidden" some of the actual syntax by changing it to event_book from training_book in the initial question, but I've changed it back to be as real as possible.)
The the documentation. QUERY_STRING contains the request content after the ?. Your condition regexp should never match. This makes more sense:
RewriteCond %{QUERY_STRING} ^sInstance=1&EventID=139$
RewriteRule ^event_book\.asp$ /clean-landing-url/ [NC,R=301,L]
The forward slash is caused by a different Apache filter (DirectorySlash).