If you've used mod_rewrite
with Apache web server, you may be familiar with its Rewrite Map functionality, which allows you to create dynamic rewrites based on a text file of mappings. We have a similar feature built on Undertow's Server Rules that mimics Apache's feature.
{% hint style="info" %} Note, when in Mult-Site mode, each site has its own rewrite maps, even if they share the same name. There is no overlap between sites! {% endhint %}
There is a rewrite-map()
handler which declares a named map file. It accepts an absolute path to the rewrite file, and case sensitivity flag.
{
"web" : {
"rules":[
"rewrite-map( name=myMap, file='/path/to/myMap.txt' case-sensitive=false )"
]
}
}
The file format matches that of Apache's rewrite map functionality.
- Lines starting with
#
are a comment - empty lines are ignored
- First space-delimited token becomes the key
- All remaining tokens become the value
- Lines with a single token default the value to an empty string
Here is an example file:
#comment
brad wood
luis majano
jorge reyes bendeck
RACHEL WOOD
sdf sdf
If the date modified on the rewrite map file changes on disk, the data will be automatically re-loaded into memory.
There are two handler/predicates you can use to interact with the rewrite map. Make sure these are in your list of Server Rules AFTER the map definition.
There is a rewrite-map-exists()
predicate which will tell you if a given key exists in the map (Apache doesn't have this)
rewrite-map-exists( map='myMap', key='%{RELATIVE_PATH}' )
You can pair this predicate to only use the rewrite map if there is a match.
There is a new %{map:name-name:mapKey|defaultValue}
exchange attribute which mostly follows Apache's syntax. The only limitation is nested exchange attributes must use [] instead of {} due to an Undertow parsing issue).
{
"web" : {
"rules":[
"rewrite-map( name=myMap, file='/path/to/myMap.txt' case-sensitive=false )",
"regex-nocase( '^/foo/(.*)$' ) -> rewrite( 'index.cfm?page=%{map:myMap:$[1]|99}' )"
]
}
}
In the example above, we're using a regex predicate to extract the text after /foo/
in the URL and then we reference that capture group as $[1]
which we pass in as the key to the map. If there is no key in the map for that value, we default to 99
.
So, given our example rule map file above, the url
http://site1.com/foo/luis
would be rewritten to
http://site1.com/index.cfm?page=majano