Case sensitive issue while setting and getting request headers using JS policy

We are trying to send 2 headers. Header names are almost identical except for the cases. EX. partner_key and partner_Key. We are trying to do some customizations using JS. we can fetch only one header value for both context.getVariable("partner_key") and context.getVariable("partner_Key"). Is there a way to get both of the header values without changing the header names

@dchiesa1 @sidd-harth 

Solved Solved
0 1 1,538
1 ACCEPTED SOLUTION

yes, HTTP Header names are case-insensitive, according to the relative specifications. See, for example, IETF RFC 7230.

http-headers-are-case-insensitive.png

Therefore, when used as a header name, partner_key is the same as partner_Key , Partner_Key , or PARTNER_KEY . Apigee just respects that requirement. Which means, if you try to set or get the header named partner_key within a JavaScript callout, it is the same as set/get on Partner_Key and etc. Set the header with the name partner_key and then immediately get the value of the header with name PARTNER_KEY, and you will see the value you just set.

If you want to pass multiple values in a single header, on the client (sender) side, you can use a single header, with values separated by a comma. For example

 

Partner_Key: variant1=ABC, variant2=123

 

According to the HTTP spec, the above implies two distinct values, not one value that happens to include a comma. In the JS callout, if you use context.getVariable('request.header.partner_key') to retrieve a header that includes a comma, you will get only the first value. This is by design, and is not a bug. If you want all the values, you can use context.getVariable('request.header.partner_key.values.string') . You would then need to split the result by commas, strip spaces, and that would give you the individual parts.

 

var values = context.getVariable('request.header.partner_key.values.string')
        .split(',')
        .map(function(item) { return item.trim(); }) ;

// for input request header like:
//   partner_key: variant1=ABC, variant2=123
// The output will be an array
//   ['variant1=ABC', 'variant2=123'] 

 

This is all documented.

View solution in original post

1 REPLY 1

yes, HTTP Header names are case-insensitive, according to the relative specifications. See, for example, IETF RFC 7230.

http-headers-are-case-insensitive.png

Therefore, when used as a header name, partner_key is the same as partner_Key , Partner_Key , or PARTNER_KEY . Apigee just respects that requirement. Which means, if you try to set or get the header named partner_key within a JavaScript callout, it is the same as set/get on Partner_Key and etc. Set the header with the name partner_key and then immediately get the value of the header with name PARTNER_KEY, and you will see the value you just set.

If you want to pass multiple values in a single header, on the client (sender) side, you can use a single header, with values separated by a comma. For example

 

Partner_Key: variant1=ABC, variant2=123

 

According to the HTTP spec, the above implies two distinct values, not one value that happens to include a comma. In the JS callout, if you use context.getVariable('request.header.partner_key') to retrieve a header that includes a comma, you will get only the first value. This is by design, and is not a bug. If you want all the values, you can use context.getVariable('request.header.partner_key.values.string') . You would then need to split the result by commas, strip spaces, and that would give you the individual parts.

 

var values = context.getVariable('request.header.partner_key.values.string')
        .split(',')
        .map(function(item) { return item.trim(); }) ;

// for input request header like:
//   partner_key: variant1=ABC, variant2=123
// The output will be an array
//   ['variant1=ABC', 'variant2=123'] 

 

This is all documented.