htaccess - outputting semi-colon's & spaces in the querystring - .htaccess

I'm struggling with .htaccess
The site has the URL
http:/www.example.com/section-1/product640/page.html
Which needs to be redirected to:
http:/www.example.com/section/c/27?dynNav=Type::query%20string;
Note the space and semicolon in the querystring.
My htaccess rule is:
RewriteRule ^section-1/product640/([^/]+)$ /section/c/27?dynNav=Type::query%20string; [L,R=301,NC]
But this returns:
http://www.example.com/section/c/27?dynNav=Type::query0string%3b
I believe the zero in "query0string" is because it's taking the %2 as a variable, which doesn't exist. So the question is, how do I encode the space?
Thanks

Replacing '%20' with '\ ' like this should solve your problem:
RewriteRule ^section-1/product640/([^/]+)$ /section/c/27?dynNav=Type::query\ string; [L,R=302,NC]

Related

htaccess RewriteRule with literal question marks (not query string)

I need to be able to match question marks because there was a translated text encoding mistake, and part of the URL ended up hardcoded with question marks in them. Here's a URL example that I need to rewrite:
https://example.com/Documentation/Product????/index.html
Here is my current rewrite rule. It works when the characters following "Product" are not question marks, but when they are, the rule doesn't apply.
RewriteRule "^Documentation/Product[^/]+/(.*)$" "https://s3.amazonaws.com/company-documentation/Help/Product/$1" [L,NC]
How would I make sure that question marks are considered to be characters too in this rule? I can't expect that only question marks and not the original non-English characters will be in the URL, so I want the rule above to match both question marks and any other character.
I found this topic which seems relevant, but the flags don't help, and the answer doesn't explain how to overcome the problem mentioned in the "Aside".
https://webmasters.stackexchange.com/questions/107259/url-path-with-encoded-question-mark-results-in-incorrect-redirect-when-copied-to
https://example.com/Documentation/Product????/index.html
You say it's "not a query string", but actually that is exactly what it is. And that is why you can't match it with the RewriteRule pattern. The above URL is split as follows:
URL-path: /Documentation/Product (matched by the RewriteRule pattern)
Query string: ???/index.html (note 3 ? - the first one starts the query string)
To match the query string you'll need an additional RewriteCond directive that checks against the QUERY_STRING server variable.
For example, to match the above URL, you would need to do something like:
RewriteCond %{QUERY_STRING} ^\?*/index\.html
RewriteRule ^Documentation/Product$ https://s3.amazonaws.com/company-documentation/Help/Product/index.html [NC,R,L]
This matches any number of erroneous ? at the start of the query string.
I've added the R (redirect) flag. Your directive (without the R flag) would trigger an external redirect anyway (because you specifying an absolute URL in the substitution), but it is far better to be explicit here. This is also a temporary (302) redirect. If this should be permanent (301) then change it to R=301, but only once you have confirmed that it's working OK (301s are cached hard by the browser so can make testing problematic).
UPDATE:
...so I want the rule above to match both question marks and any other character.
Only if there are question marks in the URL will there be a query string, so I think it is advisable to keep these two rules separate.
If there could be any erroneous characters at the start of the query string and if you want to capture the end part of the URL (like you are doing in your original directive, eg. index.html) then you can modify the above to read:
RewriteCond %{QUERY_STRING} /(.*)$
RewriteRule ^Documentation/Product$ https://s3.amazonaws.com/company-documentation/Help/Product/%1 [NC,R,L]
Note the %1 (as opposed to $1) backreference in the substitution string. This is a backreference to the captured group in the last matched CondPattern (ie. /(.*)$).
You can follow this with your existing directive (but remember to include the R flag) for more "normal" URLs that don't contain a ? (ie. query string).
NB: Surrounding the arguments in double quotes are entirely optional in this example. They are only required if you have unescaped spaces in the pattern or substitution arguments.
In summary
# Redirect URLs of the form:
# "/Documentation/Product?<anything#1>/<anything#2>"
RewriteCond %{QUERY_STRING} /(.*)$
RewriteRule ^Documentation/Product$ https://s3.amazonaws.com/company-documentation/Help/Product/%1 [NC,R,L]
# Redirect URL-paths of the form (no query string):
# "/Documentation/Product<something>/<anything>"
RewriteRule ^Documentation/Product[^/]+/(.*) https://s3.amazonaws.com/company-documentation/Help/Product/$1 [NC,R,L]

RewriteRule and Hash

I have a webpage which has ugly urls like this
DOMAINNAME/gallery.php#filter=.filtername
I want them to look like this
DOMAINNAME/artwork/filtername/
I've tried this in my .htaccess file
RewriteRule ^artwork/([^.]+)/ gallery.php#filter=.$1 [NE]
But this doesn't do the trick. It just goes to DOMAINNAME/artwork/
If you are adding # in URL then you must do a full redirect since # part is only interpreted in browser:
RewriteRule ^artwork/([^./]+)/?$ /gallery.php#filter=.$1 [L,NE,NC,R=302]
I just tried this in my environment and it seems, Apache swallows everything after and including #, when it does an internal rewrite.This happens no matter, whether you use flag NE or not.
So the only solution seems to be using a regular query string, e.g.
RewriteRule ^artwork/([^.]+)/ gallery.php?filter=.$1 [L]
or separate the filter with a slash
RewriteRule ^artwork/([^.]+)/ gallery.php/filter=.$1 [L]

How to get only first part of string before slash in URL (HTACCESS)

