How do I detect missing (or undefined) headers in the context.proxyRequest.headers javascript object?

Context:

I am trying to develop a Pre-Target Flow Hook that needs to check for the presence of a header in the original request received by the proxy. This flow hook will need to execute for all proxies in an organization including those proxies that might have altered or changed the conventional request object. I am trying to detect these headers in a javascript policy using the context object: context.proxyRequest.headers.

Question:

How do I detect when a header is missing from the original request?

When I run the following code:

var myHeader = context.proxyRequest.headers['myHeader'];

I find that the variable 'myHeader' is populated with an object value; specifically an instance of "org.mozilla.javascript.Undefined". Unfortunately, this object evaluates to a truthy value, meaning code like this will fail:

if (myHeader){
  // This will execute even if the header is missing.
}

Currently the only (hacky) solution I have found is to wrap the "Undefined" object in a String object and do the "nullity/undefined" check as follows:

if (new String(myHeader) != 'undefined') {
  // This will only execute when the header is present.
}

Is there a better way of doing this? Is this a bug on the part of Apigee or Rhino? Shouldn't a missing header value be converted to a "real" javascript undefined?

And again I want to reiterate that I am using context.proxyRequest because I need access to the original request received by the proxy. As I understand it, things like the Extract-Variable policy act on the current request object which might have changed by the time the flow hook executes.

0 3 2,271
3 REPLIES 3

A few suggestions:

  1. If you need to detect a header in the original request, why not do it with a pre-proxy flow hook?
  2. You don't really need to resort to Javascript code to do this. If you want Policy X to be triggered when the header is missing (typical use case: a RaiseFault policy), add a Condition to the step.
<Step>
  <Name>PolicyX</Name>
  <Condition>(request.header.myHeader == null) or (request.header.myHeader == "") )</Condition>
</Step>

Unfortunately, I'm pretty sure I need to run this in a Pre-Target flow hook.

The goal is to re-add specific headers back into the outgoing request when the proxy is deployed in certain test environments. (But only in certain test environments; in production, these headers shouldn't be present).

This is something that needs to happen after all the normal proxy flows have executed (since they can strip out or add headers).

I'm doing this to support how our test backend server works. It is going to inspect these incoming requests and reroute them based on the presence of these headers.

(I'm also want to avoid putting this logic in the proxies themselves because I don't want to pollute our 20 or so proxies with difficult to maintain scaffolding code.)

Is there really no robust way for us to detect an "org.mozilla.javascript.Undefined" in a javascript policy? I guess that's my real question. I feel like this is a bug on how Apigee implements it's javascript policies...

Hi @Adam Kullberg

If you want to use Java script you can try following approach.

Here is the code snippet

//  Define List of Mandatory HEADERS  you want to check
//  You can also Use KVM to store list of mandatory headers for the environment you are using

var mandatoryheadersval = "Header1,Header2,Header3" ;


// Call function to loop through mandatory header list and available request headers
// function will return two values
// retrundata[0] will return true or false 
// retrundata[1] will return list of missing mandatory headers

 retrundata = checkMissingHeaders(mandatoryheadersval);
 
 print ("Is header missing " + retrundata[0] );
 print ("Missing Headers  " + retrundata[1] );
    


//Fuction to Check Manadaotry Headers based KVM values for specific call
function checkMissingHeaders(headersData) 
{
	var missingHeader = false;
	var missingHeaderStr = null;
	if (headersData !== null) 
	{
		var headersDataArray = headersData.split(",");
		var headersField;
		var headersFieldData;
		var headersFieldDataValue;
		


		for (i = 0; i < headersDataArray.length; i++) 
		{   
		    headersField = "request.header."+ headersDataArray[i].toLowerCase();
			headersFieldData = context.getVariable(headersField);


			if ( (headersFieldData === null)|| (headersFieldData.trim() ==="")) 
			{
				missingHeader = true;
				if (missingHeaderStr === null) {missingHeaderStr = headersDataArray[i];}
				else {missingHeaderStr = missingHeaderStr + " ,  "+ headersDataArray[i];
				}
 			}
		}
	}
	
	return [ missingHeader, missingHeaderStr ];
	
}

You can also Use KVM to store list of mandatory headers for the environment you are using.

See if above solution is fit for what you are trying to do.

Regards

Jayesh