Add several headers but only if their variables are resolved

We want to add several headers to the request, containing values we previously saved into variables. AssignMessage policy allows to add several headers at once:

 

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<AssignMessage async="false" continueOnError="false" enabled="true" name="AddHeaders">
    <DisplayName>AddHeaders</DisplayName>
    <Add>
        <Headers>
            <Header name="X-Forwarded-For">{apgXForwardedFor}</Header>
            <Header name="X-Forwarded-Host">{apgXForwardedHost}</Header>
            <Header name="X-Forwarded-Port">{apgXForwardedPort}</Header>
            <Header name="X-Forwarded-Prefix">{apgXForwardedPrefix}</Header>
            <Header name="X-Forwarded-Proto">{apgXForwardedProto}</Header>
            <Header name="X-Forwarded-Server">{apgXForwardedServer}</Header>
        </Headers>
    </Add>
    <AssignTo createNew="false">message</AssignTo>
    <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables>
</AssignMessage>

 

But doing it this way, all headers are added to the request even if the variables can't be resolved. For example, if apgXForwardedPrefix is null or empty, this policy will add that header with empty value. Setting IgnoreUnresolvedVariables as false is not a solution, because it will stop the execution. Setting continueOnError to true is not a solution for this last problem, because next headers will not be evaluated (in the example, if apgXForwardedPrefix is null then Proto and Server will not be added as headers even if they are not null nor empty).

The only way we know to add all headers unless their variables are not resolved, is to make one policy for each header (with a condition like "apgXForwardedPrefix != null"). This adds the header only if the variable is resolved, doesn't add empty headers, and doesn't stop the execution or stop evaluating next variables if one unresolved variable is found. But this means having to create six policies in this case. If we want to add 20 headers we would have to create 20 policies.

Is there any alternative way of achieving this behaviour?

Solved Solved
0 1 174
1 ACCEPTED SOLUTION

Yes, I suppose you could code that conditional logic - "add this header only if this particular context variable is defined" - via JavaScript.  The way I would do it is set the header names and the variable names in a has in the JS properties. 

 

<Javascript name='JS-Set-Headers-Conditionally'>
  <Properties>
    <Property name='headersAndVariables'> {
    "X-Forwarded-For": "apgXForwardedFor",
    "X-Forwarded-Host": "apgXForwardedHost",
    "X-Forwarded-Port": "apgXForwardedPort",
    "X-Forwarded-Prefix": "apgXForwardedPrefix",
    "X-Forwarded-Proto": "apgXForwardedProto",
    "X-Forwarded-Server": "apgXForwardedServer"
  }
    </Property>
  </Properties>
  <ResourceURL>jsc://set-headers-conditionally.js</ResourceURL>
</Javascript>

 

And then in the set-headers-conditionally.js you can just iterate through the keys in that hash, and set headers as appropriate. 

 

var hash = JSON.parse(properties.headersAndVariables);
Object.keys(hash).forEach(function(headerName) {
  var v = context.getVariable(hash[headerName]); // read the referenced variable
  if (v && v.trim() != "") {
    context.setVariable('message.header.' + headerName, v);
  }
});

 

View solution in original post

1 REPLY 1

Yes, I suppose you could code that conditional logic - "add this header only if this particular context variable is defined" - via JavaScript.  The way I would do it is set the header names and the variable names in a has in the JS properties. 

 

<Javascript name='JS-Set-Headers-Conditionally'>
  <Properties>
    <Property name='headersAndVariables'> {
    "X-Forwarded-For": "apgXForwardedFor",
    "X-Forwarded-Host": "apgXForwardedHost",
    "X-Forwarded-Port": "apgXForwardedPort",
    "X-Forwarded-Prefix": "apgXForwardedPrefix",
    "X-Forwarded-Proto": "apgXForwardedProto",
    "X-Forwarded-Server": "apgXForwardedServer"
  }
    </Property>
  </Properties>
  <ResourceURL>jsc://set-headers-conditionally.js</ResourceURL>
</Javascript>

 

And then in the set-headers-conditionally.js you can just iterate through the keys in that hash, and set headers as appropriate. 

 

var hash = JSON.parse(properties.headersAndVariables);
Object.keys(hash).forEach(function(headerName) {
  var v = context.getVariable(hash[headerName]); // read the referenced variable
  if (v && v.trim() != "") {
    context.setVariable('message.header.' + headerName, v);
  }
});