Jump to content
Welcome to our new Citrix community!

Looking for Redirect / Rewrite Suggestions.


Recommended Posts

I am hoping someone here can help set my mind straight to accomplish something I do not have much experience with on this platform. I am thinking that a rewrite would be the best way to accomplish this but a redirect could work as well (I think). Let me tell you what I am trying to do. 

 

https://gateway.company.com/GATEWAY  - This URL application teams are trying to consolidate down into 1 VIP.  However, there is still traffic hitting this VIP and the app team is not sure who is using it. So we cannot simply decommission it and ask the application teams to update their code to point to the active VIP. 

 

https://gatewayadvanced.company.com/GATEWAYAdvanced - This URL they would like to stay active. 

 

So in my view, I have two ways of accomplishing this. I can either put a redirect on https://gateway.company.com/GATEWAY to https://gatewayadvanced.company.com/GATEWAYAdvanced or I can try to make this work with a rewrite by rewriting the hostname and the 1st path in the URL. 

 

The problem I am having with both after trying to test this out is there will be a string a data behind the first URL path and I am not entirely sure how to preserve that data.

 

So for example:

 

Redirect policy is HTTP.REQ.HOSTNAME.CONTAINS("gateway.company.com")

Action expression is simply = "https://gatewayadvanced.company.com/GATEWAYAdvanced/"

 

As mentioned, there will be additional paths to the URL when applications call this VIP so https://gatewayadvanced.company.com/GATEWAYAdvanced/GetDocListServlet?Number=123456789

 

The additional URL path beyond the first URL will always match between the two applications, so how can I preserve that in a redirect or would you think a rewrite is better to accomplish this? 

 

Thanks for sticking with me on this and really appreciate any insight into this. 

Link to comment
Share on other sites

18 minutes ago, Sam Jacobs said:

Try using the following action expression:


"https://gatewayadvanced.company.com/GATEWAYAdvanced/" + HTTP.REQ.URL.PATH_AND_QUERY.HTTP_URL_SAFE

 

 

Thank you Sam, I always forget about this expression for some reason. I know if Rhonda reads this she will probably shake her head at me and sigh because she has probably told me about this 3-4 different times. :) 

 

I did try that and here is my result. In my browser I typed https://gateway.company.com/gateway/test1234 

 

 

https://gatewayadvanced.company.com/GATEWAYAdvanced/gateway/test1234

 

So it looks to be maintaining the original "gateway" which make sense based on the expression. Is there a way you can think of how to get rid of that URL path? The applications will call the VIP using it, but it will need to come through to the backend as /GATEWAYAdvanced. Its almost like I need to maybe accomplish this with a rewrite as opposed to a redirect? This is my expression after modifying it: 

 

"https://gatewayadvanced.company.com/gatewayAdvanced" + HTTP.REQ.URL.PATH_AND_QUERY.HTTP_URL_SAFE

 

Disregard case in my above examples, I typed it fast. 

 

Link to comment
Share on other sites

Will the user always be entering /gateway/xxxx ?

If so, then does this work ?

"https://gatewayadvanced.company.com/GATEWAYAdvanced/" + HTTP.REQ.URL.PATH_AND_QUERY.HTTP_URL_SAFE.SUBSTR(9,256)

The second number in the SUBSTR needs to be at least as large as the remaining number of characters in the string.

  • Like 1
Link to comment
Share on other sites

Sam's got you started with the expressions.    But if I'm understanding the problem correctly, I don't think its just a redirect or rewrite in this case.  (In general though, if the the client needs to see the change and make a new request REDIRECT/RESPONDER; if you want the change to be server-side only, use a REWRITE.)

 

I initially read your request as trying to add custom paths behind a single gateway vpn vserver (since you said you were consolidating to one vip).  However, if I misunderstood that part, this first part of the discussion is going to be a lot less applicable.  (I tackle the expression part below.)

 

However, one problem you might be running into is that the vpn vserver on the ADC has a LOT of path dependencies including "/" and other paths. You can see these in the default unified gateway content switching rules.  This is one technical reason why you don't put multiple gateways behind the same cs vserver, because there is no separation of paths to tell one gateway from another outside of distinct vips/ports.  

 

