Advanced Rewriting Policies for Citrix ADC/NetScaler

Be sure to unbind all policies before continuing!


It’s time to explore policy bindings in detail. To do so (and being an enthusiastic fan of BOFH) I create a set of policies to confuse users.

  • people demanding red.htm they should see blue.htm
  • people demanding blue.htm they should see green.htm
  • people demanding green.htm they should see red.htm

Policies are simple, I created a screenshot of the first policy and action only, the rest is similar.

The policy actions

You are absolutely right, it has to be an action of the type replace, as we want to replace something (HTTP.REQ.URL has to be replaced)

NetScaler: Rewrite action

There will be 3 of these actions: rw_act_send2red, rw_act_send2green and rw_act_send2blue

The policies

NetScaler rewriting policies

The action we created, will replace any URL with /blue.htm. So we need to create a policy expression and filter for users demanding /red.htm only. So requests for red gets re-written to requests for green.

NetScaler rewriting policies

Binding policies

All policies have to be bound. So we will bind policies this way:

NetScaler policy binding

So my three policies got bound. Binding priority is default, so starting with 100.

  • A request, coming in for /red.htm will get rewritten to /blue.htm (no other policies)
  • A request, coming in for /blue.htm will get rewritten to /green.htm (no other policies)
  • A request, coming in for /green.htm will get rewritten to /red.htm (no other policies)

Give it a try: It works perfectly well and it’s confusing! Great! BOFH would be proud of us!

A second try

We want to demonstrate how policies get processed. So we change policy binding. We will use Goto NEXR instead of Goto END.

NetScaler policy binding
Policy binding using GOTO NEXT

After changing the binding, we could expect behaviour like that:

  • red gets rewritten to blue
  • blue gets rewritten to green
  • green gets rewritten to red.

You could expect red.htm, no matter which colour you request. Let’s say, I request blue, so blue gets rewritten to green and green gets rewritten to red. The result is red.

Give it a try? What’s the result? You see, it didn’t change! Why?

Policies can’t depend on each other. Instead, the Citrix ADC / NetScaler compares the request to all policies and creates a “resultant set of policies”. It will apply the resulting policies only after finishing policy evaluation.

A more elegant solution

It took us three policies to do our trick. But we could do it, using a single policy!

String Maps

Citrix ADC / NetScaler got string maps. It’s a pair of data, a key and a value.

Key Value
/red.htm /blue.htm
/blue.htm /green.htm
/green.htm /red.htm

You will find stringmaps in AppExpertString Maps

NetScaler Stringmap

String Maps – of course – may be much bigger than that. But it’s a good example.

The policy Expression using String Maps

We need just one expression here.  Any URL has to get looked up in the list a get replaced with its value.

NetScaler rewrite action using string maps
You can see, the exprtession is HTTP.REQ.URL.MAP_STRING(“confuse“)

The Policy using String Maps

NetScaler rewriting policy using stringmaps
So this policy has to get applied if the URL is any of the string map keys.

Unbind all rewrite policies and bind this one. It will do the same.

This kind of policies is very convenient. It is used very much to shorten down URLs for commercials. Instead of printing on commercials, we could print It’s way easier to remember (don’t forget to make is case-insensitive!). This kind of policies can even get managed by non-administrative stuff.

Another advantage: It less costly in terms of resources. You should always use string maps, pattern sets, data sets or URL sets if any possible.


  1. Hello
    Please let me know if stringMap supports wildcard characters, like *. For the example were I need to match /file1.txt, /file2.txt, fileN.txt, can I use /file*.txt or any other wildcard char in this case?

    1. No. Rather not. It’s a list of possible matches. Instead, you could create a policy using regexmatch (see It would be HTTP.REQ.URL.REGEX_MATCH(re#/file\d{1,2}\.txt#)

      /file\d{1,2}\.txt means it hast to start with /file next will be one or two digits (\d{1,2}, followed by a dot (\.) followed by the literal txt. REGEX is case-sensitive of course!

Leave a Comment

Your email address will not be published. Required fields are marked *