To achieve this URL pattern www.example.com/abc-xyz/mno-pqr/123.html
I am using following in htaccess:
rewriterule ^(.*)/(.*)/(.*).html$ index.php?lyrics_id=$3&singer=$1&song=$2 [L]
Below are example URL which are causing duplicate title error for my site.
www.example.com/abc-xyz/WHATEVER/ANOTHER_WHATEVER/mno-pqr/283.html
www.example.com/abc-xyz/I_DONT_WANT_THIS_PART/mno-pqr/283.html
www.example.com/abc-xyz/HELP_ME/REMOVE/mno-pqr/283.html
www.example.com/abc-xyz/HELP/REMOVE/THIS/PART/mno-pqr/283.html
I want to get only first part before slash in singer part.
I want exactly this,
www.example.com/abc-xyz/mno-pqr/123.html
but not other letters or between abc-xyz and mno-pqr.
Help me writing htaccess.
It seems that you only want to match the url if it consists of exactly 3 parts. You can do this, by matching everything but the delimiter in each part. The delimiter here is /.
Also please note that . matches EVERY CHARACTER. If you want to match the period character instead, you have to escape it (\.).
RewriteRule ^([^/]*)/([^/]*)/([^/]*)\.html$ /index.php?lyrics_id=$3&singer=$1&song=$2 [L]
That works for my 3 parameters rule but how to add 301 redirect to all
those URL which have more than 3 parts?
If the extra parts are always between the first part and the 2nd part of the url, like you showed above, you have to redirect the user with a 301 header:
RewriteRule ^([^/]*)/.*/([^/]*)/([^/]*)\.html$ /$1/$2/$3.html [R=301,L]

mod_rewrite .htaccess with %20 translate to -

I have been reading about .htaccess files for a couple of hours now and I think I'm starting to get the idea but I still need some help. I found various answers around SO but still unsure how to do this.
As far as I understand you write a rule for each page extension you want to 'prettify', so if you have something.php , anotherpage.php, thispage.php etc and they are expecting(will receive??) arguments, each needs its own rule. Is this correct?
The site I want to change has urls like this,
maindomain.com/sue.php?r=word1%20word2
and at least one page with two arguments
maindomain.com/kevin.php?r=place%20name&c=person%20name
So what I would like to make is
maindomain.com/sue/word1-word2/
maindomain.com/kevin/place-name/person-name/
Keeping this .php page and making it look like the directory. Most of the tutorials I have read deal with how to remove the .php page to which the argument is passed. But I want to keep it.
the problem I am forseeing is that all of the .php?r=parts of the url are the same ie sue.php?r=, kevin.php?r= and the .htaccess decides which URL to change based on the filename and then omits it. If I want to keep the file name will I have to change the ?r=
so that it is individual? I hope this make sense. So far I have this, but I'm sure it won't work.
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^([a-zA-Z0-9]+)/$1.php?r=$1
RewriteRule ^([a-zA-Z0-9]+)/$1.php?r=$1&c=$1
And I think I have to add ([^-]*) this in some part or some way so that it detects the %20 part of the URL, but then how do I convert it to -. Also, how are my $_GET functions going to work??
I hope my question makes sense
You're missing a space somewhere in those rules, but I think you've got the right idea in making 2 separate rules. The harder problem is converting all the - to spaces. Let's start with the conversion to GET variables:
# check that the "sue.php" actually exists:
RewriteCond %{REQUEST_URI} ^/([a-zA-Z0-9]+)/([^/]+)/?$
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule ^([a-zA-Z0-9]+)/([^/]+)/?$ /$1.php?r=$2 [L,QSA]
RewriteCond %{REQUEST_URI} ^/([a-zA-Z0-9]+)/([^/]+)/([^/]+)/?$
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule ^([a-zA-Z0-9]+)/([^/]+)/([^/]+)/?$ /$1.php?r=$2&c=$3 [L,QSA]
Those will take a URI that looks like /sue/blah/ and:
Extract the sue part
Check that /document_root/sue.php actually exists
rewrite /sue/blah/ to /sue.php?r=blah
Same thing applies to 2 word URI's
Something like /kevin/foo/bar/:
Extract the kevin part
Check that /document_root/kevin.php actually exists
3 rewrite /kevin/foo/bar/ to /kevin.php?r=foo&c=bar
Now, to get rid of the "-" and change them to spaces:
RewriteCond %{QUERY_STRING} ^(.*)(c|r)=([^&]+)-(.*)$
RewriteRule ^(.*)$ /$1?%1%2=%3\ %4 [L]
This looks a little messy but the condition matches the query string, looks for a c= or r= in the query string, matches against a - in the value of a c= or r=, then rewrites the query string to replace the - with a (note that the space gets encoded as a %20). This will remove all the - instances in the values of the GET parameters c and r and replace them with a space.

htaccess rewrite problem

RewriteRule ^a/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)/([0-9]+)$
/var/www/vhosts/mydomin.com/httpdocs/search.php?searchtext=$1&locationtext=$2&page=$3
[QSA]
I want to pass http://www.mydomain.com/searchtext=jobs&locationtext=A.G.sBosRoad&page=1,
but I'm getting an error. I'm guessing this error is due to the . characters. What modification is needed in htaccess to allow read . characters?
Your regex for locationpart doesn't accept dots, as you say. Change the character class to include \.:
RewriteRule ^a/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_\.-]+)/([0-9]+)$ /var/www/vhosts/mydomin.com/httpdocs/search.php?searchtext=$1&locationtext=$2&page=$3 [QSA]
or, more generally, if your script doesn't have problems with it:
RewriteRule ^a/([^/]*)/([^/]*)/(\d+)$ /var/www/vhosts/mydomin.com/httpdocs/search.php?searchtext=$1&locationtext=$2&page=$3 [QSA]
That will accept any string without slashes for locationtext and searchtext, even the empty string, and still redirect to your search script.
.htcaccess only accepts files that end in a proper extension such as .html or .php.

Resources