I haven't tried this recently, but you manually inserting a /<path1> vs /<path2> may not work because of the rest of the built in traffic flow. (In the past, I have not gotten this to work; but I haven't tried since the 9.x days.  Even using a specific custom path on a single vpn vserver is challenging because of all the other gateway paths present during subsequent requests.)

 

So one gateway with different storefronts work.  But path intercepts on the vpn vserver are tricky because you have a lot of secondary requests that won't look distinct in the default functions or contain the original custom path (even if we are talking about two separate vpn vservers).

 

What you might have to do instead is have the common FQDN direct to a placeholder VIP1 port and then use cs to sort the paths, then use redirect to redirect to gateway1/xxx vs gateway2/gatewayadvanced.  If you have to use the single VIP, run them as two different vpn vservers on separate ports.  The cs vserver would be your tier 1 access point that users overtly see and then it would redirect to gateway1 (vpn1) or gateway2 (vpn2) to handle the rest of your actual traffic flow.

 

Anyway, if the above, was completely off the mark of your original request, then ignore.

 

20 minutes ago, Todd Harrington said:

Thank you Sam, I always forget about this expression for some reason. I know if Rhonda reads this she will probably shake her head at me and sigh because she has probably told me about this 3-4 different times. :) 

Todd, no sighing; I did laugh a little at this comment, but only in sympathy.  :) Not everyone ONLY works on the ADC and this is actually a fairly tricky question.  No worries. 

 

But from a pure expression standpoint, if the path can be manipulated and I'm just overthinking things in the above analysis, then the expression you can also use is:

If you want to make:

[1] https://gateway.example.com/Gateway/<stuff>

into

[2] https://gateway.example.com/GatewayAdvanced/<stuff>

 

The redirect expression could be based on the after_str() operator, if you don't want to deal with substr().  There's more than one way to write most of these expressions:

"https://gateway.example.com/GatewayAdvanced/"  + http.req.url.path_and_query.set_text_mode(ignorecase).after_str("/Gateway/")

  • Like 1
Link to comment
Share on other sites

Rhonda / Sam, 

 

Thank you. I really appreciate the support and the very detailed and informative info. I love context :) 

 

I probably should not have said consolidating the VIPs, that's not completely accurate. This particular environment is really messy and the developers are trying to get rid of some old legacy code. They have 2 different VIPs per application (gateway / gatewayadvanced), why, I have no idea. They handed out the /gateway application VIP to a handful of people over the years and also the /gatewayadvanced to different people. So they are both being consumed.

 

We need to maintain the /gateway VIP as they have no idea which applications are calling it, so I wanted to just provide either a redirect or rewrite to accomplish this. If rewrite then I was going to put the /gatewayadvanced servers behind the /gateway VIP and rewrite the URL. One of their 2 VIPs is a content switching VIP and did a rewrite for that on the URL path, but this is a layer 4 VIP so I changed my thinking to try to make it simple...  

 

It's dirty, I know. I was pushing for looking in the client access logs for IP's (we use RISE/APBR to deliver client IP) and identify the systems hitting the old VIP and just updating code, but that is hard, making the load balancer do it is easier :P  

 

I will play around with your suggestions and see if I can get it to work. 

 

Thanks again

 

EDIT for clarification: 

 

Rhonda, for this example, just to try to make it clearer (if possible, lol) 

 

https://gateway.company.com/gateway - Old legacy VIP, application servers will be going away. 

https://gatewayadvanced.company.com/gatewayadvanced - Newer VIP that I need to deliver old traffic to. 

 

Some applications are coded to call either one. We need to make sure that if the legacy VIP is called, traffic gets to the newer VIP. So in essence the first path in the URL for both VIPs will always stay the same, respectively  ( /gateway -- /gatewayadvanced) but there will be an additional path that gets dynamically generated (after the first path) depending on the content the originating system is calling so I need to maintain that part of the URL as well, this is generally not consumed by users, mainly other applications. 

