Apache rule to change / (slash) to _ (underscore) - apache

I've set up an Apache HTTP server with VirtualHosts in front of a proprietary web server in the back. The backend server can only have one (1) level in its ID paths so the following public URLs:
http://public-server/path1/path2/path3?querystring-parameters
should be converted for the backend to:
http://internal-server/path1/path2/page/<path1>_<path2>_<path3>?querystring-parameters
Notice that there can be any number of path1, path2, path3, path4, .... and they should all (no matter if only 1 exists or multiple) be concatenated with an underscore. Also notice that the querystring-parameters CAN contain '?', '/' and '_' so the rule should not alter the querystring in any way.
I've tried searching for solutions to this but can't figure out how to overcome the problem. Any suggestions?

If you can come up some maximum number of possible paths, you can do something to this effect:
# This will work for up to 5 paths
RewriteRule /([^/]*)/?([^/]*)/?([^/]*)/?([^/]*)/?([^/]*) http://internal-server%{REQUEST_URI}$1_$2_$3_$4_$5 [L,QSA]
The /?([^/]*) can be added to the end as many times as you need, along with added the corresponding groups (_$6 ..) to the rewritten URL.
Unfortunately, there is not a way have a completely unknown number of paths, while at the same time use them in the rewritten URL. Also, the [QSA] flag will attach your querystring on to the forwarded URL, untouched.
Hope this helps.

Related

How do I enable query string in Cloudflare page rules?

I want to forward this URL
https://demo.example.com/page1?v=105
to
https://www.example.com/page1
It's not working if I set so:
But if I remove the ?v= part, it works:
Is there any way to include the ?v= part in this page rule?
The rule you mentioned works only for that exact URL: https://demo.example.com/page1?v=105. If it has any additional query parameter or even an additional character, eg https://demo.example.com/page1?v=1050, it won't match the rule.
If you need to use complicated URL matches that require specific query strings, you might need to use bulk redirects or a Cloudflare worker.

Mod_Rewrite how to ignore slashes that don't belong in url string

I'm trying to setup canonical links in our forum and I need to come up with a rewrite rule that will ignores slashes that don't belong in the URL.
The proper URL would look like:
http://www.truckingtruth.com/truckers-forum/Topic-20315/Page-1/speak-to-recruiter
For this I'm using the following mod_rewrite rule to pass the 'topic', 'page', and 'subjectString' variables:
^Topic-(.*)/Page-(.*)/(.*)$ index.html?topic=$1&page=$2&subjectString=$3
But sometimes improper links to our site or improper links in a comment will add slashes to the URL that don't belong there and it throws off the rule. Example:
http://www.truckingtruth.com/truckers-forum/Topic-1652/Page-1/www.truckingtruth.com/free_truck_driving_schools/swift/how-to-use-the-qualcomm
When that happens the variables being passed are:
topic = "1652"
page = "1/www.truckingtruth.com/free_truck_driving_schools/swift"
subjectString = "how-to-use-the-qualcomm"
What I want it to do is pass:
topic = "1652"
page = "1"
subjectString = "www.truckingtruth.com/free_truck_driving_schools/swift/how-to-use-the-qualcomm"
How can I create a rewrite rule that will pass everything after "Page-1" as the subjectString even if there are slashes in it?
Since the topic is always integer, for your first capturing group you can use \d which matches any decimal digit (equivalent to [0-9]).
For page, just make sure not to include any slashes, [^/] will take care of that.
The rest should then all go to third capturing group, so the resulting regex will be:
^Topic-(\d*)/Page-([^/]*)/(.*)$

Mod Rewrite on get vars

I'm working on a private project, which is basicly a profile system.
Now I've been trying how to improve the URL formatting.
At this moment, I am using URL's which look like:
-> http://example.com/overview
-> http://example.com/profile/?name=foo
-> http://example.com/jobs/?name=foo
Both overview and profile are directories on my website, which contain a single index.php file, which holds the PageID of which should be retrieved from the database.
Now, my goal is to format the URL to something as:
-> http://example.com/foo OR http://example.com/profile/foo
-> http://example.com/foo/jobs OR http://example.com/profile/foo/jobs
Is there anyway to do this with MOD_REWRITE?
This would mean the original url would look something like http://example.com/?character=foo/jobs which is http://example.com/get_var/directory.
I've done my research on Stackoverflow and Google, searching for 'mod_rewrite get variables'. But nothing seemed to be what I'd like to see happening.
Yours Sincerely,
Larssy1
To extract a portion of the URI between slashes and append it as a URL parameter, use the expression ([^/]+) to capture all characters up to but not including the next / into $1:
RewriteEngine On
RewriteRule ^profile/([^/]+)/([^/]+/?)?$ profile/$2?character=$1 [L]
The above rule will dynamically capture what follows Foo from your example, meaning that whether it was followed by /jobs or /other or /somethingelse, it would be appended as /profile/somethingelse?character=Foo. If that isn't necessary, and /jobs is static, you don't need to capture it into $2:
RewriteEngine On
# Don't dynamically capture what comes after the first variable group...
RewriteRule ^profile/([^/]+)/jobs$ profile/jobs?character=$1 [L]

