Problem with Extract Variables policy uripath

Not applicable

Hi all apigee experts,

I have a problem retrieving an UriPath Parameter from my request, the problem is that my parameter ends with an "=".

Example:
https://ApiUrl/pathsuffix/1245=

when I use

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ExtractVariables async="false" continueOnError="false" enabled="true" name="Extract-Online-ID">
    <DisplayName>Extract Online ID</DisplayName>
    <Properties/>
    <URIPath>
        <Pattern ignoreCase="true">/pathsuffix/{id}</Pattern>
    </URIPath>
</ExtractVariables>

The ìd variable gets the value 1245 without the "=" character.

Have you an idea how to resolve this problem?

Thanks

Solved Solved
2 2 528
1 ACCEPTED SOLUTION

Hmm, I think that may be a deficiency in the ExtractVariables policy. I haven't looked closely, but if you are seeing the behavior you reported, it seems pretty clear.

You can work around it using a JavaScript policy. Here's how I would do it.

<Javascript name='JS-ExtractVariablesFromUriPath' timeLimit='200' >
  <Properties>
    <Property name='pattern'>/t1/{id}</Property>
    <Property name='varprefix'>extracted</Property>
  </Properties>
  <ResourceURL>jsc://extractVariablesFromUriPath.js</ResourceURL>
</Javascript>

And then the JS code would be like this:

//
// convert a pattern from a form like '/t1/{id}/{fred}' 
// into a regexp, and a set of names.
//
function compilePattern(pattern) {
  var re1 = new RegExp('^([^{]*)({[^}]+})(.*)$');
  var names = [];
  var match;
  while ((match = re1.exec(pattern)) !== null) {
    pattern = match[1] + '([^/]+)' + match[3];
    names.push(match[2].substring(1, match[2].length-1));
  }
  return { re: new RegExp(pattern), names:names};
}
var path = context.getVariable('proxy.pathsuffix');
var varprefix = properties.varprefix;
var compiled = compilePattern(properties.pattern);
var match = compiled.re.exec(path);
if (match && match.length) {
  varprefix = (varprefix) ? varprefix + '.': '';
  for (var i=1, L=match.length; i<L; i++) {
    context.setVariable(varprefix + compiled.names[i - 1], match[i] );
  }
}

Also see attached for a working API Proxy.

apiproxy-js-extractvariables-20170117-141250.zip

Deploy it and invoke it like this:

curl -i https://ORGNAME-ENVNAME.apigee.net/js-extractvariables/t1/12345=

...and you should see this output:

{
    "extracted" : "12345=",
    "stamp" : "1484691146863"
}

View solution in original post

2 REPLIES 2

Hmm, I think that may be a deficiency in the ExtractVariables policy. I haven't looked closely, but if you are seeing the behavior you reported, it seems pretty clear.

You can work around it using a JavaScript policy. Here's how I would do it.

<Javascript name='JS-ExtractVariablesFromUriPath' timeLimit='200' >
  <Properties>
    <Property name='pattern'>/t1/{id}</Property>
    <Property name='varprefix'>extracted</Property>
  </Properties>
  <ResourceURL>jsc://extractVariablesFromUriPath.js</ResourceURL>
</Javascript>

And then the JS code would be like this:

//
// convert a pattern from a form like '/t1/{id}/{fred}' 
// into a regexp, and a set of names.
//
function compilePattern(pattern) {
  var re1 = new RegExp('^([^{]*)({[^}]+})(.*)$');
  var names = [];
  var match;
  while ((match = re1.exec(pattern)) !== null) {
    pattern = match[1] + '([^/]+)' + match[3];
    names.push(match[2].substring(1, match[2].length-1));
  }
  return { re: new RegExp(pattern), names:names};
}
var path = context.getVariable('proxy.pathsuffix');
var varprefix = properties.varprefix;
var compiled = compilePattern(properties.pattern);
var match = compiled.re.exec(path);
if (match && match.length) {
  varprefix = (varprefix) ? varprefix + '.': '';
  for (var i=1, L=match.length; i<L; i++) {
    context.setVariable(varprefix + compiled.names[i - 1], match[i] );
  }
}

Also see attached for a working API Proxy.

apiproxy-js-extractvariables-20170117-141250.zip

Deploy it and invoke it like this:

curl -i https://ORGNAME-ENVNAME.apigee.net/js-extractvariables/t1/12345=

...and you should see this output:

{
    "extracted" : "12345=",
    "stamp" : "1484691146863"
}

Not applicable

The equality sign is a reserved character per the HTTP spec for URIs (see https://tools.ietf.org/html/rfc3986). Any such special characters will need to be encoded by the calling client.

Take a look at https://tools.ietf.org/html/rfc3986#section-2.2 for more info...