Forum Discussion

C_D_18583's avatar
C_D_18583
Icon for Nimbostratus rankNimbostratus
Nov 20, 2006

Replacing in the URI ; http -> https and port 80 -> 443

 

What is the easiest way to rewrite the following string? Replacing in the URI http -> https and port 80 -> 443

 

 

Before:

 

 

https://testlab-d.tdx.dorion.com/amserver/UI/Login?goto=http%3A%2F%2Ftestlab-d.tdx.dorion.com%3A80%2Fperform%2FLogin.do%3FLANGUAGE%3DEN

 

 

After:

 

 

https://testlab-d.tdx.dorion.com/amserver/UI/Login?goto=https%3A%2F%2Ftestlab-d.tdx.dorion.com%3A443%2Fperform%2FLogin.do%3FLANGUAGE%3DEN

 

 

Thanks in Advance!

18 Replies

  • Hi Aaron

     

     

    I'm really at a loss on this. Okay here goes. I trying to substitute specific stings in a URL as follows

     

     

    Before URL that hits F5 from the client

     

     

    https://secureinternal-d.tmi.telus.com/amserver/UI/Login?goto=http%3A%2F%2Fsecureinternal-d.tmi.telus.com%3A40%2Feperformance%2FLogin.do%3FLANGUAGE%3DEN

     

     

    Desire is to change the URL to look like this

     

     

    https://secureinternal-d.tmi.telus.com/amserver/UI/Login?goto=https%3A%2F%2Fsecureinternal-d.tmi.telus.com%3A443%2Feperformance%2FLogin.do%3FLANGUAGE%3DEN

     

     

     

    What I found using your latest suggestion

     

     

    when HTTP_REQUEST {

     

    if {[HTTP::uri] contains "goto"} {

     

    HTTP::query [string map {goto=http% goto=https% %3A80% %3A443%} [HTTP::query]]

     

    }

     

    }

     

     

    is that the string map on the HTTP::query removes all strings before the first substitution in my case goto

     

     

    goto=https%3A%2F%2Fsecureinternal-d.tmi.telus.com%3A443%2Feperformance%2FLogin.do%3FLANGUAGE%3DEN

     

     

    What I need to do is somehow build a full URL either on the fly and send to the downstream node or through a 302 redirect. So my questions are

     

     

    1.) How do I build the full URL?

     

     

    Hope this helps

     

    Steve

     

  • Hi Aaron;

     

     

    The latest.

     

     

    The iRule I tested with is

     

     

    big ip rule

     

     

    RULE NAME: D3_INT1_SECURE_REDIRECT_NEW

     

    VERSION : 1.0

     

     

    when HTTP_REQUEST {

     

    if {[HTTP::uri] contains "goto" and [HTTP::uri] contains "eperformance"} {

     

    HTTP::uri [string map {goto=http% goto=https% %3A80% %3A443%} [HTTP::uri]]

     

    log local0. "The cached uri is [HTTP::uri]"

     

    pool D2_INT1_IDENTITY

     

    }

     

    elseif { [HTTP::uri] starts_with "/eperformance/" } {

     

    persist source_addr 1800

     

    pool D3_INT1_EMPLOYEE_8

     

    }

     

    elseif { [HTTP::uri] starts_with "/amserver/" } {

     

    persist source_addr 1860

     

    pool D2_INT1_IDENTITY

     

    }

     

    elseif { [HTTP::uri] starts_with "/amconsole/" } {

     

    persist source_addr 1860

     

    pool D2_INT1_IDENTITY

     

    }

     

    }

     

     

     

    Verified back end node (D2_INT1_IDENTITY) is getting the correct URI

     

     

    172.23.106.13 - - [27/Nov/2006:08:58:10 -0500] "GET

     

     

    /amserver/UI/Login?goto=https%3A%2F%2Fsecureinternal-d.tmi.telus.com%3A443%2Feperformance%2FLogin.do%3FLANGUAGE%3DEN

     

     

    HTTP/1.1" 200 7773

     

     

     

    However problem is client browser still passing incorrect uri. Do I need to change my rule logic to redirect the new HTTP::uri instead of doing the string substitution then forwarding traffic to the D2_INT1_IDENTITY pool

     

     

     

    Onward I go

     

    Steve
  • Hi Aaron;

     

     

    Still having challenges. When add the HTTP_RESPONSE event F5 does not respond to the HTTP get from client browser. Firefox live headers shows request GET https://secureinternal-d.tmi.telus.com/eperformance/Login.do?LANGUAGE=EN

     

     

    Thx

     

    Steve

     

     

    My rule is now

     

     

    when HTTP_RESPONSE {

     

    if { [HTTP::status] starts_with "3" and [HTTP::header "Location"] != ""} {

     

    HTTP::header "Location" [string map { goto=http% goto=https% %3A80% %3A443% } [HTTP::header "Location"] ]

     

    }

     

    }

     

    when HTTP_REQUEST {

     

    if { [HTTP::uri] starts_with "/eperformance/" } {

     

    persist source_addr 1800

     

    pool D3_INT1_EMPLOYEE_8

     

    }

     

    elseif { [HTTP::uri] starts_with "/amserver/" } {

     

    persist source_addr 1860

     

    pool D2_INT1_IDENTITY

     

    }

     

    elseif { [HTTP::uri] starts_with "/amconsole/" } {

     

    persist source_addr 1860

     

    pool D2_INT1_IDENTITY

     

    }

     

    }
  • I'll take a closer look at your files and see what I find.

     

     

    Aaron
  • Thanks Aaron

     

     

    In parallel, I'll open a support ticket with F5 given the complex nature of the problem and the solution not readily apparent.

     

     

    Steve
  • A couple of comments on your final code

     

     

    1) If you are going to log the modified value in the response, then use a temporary variable instead of calling the "string map" command twice. Two temporary variables are created and you have the extra overhead of scanning and replacing in the string twice. If you end up removing the log statement then you can leave the HTTP::header replace command as-is.

     

     

    when HTTP_RESPONSE {
      log local0. "response code: [HTTP::status], Location: [HTTP::header Location]"
      if { [HTTP::status] starts_with "3" and [HTTP::header "Location"] != ""} {
        set new_loc [string map { goto=http% goto=https% %3A80% %3A443% } [HTTP::header "Location"] ]
        log local0. "New location: $new_loc"
        HTTP::header replace "Location" $new_loc
      }
    }

     

     

    2) Since two of your cases in the switch have the same enclosing code, then you can combine them as follows:

     

     

    when HTTP_REQUEST {
      switch -glob [string tolower [HTTP::uri]] {
        "/eperformance/*" {
          persist source_addr 1800
          pool D3_INT1_EMPLOYEE_8
        }
        "/amserver/*" -
        "/amconsole/*" {
          persist source_addr 1860
          pool D2_INT1_IDENTITY
        }
        default {
          discard
        }
      }
    }

     

     

    The dash after the string tells the switch to treat it as a logical or between the two. You can combine as many of these as you want together if more come up, just add a dash to the end of each match string with the code tacked on to the last one. Not a big deal, but it does make the rule a bit smaller and more readable.

     

     

    -Joe
  • Hi Steve,

     

    This is the rule I use successfully to detect a string in the URI & then replace it with another string. This sounds like waht you are trying to do.

     

     

    when HTTP_REQUEST {

     

    if { [HTTP::uri] contains "/oma"} {

     

    HTTP::redirect "https://[HTTP::host]/oma"}

     

    else {

     

    HTTP::redirect "https://[HTTP::host]/exchange"

     

    }

     

    }