Apache mod_rewrite path name as query parameters?

I want to use Apache's mod_rewrite in order to be able to take each folder of a path as a particular query parameter, for example consider the following:
Basic example
Url requested: http://domain.com/shoes/prada/image-1/
Page served: http://domain.com/?cid=shoes&bid=prada&pid=image-1
In this scenario, there are 3 sub-folders requested (/shoes/, /prada/ then image-1), so the first sub-folder is passed in the actual page served as cid, the second as bid and the third as pid.
Full example
However, I would also like it to serve a particular page depending on the number of sub-folders requested, e.g.
Url requested: http://domain.com/shoes/prada/
Page served: http://domain.com/shop.php?cid=shoes&bid=prada
So far all I've managed to find is regex based matching for mod_rewrite but my path's will vary a lot, which is why I would like to have conditions based on the number of folders accessed (please note, I'm not that good with regex - I reckon a wildcard character would help with this, but I wouldn't be sure where to start).
Any help on this would be greatly appreciated! This is pretty long winded, so if you need any more info for clarifying, please let me know!
With a little bit of work I was able to tweak some regex and get a working rule set for what I wanted:
RewriteEngine on
RewriteRule ^(.*)/(.*)/(.*)/(.)?$ product.php?tid=$1&sid=$2&eid=$3 [L]
RewriteRule ^(.*)/(.*)/(.)?$ brand.php?tid=$1&sid=$2 [L]
RewriteRule ^(.*)/(.)?$ shop.php?tid=$1 [L]
This is a bit different to the example, however it's what I intended for in the first place.
This allows for the rewriting of url's up to four folders deep, with the "name" of each folder being given as a parameter, and each additional level of depth rewriting the url to a separate resource for example:
http://x.com/shoes/prada/2011-high-heels/ -> http://x.com/product.php?tid=shoes&sid=prada&eid=2011-high-heels
Tested on http://martinmelin.se/rewrite-rule-tester/

Abusing Mod Rewrite for a clean file system, and pretty URLs

I have a few php files that do a few different jobs. I'd like to change the way my clients access these php files to make it more clean for the end user. The Mod_Rewrite system has shown that it can do some pretty powerful things when in the hands of the right server admin. So I was wondering how far can you abuse the Mod Rewrite rules for a cleaner file system, and pretty URLs. Considering that the PHP files themselves use query strings to get their data, I'd like to alias the way the query string is built based upon how the how deep into the fake files system we go.
Our website's URL is http://www.domain.tld/, but we shall call it domain.tld for short. I'd like to map a few different address to a few different query strings on a few different files. But I'd also like to to be expandable on a whim.
Or first set would be, anything going past domain.tld/series/ should be directed to the domain.tld/series.php script with any (fake) directory past series to become part of the query-string for series.php. The same should happen to anything directed in the direction of domain.tld/users/ that should be redirected to the domain.tld/users.php file.
So if we had a URLs like, domain.tld/series/Master/2010/ or domain.tld/series/Novice/Season 01/ they would still be redirected to the domain.tld/series.php script, but with the query-string of ?0=Master&1=2010 and ?0=Novice&1=Season 01. But should I want to get an overview of the Master series, I could go the the URL domain.tld/series/Master/ and produce the query-string of just ?0=Master. The idea being that the rewrite rule should allow for infinite expandability.
This is how I'm doing it, and it sure works infinitely:
RewriteRule ^((/?[^/]+)+)/?$ ?q=$1 [L]
The trick is that the whole path is passed on as a single parameter, q, to index.php. So for example domain.tld/series/Novice/Season 01/ becomes domain.tld/?q=series/Novice/Season 01. Then you can do:
<?php
$params = explode('/', $_GET['q']);
var_dump($params);
?>
to get the individual parts.
array(3) { 0 => 'series', 1 => 'Novice', 2 => 'Season 01' }
It is not possible to be completely dynamic in such a system and have, as you say 'infinite expandability. You would have to define a RewriteRule for every 'tier' you will allow in your URL, or alternatively match everything after the first 'tier' as a single variable and do the work with PHP.
Example 1
RewriteRule ^([^/]+)/?$ /$1.php
RewriteRule ^([^/]+)/([^/]+)/?$ /$1.php?0=$2
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ /$1.php?0=$2&1=$3
Example 2
RewriteRule ^([^/]+)/(.*)/? /$1.php?qs=$2
Obviously these are only very simple examples and you'd probably have to use RewriteConds etc. to exempt certain files etc.