Advanced Query String Manipulation with IIS URL Rewrite: Selective Parameter Forwarding


3 views

When working with IIS URL Rewrite Module, developers often need more granular control over query string parameters than the simple "Append query string" option provides. The requirement is to selectively forward specific parameters while discarding others, regardless of their original order in the incoming URL.

We'll implement this using rewrite rules with conditions that check for specific query string parameters. The key components are:

<rule name="Selective Query String Forwarding">
  <match url="test" />
  <conditions logicalGrouping="MatchAll" trackAllCaptures="true">
    <add input="{QUERY_STRING}" pattern="(?:^|&)(beta=([^&]*))" />
    <add input="{QUERY_STRING}" pattern="(?:^|&)(gamma=([^&]*))" />
  </conditions>
  <action type="Redirect" url="redirect?{C:1}&{C:3}" appendQueryString="false" />
</rule>

For scenarios where the parameter list might change frequently, we can create a more flexible solution:

<rule name="Dynamic Parameter Filter">
  <match url="test" />
  <conditions>
    <add input="{QUERY_STRING}" pattern="(?:^|&)((beta|gamma)=([^&]*))" />
  </conditions>
  <action type="Redirect" url="redirect?{C:1}" appendQueryString="false" />
  <serverVariables>
    <set name="QUERY_STRING" value="{C:1}" />
  </serverVariables>
</rule>

The regex pattern (?:^|&)((beta|gamma)=([^&]*)) breaks down as:

  • (?:^|&) - Matches start of string OR ampersand
  • (beta|gamma) - Captures our target parameter names
  • =([^&]*) - Captures everything after equals until next ampersand

When implementing this solution, consider:

<rule name="EdgeCaseHandling">
  <match url="test" />
  <conditions logicalGrouping="MatchAny" trackAllCaptures="true">
    <add input="{QUERY_STRING}" pattern="(?:^|&)(beta=([^&]*))" />
    <add input="{QUERY_STRING}" pattern="(?:^|&)(gamma=([^&]*))" />
  </conditions>
  <action type="Redirect" url="redirect?{C:1}{C:2}" appendQueryString="false" />
</rule>

When working with IIS URL Rewrite Module, developers often need more granular control over query string parameters than the simple "Append query string" checkbox provides. The requirement is to selectively forward specific parameters while excluding others, regardless of their order in the original URL.

We can achieve this through a combination of server variables and rewrite conditions. The key components are:

<rule name="Selective Query String Forwarding" stopProcessing="true">
    <match url="test" />
    <conditions logicalGrouping="MatchAny" trackAllCaptures="true">
        <add input="{QUERY_STRING}" pattern="(?:^|&)(beta=([^&]*))" />
        <add input="{QUERY_STRING}" pattern="(?:^|&)(gamma=([^&]*))" />
    </conditions>
    <action type="Redirect" url="redirect?{C:1}&{C:3}" appendQueryString="false" />
</rule>

For a more robust solution that handles edge cases:

<rule name="Advanced Parameter Filtering" enabled="true" stopProcessing="true">
    <match url="^test$" />
    <conditions>
        <add input="{QUERY_STRING}" pattern="(?:^|&)(beta=([^&]*))" />
        <add input="{QUERY_STRING}" pattern="(?:^|&)(gamma=([^&]*))" />
    </conditions>
    <serverVariables>
        <set name="RESPONSE_LOCATION" value="redirect?{C:1}{C:2}" />
    </serverVariables>
    <action type="Redirect" url="{RESPONSE_LOCATION}" />
</rule>

For scenarios where parameter keys need to be configurable:

<rewrite>
    <rules>
        <rule name="Dynamic Parameter Selection">
            <match url="^test$" />
            <conditions>
                <add input="{QUERY_STRING}" pattern="(beta|gamma|delta)=([^&]+)" />
            </conditions>
            <action type="Rewrite" url="redirect?{C:1}={C:2}" appendQueryString="false" />
        </rule>
    </rewrite>

When implementing complex rewrite rules:

  • Use stopProcessing="true" when appropriate
  • Order conditions by probability of match
  • Limit capture groups to only what's necessary
  • Consider using Rewrite instead of Redirect when possible

Enable Failed Request Tracing in IIS to troubleshoot:

<traceFailedRequests>
    <add path="*">
        <traceAreas>
            <add provider="WWW Server" areas="Rewrite" verbosity="Verbose" />
        </traceAreas>
        <failureDefinitions statusCodes="200-999" />
    </add>
</traceFailedRequests>