Created 01-27-2021 02:36 AM
Hello,
I have a HandleHttpRequest processor configured. I can access the headers as documented but unfortunately the flow file properties (http.headers.XXX) are case sensitive, so if I want to use one in some later processor using EL, I need to know the exact case used (e.g. http.headers.x-My-Header).
As it's not possible to control the end that sends the http request I am stuck (unless I add some script processing to extract what I need). Also http spec wise, the header names are case insensitive.
So, question - is there a 'standard EL way' to get hold of a header value that came with a HandleHttpRequest processor regardless of the case of the header name?
Many thanks!
Peter
Created 02-01-2021 06:49 AM
I am not sure if I understand fully what you are trying to achieve, but here are some solution directions that come to mind:
1. Use regex to match the attribute name, perhaps with anyMatchingAttribute https://nifi.apache.org/docs/nifi-docs/html/expression-language-guide.html#anymatchingattribute
2. Cast the attribute name to lower, this may indeed require a script.
Created 02-01-2021 07:16 AM
Thanks for you answer Dennis.
As I need the value of the attribute I don't understand how anymatchingattribute could help
What I need is to find an attribute based on it's name (doing a case insensitive search). So casting to lower case all attributes, then searching the one I need and then getting the value is indeed what i was looking for, but without scripting, using el only
Wkr
Peter
Created 02-02-2021 08:26 AM
@peter_coppens
While the HTTP spec may be case insensitive, NiFi Expression Language (EL) is case sensitive.
Are we talking about an undefined number of unique header case sensitivity here?
I would think you have a short defined list of possible header values here, correct?
There are multiple EL functions you can use here:
1:
${http.headers.x-My-Header:isNull():ifElse('${http.headers.x-my-header}','${http.headers.x-My-Header}'):......}
In above if subject "http.headers.x-My-Header" does not exist on the FlowFile it returns the value from "http.headers.x-my-header" attribute instead; otherwise it returns value from "http.headers.x-My-Header". Then you can continue the EL statement to do whatever additional manipulation needed.
2:
${allMatchingAttributes('(?i)http\.headers\.x-my-header'):join(''):....}
In above it uses a case insensitive Java regular expression within the "AllMatchingAttribtes( )" EL function to return values from all FlowFile attributes that satisfy that regex and then use the "join( )" function to merge them all together. Since we expect that only one attribute will actually match, the result is just a single value. This may be best option.
3:
${http.headers.x-My-Header:replaceNull(${http.header.X-my-header:replaceNull(${http.headers.x-my-header})}):....}
In above we chain multiple "replaceNull( )" functions to iterate through all case permutations till we find one that exist as an attribute on the FlowFile.
Note: In any of the above you would replace that last ":...." with the rest of your EL statement fucntions needed to manipulate the subject returned as you need.
Options 1 and 3 require you to know all case permutations that may exist.
Option 2 may be best choice as you do not need to know all the permutations, but can be an issue if for some reason you have multiple permutations of the same attribute on the same FlowFile.
Hope this helps,
Matt