I'm working on some rewrite rules, and for some reason a regexp I'm not expecting to pass (and does pass not on any of my regexp testers) is passing in mod_rewrite.
The URL in question is:
http://url.com/api/projects.json?division=aa
And the rewrite rule is:
RewriteEngine On
RewriteBase /
RewriteRule ^api\/([^.?#/%\s]+)\.([^#?\s]+)$ api.php?type=$1&format=$2 [NC,L]
Because the second capture is immediately followed by $ I'd expect that URL to fail because of the query string, but it seems to accept just fine and pass the two parameters to GET.
Any thoughts?
Note: Query String
The Pattern will not be matched
against the query string. Instead, you
must use a RewriteCond with the
%{QUERY_STRING} variable.
Snip from the bottom of the docs
Related
Id like to have the following URL(s) redirect to the same URL just without the ?
For example:
https://www.example.com/this-is-static?numbersletterssymbols
goes to
https://www.example.com/this-is-static
"numbersletterssymbols" can be anything
Id like this to be a 301 , using htaccess ( apache )
I came across the following, however, the variable seems to be in parentheses
RewriteCond %{QUERY_STRING} ^product=(.*)$
RewriteRule ^test.php$ %1/? [R=301,L]
Any insight is appreciated
To remove the query string (any query string) from any URL you could do the following using mod_rewrite, near the top of your .htaccess file:
RewriteEngine On
RewriteCond %{QUERY_STRING} .
RewriteRule ^ %{REQUEST_URI} [QSD,R=301,L]
The condition (RewriteCond directive) simply asserts that there is a query string consisting of at least 1 character (determined by the regex . - a single dot).
The QSD (Query String Discard) flag removes the original query string from the redirected response. The QSD flag requires Apache 2.4 (which you are most probably using). The method used on earlier versions of Apache, as in your example, is to append a ? to the susbstitution string (essentially an empty query string).
Note that you should test first with a 302 (temporary) redirect to avoid potential caching issues.
however, the variable seems to be in parentheses
The parentheses in the regex simply creates a "capturing group" which can be referenced later with a backreference. eg. In your example, the value of the product URL parameter is referenced in the RewriteRule substitution string using the %1 backreference in order to redirect to the value of the URL parameter. This is very different to what you are trying to do and is arguably a security issue. eg. It would redirect a request for /test.php?product=https://malicious.com to https://malicious.com/, allowing a potential hacker to relay traffic via your site.
UPDATE: is it possible to make this work only for when the URL begins with "this-is-static" (for example)
Yes, the RewriteRule pattern (1st argument) matches the URL-path, less the slash prefix. For example:
RewriteCond %{QUERY_STRING} .
RewriteRule ^this-is-static %{REQUEST_URI} [QSD,R=301,L]
Matches all URLs that start with /this-is-static.
I am trying to turn an ugly url with parameters into a nice url. At the moment I have:
http://myasite.com/index.php?reg=uk&area=london&id=16
Which I would like to have like so:
http://myasite.com/uk/london/16
I have tried using this .htaccess:
RewriteEngine On
RewriteRule ^/?$/?$ index.php?reg=$1&area=london&id=$2 [L,QSA]
Which I got from an online generator however when I run the page with /uk/16 in the url it just crashes.
What am I doing wrong?
In reply to Chris's reply below. All of these are optional.
Structure of url is like so:
myasite.com
myasite.com/uk (if set, This will always be text and always 2 chars long)
myasite.com/uk/london (if set, This will always be text, this will be any char length )
myasite.com/uk/london/16 (if set, This will always be integer and any char length)
Your regex is incorrect. Your ^/?$/?$ says the request can have 2 /s only, each is optional. You also aren't using any capture groups so $1 and $2 have no context. Here's a regex that would work for your provided example:
^/(uk)/(\d+)$
If uk can be any 2 lowercase letters you could use:
^/([a-z]{2})/(\d+)$
You can use regex101 to see how your regexs will function.
https://regex101.com/r/VyJE9d/1 (your rule)
https://regex101.com/r/VyJE9d/2
The right side of the page gives explanations.
As a rewrite rule:
RewriteEngine On
RewriteRule ^/([a-z]{2})/(\d+)$ index.php?reg=$1&id=$2 [L,QSA]
All you need to use is this in your .htaccess file:
RewriteEngine On
RewriteRule ^([^/]*)/([^/]*)/([^/]*)$ /index.php?reg=$1&area=$2&id=$3 [L]
This will leave you with your desired URL of: http://myasite.com/uk/london/16. Just make sure you clear your cache before testing this.
RewriteEngine On
RewriteRule ^([a-zA-Z0-9_-]+)/([0-9]+)/?$ index.php?reg=$1&id=$2 [L,QSA]
We are rewriting $1/$2/ and $1/$2 to index.php?reg=$1&id=$2
I am having a little trouble with apache mod_rewrite, I need to be able to modify (append) a variable name to something else depending the regex in another variable in the URL:
https://localhost:85/fight?shoes=baby.firstlove&type=textype&awesome=23481234
By this i mean that if "awesome=" is 234[8,7]1234, shoes=baby.firstlove should become shoes=baby.firstlovefirsttry, OR if awesome=234[1,2]1234, then shoes=baby.firstlove, should become shoes=baby.firstlovesecondtry .
My rewrites rule are something like this (trying to capture awesome=23411234 or awesome=23425678):
RewriteCond %{QUERY_STRING} shoes=(.+)\&awesome=(\b234(1|2)\d{4}\b)
RewriteRule ^(.*)$ http://localhost:85/fight?shoes=baby.firstloveactual&subscriber=%2 [P]
But they are not changing the "shoes=" variable content as expected.
The URL remains the same:
http://localhost:85/fight?shoes=baby.firstlove&type=textype&awesome=23481234
Please what am I doing wrong?
RewriteCond %{QUERY_STRING} shoes=(.*)\&awesome=(\b234(1|2)\d{4}\b)
Your regex does not match your example URL:
https://localhost:85/fight?shoes=baby.firstlove&type=textype&awesome=23481234
You have an 8 where your regex is expecting a 1 or 2. However, if you need to match one of a series of characters then you should use a character class (eg. [12]) rather than a parenthesised/capturing group. Also, I'm not sure what you are trying to do with the word boundaries (ie. \b)? What is the intention of using the P flag? Presumably you need to externally redirect?
But also, your code sample does not seem to match your textual description of the problem?
if "awesome=" is 234[8,7]1234, shoes=baby.firstlove should become shoes=baby.firstlovefirsttry
Try the following (assuming "1234" is the literal string, rather than any 4 digits):
RewriteCond %{QUERY_STRING} shoes=.+&awesome=(234[87]1234)
RewriteRule ^/?fight http://localhost:85/fight?shoes=baby.firstloveactual&subscriber=%1 [R,L]
You've used https in your example URLs, but http in your rewrite?
I am currently working on a Rewrite Rule where I need to append certain text into the redirected URL.
The URL that that I want to type into the browser is
http://testwebsite.com/search/?q=SEARCH_STRING
I want this redirected to
http://testwebsite.com/search/SEARCH_STRING/
Basically the SEARCH_STRING needs to be taken from infront of ?= and put after /search/
The current rule that I have is malfunctioning:
RewriteRule ^.*\/search\/\?q=(.*) /#!/search/$1/ [R=301,L,NC,NE]
Any idea how I can fix this ?
You need to capture the query string in a RewriteCond, it's not part of the string your RewriteRule implicitly matches against
RewriteCond %{QUERY_STRING} ^q=(.+)
RewriteRule ^/search/$ /search/%1? [R=301,L,NC,NE]
The trailing ? deletes the existing query string.
I try to do a 301 redirect with .htaccess.
The issue:
/?view=products&id=12345 -> /8831
there is no relation between the old and the new address.
For some reason
Redirect 301 /?view=products&id=12345 /8831
doesn't work. If I remove the question mark, it works without question mark.
i tried also:
RewriteCond %{QUERY_STRING} view=products&id=12345
RewriteRule .*$ /8831 [L,R=301]
but it redirects me to /8831?view=products&id=12345, which is not good for me. I don't need the query string in the new url-
RewriteCond %{QUERY_STRING} view=products&id=12345
RewriteRule .*$ /8831? [L,R=301]
The ending ? will prevent the original query parameters from being appended, unless you also give the [QSA] flag again.
From the manual:
Note: Query String
The Pattern will not be matched against the query string. Instead, you must use a RewriteCond with the %{QUERY_STRING} variable. You can, however, create URLs in the substitution string, containing a query string part. Simply use a question mark inside the substitution string, to indicate that the following text should be re-injected into the query string. When you want to erase an existing query string, end the substitution string with just a question mark. To combine a new query string with an old one, use the [QSA] flag.