Link to comment
Share on other sites

Sam / Rhonda, 

 

Can you help me out with a little more detail on the substr function and how exactly that is going to work. I have read through the documentation but for some reason it's not sinking in. The first number in that function represents the total amount of characters before the string I want to replace/remove? Does that start from https:// or the very beginning of the host name? So for example in this URL: 

 

"https://gatewayadvanced.company.com/GATEWAYAdvanced/gateway/test?dynamic?content/" when using the substr would that look like  SUBSTR(53,256) (with HTTPS://) or SUBSTR(45,256) (without HTTPS://) 

 

Last question, using substr like this, will it strip out /gateway and then maintain everything beyond that? Ultimately the end goal URL here is going to be: 

 

https://gatewayadvanced.company.com/GATEWAYAdvanced/test?dynamic?content/

 

Thanks again 

Link to comment
Share on other sites

Sample URLs:

[1] https://gateway.company.com/Gateway/<pathstuff>?<querystuff>

[2] https://gatewayadvanced.company.com/gatewayadvanced/<pathstuff>?<querystuff>

 

So, first:  substring(<offset>,<count>) defines the <starting offset> meaning starting character position to begin the substring action and <count> meaning the next number of characters to grab.  You have to set the length/count to be longer than any possible URL you will receive to grab everything after the starting position (offset).  (That's why I like after_str more as you don't have to worry about a character length. So we'll do both examples:

 

Basic URL elements:

http.req.url   targets path and query in most cases:  /Gateway/<pathstuff>?<querystuff>  OR   /gatewayadvanced/<pathstuff>?<querystuff>

http.req.url.path  targets path of URL only (which usually excludes protocol and host):  /Gateway/<pathstuff> OR   /gatewayadvanced/<pathstuff>

http.requ.url.path_and_query:  /Gateway/<pathstuff>?<querystuff>  OR   /gatewayadvanced/<pathstuff>?<querystuff>

 

So Substring example to extract post "/gateway" elements:

http.req.url.path_and_query.substr(8, 1024)  targets next 1024 chars after the first 8 characters so in url [1]:  /<pathstuff>?<querystuff>

This policy action should verify that your path startswith /gateway/  and not /gatewayadvanced...

http.req.url.path_and_query.substr(16,1024) targets next 1024 chars after the first 16 chars so in url [1]:  /<pathstuff>?<querystuff>

 

Afterstring demos:

http.req.url.path_and_query.set_text_mode(ignorecase).after_str("/gateway")   would yield  from [1]:  /<pathstuff>?<querystuff>

Again, important to make sure policy to trigger this one can distinguish URLs that startwith "/gateway/" to exclude those already containing "/gatewayadvanced/"  (so use trailing "/" in distinguishing clauses in the policy trigger.)

 

http.req.url.path_and_query.set_text_mode(ignorecase).after_str("/gatewayadvanced")   would also yield  from [2]  /<pathstuff>?<querystuff>

 

 

So for a responder policy to redirect requests from '/gateway/<allstuff>' to '/gatewayadvanced/<allstuff>'

Its important that regardless of which expression you use, that you must be able to clearly distinguish urls that are /gateway<stuff> vs /gatewayadvanced (though the separate fqdns should make this less of an issue and you should be able to avoid overlapping scopes...forgot that part when I was drafting this.)

policy expr:  http.req.url.path.set_text_mode(ignorecase).get(1).eq("gateway")     

policy expr alternate:  http.req.url.path.set_text_mode(ignorecase).starts_with("/gateway/")

responder redirect action 1a:  "https://<fqdn>" + http.req.url.path_and_query.set_text_mode(ignorecase).after_str("/gateway")

responder redirect action 1b:  "https://<fqdn>" + http.req.url.path_and_query.substring(8,1024)

 

I wouldn't use a rewrite here, because you are moving from one fqdn (vpn1) to another (vpn2). 

 

 

 

 

 

 

 

 

  • Like 2
Link to comment
Share on other sites

2 hours ago, Rhonda Rowland1709152125 said:

Sample URLs:

[1] https://gateway.company.com/Gateway/<pathstuff>?<querystuff>

[2] https://gatewayadvanced.company.com/gatewayadvanced/<pathstuff>?<querystuff>

 

So, first:  substring(<offset>,<count>) defines the <starting offset> meaning starting character position to begin the substring action and <count> meaning the next number of characters to grab.  You have to set the length/count to be longer than any possible URL you will receive to grab everything after the starting position (offset).  (That's why I like after_str more as you don't have to worry about a character length. So we'll do both examples:

 

Basic URL elements:

http.req.url   targets path and query in most cases:  /Gateway/<pathstuff>?<querystuff>  OR   /gatewayadvanced/<pathstuff>?<querystuff>

http.req.url.path  targets path of URL only (which usually excludes protocol and host):  /Gateway/<pathstuff> OR   /gatewayadvanced/<pathstuff>

http.requ.url.path_and_query:  /Gateway/<pathstuff>?<querystuff>  OR   /gatewayadvanced/<pathstuff>?<querystuff>

 

So Substring example to extract post "/gateway" elements:

http.req.url.path_and_query.substr(8, 1024)  targets next 1024 chars after the first 8 characters so in url [1]:  /<pathstuff>?<querystuff>

This policy action should verify that your path startswith /gateway/  and not /gatewayadvanced...

http.req.url.path_and_query.substr(16,1024) targets next 1024 chars after the first 16 chars so in url [1]:  /<pathstuff>?<querystuff>

 

Afterstring demos:

http.req.url.path_and_query.set_text_mode(ignorecase).after_str("/gateway")   would yield  from [1]:  /<pathstuff>?<querystuff>

Again, important to make sure policy to trigger this one can distinguish URLs that startwith "/gateway/" to exclude those already containing "/gatewayadvanced/"  (so use trailing "/" in distinguishing clauses in the policy trigger.)

 

http.req.url.path_and_query.set_text_mode(ignorecase).after_str("/gatewayadvanced")   would also yield  from [2]  /<pathstuff>?<querystuff>

 

 

So for a responder policy to redirect requests from '/gateway/<allstuff>' to '/gatewayadvanced/<allstuff>'

Its important that regardless of which expression you use, that you must be able to clearly distinguish urls that are /gateway<stuff> vs /gatewayadvanced (though the separate fqdns should make this less of an issue and you should be able to avoid overlapping scopes...forgot that part when I was drafting this.)

policy expr:  http.req.url.path.set_text_mode(ignorecase).get(1).eq("gateway")     

policy expr alternate:  http.req.url.path.set_text_mode(ignorecase).starts_with("/gateway/")

responder redirect action 1a:  "https://<fqdn>" + http.req.url.path_and_query.set_text_mode(ignorecase).after_str("/gateway")

responder redirect action 1b:  "https://<fqdn>" + http.req.url.path_and_query.substring(8,1024)

 

I wouldn't use a rewrite here, because you are moving from one fqdn (vpn1) to another (vpn2). 

 

 

 

 

 

 

 

 

 

I really appreciate you taking the time for this. This helps immensely.  

Link to comment
Share on other sites

Another suggestion: apply a responder policy to the old FQDN, and respond with a page from the netscaler.... that page would say "Look, punk, stop using this URL - update your bookmarks or that yellow sticky on your screen to use the NEW URL, which we've told you about many times... it is of course: https://newfqdn"

 

That will quickly get rid of any traffic to the old FQDN!!!

 

(ok, may be a more Politically Correct response text is needed!)

Link to comment
Share on other sites

6 minutes ago, Paul Blitz said:

Another suggestion: apply a responder policy to the old FQDN, and respond with a page from the netscaler.... that page would say "Look, punk, stop using this URL - update your bookmarks or that yellow sticky on your screen to use the NEW URL, which we've told you about many times... it is of course: https://newfqdn"

 

That will quickly get rid of any traffic to the old FQDN!!!

 

(ok, may be a more Politically Correct response text is needed!)

 

Lol Paul, I wish.... you have no idea, the things we have to do to accommodate...   

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...