Url rewriting - Querystring parsing - regex

I am new to URL rewriting and getting a bit frustrated. I'm using Helicon on the server and have gotten most URLs to re-write correctly.
(I had to remove the '//'s to allow me to submit the questions, but the urls are the standard http:// version)
My last task is to get these:
http://example.com/Object/?page=1
http://example.com/Object/?page=1&pagesize=10
http://example.com/Object/?page=1&pagesize=10&backcolor=red
to
http://example.com/default.aspx?resource=Object&page=1
http://example.com/default.aspx?resource=Object&page=1&pagesize=10
http://example.com/default.aspx?resource=Object&page=1&pagesize=10#backcolor=red
Preferably I'd like one rule to handle all 3 possibilities, but if I need to make 3 rules, one for each, and add a [L] or something at the end that would be ok too. I just can't get the querystring parsing right.
Here is an existing rule I have that works to give you an idea of what I've been doing:
RewriteRule ^/([a-zA-Z0-9]+)(/([a-zA-Z0-9]+)(/([a-zA-Z0-9]+))?)?/?($|\?) /default.aspx?resource=$1&id=$3&option=$5 [L]
It's for a separate example, but the syntax shows what I'm doing.

Does this work for you?
RewriteRule ^\/([^/]*)\/\?(.*)$ /default.aspx?resource=$1&$2 [L]
[Update]
Try this:
RewriteRule ^([^/]*(?=\/)|[^?]*(?=\?)|.*)($|[^\?]*\?(.*)) /default.aspx?resource=$1&$3 [L]

Related

My apache rewrite only works for the first folder level

We have a website where we show clients creative work we have produced for them. We upload raw assets to a path like this:
x.com/clients/clientName/campaignName/size/
I have a PHP script which adds our branding, contact information and other information and pulls in the raw creative (usually a swf object). It is in this directory x.com/clients/index.php and it accepts a query string parameter ?path so it knows where to look for the creative.
I am trying to do an apache rewrite in .htaccess so that our designers can upload directly to the known folder structure but so that when you go to x.com/clients/clientName/campaignName/size/ it should rewrite to x.com/clients/index.php?path=clientName/campaignName/size/
I am currently using the following rewrite rule, which works for the first folder level e.g. x.com/clients/clientName/ does successfully rewrite, but any subsequent folders do not.
RewriteRule ^clients/([^/\.]+)/?$ /clients/index.php?path=$1 [L]
My RegEx's are terrible, so I'm stuck on what to do. Any help appreciated, thank you kindly.
Your regex is only matching urls like clients/xxxxxx/ because your pattern [^/\.]+ means one or many characters except "/" or "."
With your rule, it can't work for other subdirectories.
You can change your rule by this one
RewriteRule ^clients/(.+)$ /clients/index.php?path=$1 [L]
To avoid internal server error (code 500 which means an infinite loop in this case), you can do it this way
RewriteRule ^clients/index\.php$ - [L]
RewriteRule ^clients/(.+)$ /clients/index.php?path=$1 [L]
Is there a special reason you want to use regex? In my opinion you can just catch everything coming after /clients:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^(.*/)?index\.php$ [NC]
RewriteRule ^clients/(.*)$ /clients/index.php?path=$1 [L]
The second line is to prevents redirect loops, because the index.php is also in the folder /clients and this would cause never ending redirects.

.htaccess | Rewrites with pages

So I'm adjusting the URLs on a site I'm working on and I'm having some trouble with a couple of variables being passed in the URL.
mylighting.com/bath-fixture-c-13.html?osCsid=u2qj8o9rvjn0p5pa7p8npuhs54
RewriteRule ^bath-fixture bath-fixture-c-13.html?id=$1
So this Rewrite works perfect as the page that comes up is mylighting.com/bath-fixture
Now unfortunately on that page there are several other items to view and I'm having some trouble with the page variable. I think I have the code correct but every time I try to go to the correct page it doesn't seem to work.
http://mylighting.com/bath-fixture-c-13.html?page=2&id=u0hnumfus6gjhjc45av36663m3
RewriteRule ^bath-fixture/([a-zA-Z0-9]+)$ bath-fixture-c-13.html?page=$1&id=$2
So I thought I had this correct but apparently not. I would like the output to be
mylighting.com/bath-fixture/2 for the second page.
Unfortunately with that code in the .htaccess, every time I input that URL it takes me to the first page of the category and not the second like it should.
It appears that you have misunderstood the format of the RewriteRule. The first one is working by accident.
RewriteCond %{QUERY_STRING} page=([0-9]+)
RewriteRule ^bath-fixture-c-13.html bath-fixture/%1 [R=301,QSA,L]
RewriteRule ^bath-fixture-c-13.html bath-fixture/ [R=301,QSA,L]
The first argument to RewriteRule is the regex to match against the requested URL. The second argument is the URL to send as a Redirect to the user, so they end up at your desired URL instead. Because you want to parse the QUERY_STRING I believe you need to use a RewriteCond. If you are doing this for SEO purposes do not forget to add the [R=301].
http://httpd.apache.org/docs/current/mod/mod_rewrite.html
If you are trying to go the other direction then you need the following.
RewriteRule ^bath-fixture/$ bath-fixture-c-13.html [QSA,L]
RewriteRule ^bath-fixture/([0-9]+) bath-fixture-c-13.html?page=$1 [QSA,L]
If you can clarify your desired inputs and outputs you will get correct answers much more quickly.

Proper regex for .htaccess redirect and prevention of hotlinks

I posted this on Reddit (r/learnprogramming) and someone there PM'd me and told me to come here, so here I am!
I have been trying to learn regex's and I suck at them still. I seriously have difficulty grasping the pattern matching. I am solid in other OOP languages so I figured I would learn regex and it just evades me.
I have downloaded EditPad Pro so I can practice as http://www.regular-expressions.info/tutorial.html suggests. I can get expressions to match bulk text, but I am trying to parse URL's and I keep missing.
Here is what I am trying to do. I am writing my own permalink .htaccess file as a proof of concept study, so I can hopefully use this is in future sites.
I need to return the following dynamic content from a URL:
I need everything other than http:// www.domain.com/ or http:// domain.com/ or domain.com/:
(I am adding a space after http:// because of the limits on new accounts)
http:// www.domain.com/asdjh324hj.jpg
http:// www.domain.com/asa45s.png
http:// www.domain.com/aser24hj.gif/
http:// www.domain.com/wer234dsfa/
http:// www.domain.com/k3kjk4
http:// www.domain.com/k3kasd4/
The matched part will then be appended to:
http:// www.domain.com/some_dir/som_subdir/some_file.php?querystring=$1
But, I don't want any of these urls in the results:
http:// www.domain.com/some_dir/some_file.php
http:// www.domain.com/some_dir/some_subdir/some_file.html
And I need to prevent hotlinking to images in the image_dir:
http:// www.domain.com/image_dir/some_dir/some_subdir/some_image.jpg (or png,gif,etc)
Hotlinked images would be redirected to a page with the passed image as a querystring.
So what RewriteRule regex would I setup to grab this? I understand RewriteRules and the flags, putting matched results into variables, etc, I just can't figure out what regex I should write to grab the actual result.
If this is too complex for RewriteRules, then please let me know as I am struggling here.
Usually I do these in PHP and would start with:
.com/[a-zA-Z0-9-_.]+
([^/]+)/?$
Then do good 'ol substrings and checks. It's hacking it to death and I should be doing better!
I am currently going through the regular-expressions.info tutorials and am making progress, but I keep grabbing the wrong things too.
Thanks for any help you can send my way!
Update: I was able to resolve everything with a ton of help and discussed more here: Mod_Rewrite conditions help for hotlinking but allow local requests
I need everything other than http:// www.domain.com/ or http:// domain.com/ or domain.com/:
RewriteCond %{REQUEST_URI} !^/$
But, I don't want any of these urls in the results:
RewriteCond %{REQUEST_URI} !^/some_dir/
The matched part will then be appended to:
RewriteRule ^(.*)$ /some_dir/som_subdir/some_file.php?querystring=$1 [L]
So in all it should look something like this:
RewriteCond %{REQUEST_URI} !^/$
RewriteCond %{REQUEST_URI} !^/some_dir/
RewriteRule ^(.*)$ /some_dir/som_subdir/some_file.php?querystring=$1 [L]
Which will make it so when you request something like http://www.domain.com/asa45s.html, it will get internally rewritten to some_dir/som_subdir/some_file.php?querystring=asa45s.html. As for the hotlinking bit:
RewriteCond %{REQUEST_URI} ^/image_dir/
RewriteCond %{REQUEST_URI} \.(png|gif|jpe?g|bmp|ico)$ [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?domain.com/
RewriteRule ^(.*)$ /some_dir/som_subdir/some_file.php?querystring=$1 [L]
This checks that first the request is for something in the /image_dir/ directory, then that the requested resource ends with a png/gif/jpeg/bmp/ico extension, then that the HTTP referer [sic] does not start with http://www.domain.com/, https://domain.com/ or whatever combination of the 2. If all those are true, then it rewrites the request to the /some_dir/som_subdir/some_file.php file with the original URI as the querystring parameter.

Need to override previously written rewrite rule

I have some rewrite rules in an htaccess file. I'm still getting into it so theres a few things I'm unsure of.
Basically I want all pages (except the /register page) to be rewritten like this: http://www.example.com/about -> http://www.example.com?page=about
To get that right I wrote this rule:
RewriteRule ^([a-z-_1-9]+)+/?$ ./?page=$1&%{QUERY_STRING} [L]
I then wrote this rule below the one above thinking it would override it, but it doesnt...
RewriteRule ^register/?$ ./?page=login&option=register
So going to /register gives me a 404. However if I comment out the first rule then the register page works.
I was thinking it would work like CSS where writing a new rule below would take precedence.
How would I get this right and how do you override previously written rewrite rules?
Thanks!
.htaccess is not CSS -- especially when it comes to mod_rewrite instructions/rules.
The rules are executed from top to bottom. Therefore -- put more specific rules at top and then more generic at bottom.
In your case:
RewriteRule ^register/?$ ./?page=login&option=register [L]
RewriteRule ^([a-z-_1-9]+)+/?$ ./?page=$1&%{QUERY_STRING} [L]

How can I improve my .htaccess mod_rewrite stuff?

I've created the following .htaccess file after hours of work,
Everything seems to be working properly, however I'm new to mod_rewrite, and I think my code is amateurish, so I'm looking for things to improve.
For example I thought if I use [L] at the end of a rule, the rest of rewrites will be ignored, but looking at the rewrite logs I see that they are not, there are multiple unwanted pattern matchings that certainly will slow everything down.
Also I have a book that says [C] will chain rewrite conditions, but my apache throws
http://pastebin.com/62JyBXdS
The [L] flag does indeed prevent further rules from processing, however the rewritten url could be passed back through all of your rules a second time hence the multiple entries in your log - see the manual page http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_l
Alot of your rewrite rules do the same thing with just different data and could be compacted down to a single regex, I've done a few but you could do the entire list.
RewriteRule ^/([dprcmlfb]|members|lnli|freelisting)/(.*)$ /$1\.php/$2 [L]
if you also add a RewriteCond of somethine like
RewriteCond %{REQUEST_URI} !^/[^/]+\.php
to prevent the rule firing for a php file request
You could add the MultiViews option instead of rules like the rule below:
RewriteRule ^/d/(.*)$ /d\.php/$1 [L]
MultiViews would correctly interpret /d/stuff as a request to d.php if no other rule interferes.