Disallowing empty values in path suffix

I have a proxy whose conditional path looks like follows -

manifest/5320037/dd6638c9

I'm catching this through a condition that looks like below -

(proxy.pathsuffix MatchesPath "/manifest/*/*")

However, when a request comes like this,

manifest/5320037/

this condition is still passing.

I want a condition where it should pass only if atleast one char is present in the last part of the uri -

manifest/5320037/dd6638c9

Otherwise I get an ugly 404 service not found error from the backend.

How do I write this?

1 5 324
5 REPLIES 5

I think you want to use the ~~ operator, aka JavaRegex.

For example, here is a set of flows with Conditions. The first flow matches a path with a non-empty trailing value. The second matches a path with an empty trailing value. The final one is a "catch all" for other paths that don't match anything.

  <Flows>


    <Flow name="flow1">
      <Request>
      </Request>
      <Response>
        <Step>
          <Name>AM-Response-Case1</Name>
        </Step>
      </Response>
      <Condition>(proxy.pathsuffix ~~ "/t1/.+/.+") and (request.verb = "GET")</Condition>
    </Flow>


    <Flow name="flow2">
      <Request>
      </Request>
      <Response>
        <Step>
          <Name>AM-Response-Case2</Name>
        </Step>
      </Response>
      <Condition>(proxy.pathsuffix ~~ "/t1/.+/") and (request.verb = "GET")</Condition>
    </Flow>


    <Flow name="unknown request">
      <Request>
        <Step>
          <Name>RF-UnknownRequest</Name>
        </Step>
      </Request>
      <Response>
      </Response>
    </Flow>


  </Flows>


Results:

$ curl -i https://$ORG-$ENV.apigee.net/condition-1/t1/foo/bar
HTTP/1.1 200 OK
Date: Thu, 05 Dec 2019 18:57:13 GMT
Content-Type: application/json
Content-Length: 26
Connection: keep-alive


{
    "status" : "case1"
}


$ curl -i https://$ORG-$ENV.apigee.net/condition-1/t1/foo/
HTTP/1.1 200 OK
Date: Thu, 05 Dec 2019 18:57:17 GMT
Content-Type: application/json
Content-Length: 26
Connection: keep-alive


{
    "status" : "case2"
}


$ curl -i https://$ORG-$ENV.apigee.net/condition-1/t1/foo
HTTP/1.1 404 Not Found
Date: Thu, 05 Dec 2019 18:57:19 GMT
Content-Type: application/json
Content-Length: 112
Connection: keep-alive


{
  "error" : {
    "code" : 404.01,
    "message" : "that request was unknown; try a different request."
  }
}

The downside is that you need to use regular expressions. In my opinion, regex are a handy and powerful tool. But some people find them difficult to use because the syntax is sort of complicated. In my example above, I kept it pretty simple. But actually I cheated.

The regex I used above are too lax. Here's why: in the regex above, the ".+" can match "any string of one or more characters" and that string could include a slash!

In other words, this: "/t1/.+/.+" at first looks like a simple pattern for matching a path with three segments, the first of which is t1. But it could actually match other things, including "/t1/foo/bar/bam". The ".+" can capture strings that contain slashes. So a request like

curl -i https://$ORG-$ENV.apigee.net/condition-1/t1/foo/bar/bam/baz/bah/bug

...would actually match case1 in the condition above. Probably not what you want!

To explore the behavior of regex, you can interactively test regex at any one of a number of online regex testers, like this one here: https://www.freeformatter.com/regex-tester.html

A more strict regex would use [^/]+ in place of ".+". That would disallow slashes in the segments.

like this:

      <Condition>(proxy.pathsuffix ~~ "/t1/[^/]+/[^/]+") and (request.verb = "GET")</Condition>

So you can see it can start to look confusing with all those characters. But anyway, as I said, regex are handy and powerful, and if applied correctly, they are just the right solution for your specific problem.

@Dino-at-Google

it solved the issue mentioned above however it still passes when the URI looks like this (two slashes)

manifest/5320037//dd6638c9

From Postman, I can see the request was sent out with two slashes however in Apigee Trace, the request received from client is simply shown as

manifest/5320037/dd6638c9

Is this default APIGEE behaviour?

I'm using the regex condition (proxy.pathsuffix ~~ "/t1/[^/]+/[^/]+")

yes it is default behavior. Apigee's inbound proxy collapses duplicated slashes. (I don't think you can change this)

thats fine, thanks for your support.