Forum Discussion

atoth's avatar
atoth
Icon for Cirrus rankCirrus
May 01, 2015

Writing and Rewriting a URI

I've got a vip similar to the below.

when HTTP_REQUEST {`
switch -glob [HTTP::path] {
"/a/b/c" - 
"/blah/blah/blah"  {
HTTP::header replace "Host" "internal.domain.com"
pool redirect-pool
snat automap
}  default { pool default-pool }
}
}
when HTTP_RESPONSE {
if { [HTTP::is_redirect] } {
HTTP::header replace "Host" "external.domain.com"
}
}

What the customer would like to do now is rewrite "/blah/blah/blah" to either "/a/b/c" or "/" and when the traffic returns, rewrite the uri to what it was originally. Is this possible? How would I go about doing something like this?

7 Replies

  • What the customer would like to do now is rewrite "/blah/blah/blah" to either "/a/b/c" or "/"

     

    you can change (rewrite) uri sending to server (pool member) by using HTTP::uri command.

     

    HTTP::uri

     

    https://devcentral.f5.com/wiki/iRules.HTTP__uri.ashx

     

    when the traffic returns, rewrite the uri to what it was originally.

     

    response does not have uri. uri is in request.

     

  • So I can rewrite the uri, but my impression from the customer is that he doesn't want the rewritten URI to be seen by the client's browser. He wants the end server(s) to see it, but not the not the client.

     

    As for the Stream profile, this would be something I need to enable on the VIP itself, before I use it in the irule, correct? Since this VIP already has a HTTP profile, it seems like Stream would only work on the HTTP payload, but not the headers.

     

  • As for the Stream profile, this would be something I need to enable on the VIP itself, before I use it in the irule, correct?

     

    yes

     

    Since this VIP already has a HTTP profile, it seems like Stream would only work on the HTTP payload, but not the headers.

     

    yes. if uri is not embedded in response body, you do not need stream profile. you can rewrite response header by using HTTP::header command which you already used in your irule.

     

  • So the one thing that still concerns me. Not sure if I'm misunderstanding the problem, but it seem to me this would be the flow.

    Client -> "/a/b/c" -> Vip(redirects to pool redirect-pool) -> Servers.

    That's fine but if i rewrite the irule so that /blah/blah/blah is rewritten as /a/b/c, when the traffic returns from the servers, I want to rewrite the uri back to what it was originally. I can do this based on what? Unfortunately, all I know how how to do this is based on uri as well. So...

    Client -> "/blah/blah/blah/" -> VIP(uri is rewritten as "/a/b/c" and sent to redirect-pool) -> Servers -> VIP(rewritten to "/blah/blah/blah/") -> Client

    Client -> "/a/b/c" -> Vip(redirects to pool redirect-pool) -> Servers - > VIP(also rewritten as "/blah/blah/blah/") -> Client

    In the first case its "/blah/blah/blah/" is rewritten back to "/blah/blah/blah/" on its return trip. On the second case "/a/b/c" is also rewritten as "/blah/blah/blah/" on its return trip, something thats not desirable.

    If instead "/blah/blah/blah/" is rewritten to "/", on the return trip, all redirected traffic is still rewritten as "/blah/blah/blah", which wouldn't be good either.

    Am I misunderstanding the situation here?

  • The client browser needs to see "/blah/blah/blah" as the uri for the entire length of the session, but when the VIP redirects the request, the pool servers need to see "/a/b/c" as the uri instead.

     

  • After brainstorming with some coworkers, we came up with this.

    when HTTP_REQUEST {
    set uri_redirect 0
    switch -glob [HTTP::path] {
    "/blah/blah/blah*" {
    set uri_redirect 1
    HTTP::header replace "Host" "external.domain.com"
    HTTP::redirect "https:// [getfield [HTTP::host] ":" 1][string map {/blah/blah/blah /a/b/c } [HTTP::path]]"
    pool redirect-pool
    snat automap
    } "/a/b/c*" {
    set uri_redirect 0
    HTTP::header replace "Host" "external.domain.com"
    pool redirect-pool
    snat automap
    } default { pool default-pool }
    }
    }
    when HTTP_RESPONSE {
    if { [HTTP::is_redirect] } {
    if { $uri_redirect == 1 } { HTTP::header replace "Host" "internal.domain.com"
    HTTP::redirect "https:// [getfield [HTTP::host] ":" 1 ][string map { /a/b/c /blah/blah/blah } [HTTP::path]]"
    } else {
    HTTP::header replace "Host" "internal.domain.com"
    }
    }
    }
    

    However, after trying it out in the editor and fixing a bunch of errors, I still get

    line 21: [command is not valid in current event context (HTTP_RESPONSE)] [HTTP::host]
    line 21: [command is not valid in current event context (HTTP_RESPONSE)] [HTTP::path]
    

    Anyone know of a way of rewriting the URI without resorting to using [HTTP::host] or [HTTP::path] ?