Forum Discussion

Moinul_Rony's avatar
Moinul_Rony
Icon for Altostratus rankAltostratus
May 15, 2014

How to destroy and replace a URI query value ?

Hi,

 

I am trying to figure out how I can replace a URI query value.

 

For example for this we will select the URL based on the HTTP:host

 

Incoming URL pattern

 

https://host/URI? https://host/URI?query=any_value

 

Rewrite URL https://host/URI?query=ReplacedValue

 

Can this be done?

 

What I have done is as follows which looks for anything matching the URI and does a rewrite does not really match my requirement

 

when HTTP_REQUEST {

 

if { [string tolower [HTTP::host]] contains "host" } { switch -glob [string tolower [HTTP::uri]] { "/URI*" { log local0. "Incoming URI = [HTTP::uri]" log local0. "URI Query = [URI::query [HTTP::uri]]" HTTP::uri "/URI?query=ReplacedValue" log local0. "Changed URI = [HTTP::uri]" } } } }

 

Thanks.

 

14 Replies

  • It works only the server side. (consider change "/URI" to "/uri" on switch statement first). Maybe you will need to redirect to the new uri address to affect the client side.

     

  • when HTTP_REQUEST { if {([HTTP::uri] contains "query=any_value") } { HTTP::redirect "https://host/URI?query=ReplacedValue" } }

     

    I think this should work.

     

    -PK

     

    • Moinul_Rony's avatar
      Moinul_Rony
      Icon for Altostratus rankAltostratus
      Thanks p1hbatia, By "any_value or *" i meant regardless of any value the Query has it should always redirect to the destination.
  • when HTTP_REQUEST { if {([HTTP::uri] contains "query=any_value") } { HTTP::redirect "https://host/URI?query=ReplacedValue" } }

     

    I think this should work.

     

    -PK

     

    • Moinul_Rony's avatar
      Moinul_Rony
      Icon for Altostratus rankAltostratus
      Thanks p1hbatia, By "any_value or *" i meant regardless of any value the Query has it should always redirect to the destination.
  • what about this?

    e.g.

     config
    
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm virtual bar
    ltm virtual bar {
        destination 172.28.24.10:80
        ip-protocol tcp
        mask 255.255.255.255
        pool foo
        profiles {
            http { }
            tcp { }
        }
        rules {
            qux
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        vs-index 26
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm pool foo
    ltm pool foo {
        members {
            200.200.200.101:80 {
                address 200.200.200.101
            }
        }
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm rule qux
    ltm rule qux {
        when HTTP_REQUEST {
      set q [URI::query [HTTP::uri] query]
      if { $q ne "" } {
        HTTP::uri [string map "$q ReplacedValue" [HTTP::uri]]
      }
    }
    }
    
     trace
    
    [root@ve11a:Active:In Sync] config  ssldump -Aed -nni 0.0 port 80
    New TCP connection 1: 172.28.24.1(37391) <-> 172.28.24.10(80)
    1400340463.6588 (0.0033)  C>S
    ---------------------------------------------------------------
    GET /URI?query=any_value&other=somethingelse HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Host: 172.28.24.10
    Accept: */*
    
    ---------------------------------------------------------------
    
    New TCP connection 2: 200.200.200.14(37391) <-> 200.200.200.101(80)
    1400340463.6622 (0.0016)  C>S
    ---------------------------------------------------------------
    GET /URI?query=ReplacedValue&other=somethingelse HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Host: 172.28.24.10
    Accept: */*
    
    ---------------------------------------------------------------
    
    • Moinul_Rony's avatar
      Moinul_Rony
      Icon for Altostratus rankAltostratus
      Thanks nitass, I wanted the irule to look for query=A in the URI and replace query=A to query=B Could I try using the condition if { $q eq "query=A" } { HTTP::uri [string map "$q Query=B" [HTTP::uri]] }
  • what about this?

    e.g.

     config
    
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm virtual bar
    ltm virtual bar {
        destination 172.28.24.10:80
        ip-protocol tcp
        mask 255.255.255.255
        pool foo
        profiles {
            http { }
            tcp { }
        }
        rules {
            qux
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        vs-index 26
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm pool foo
    ltm pool foo {
        members {
            200.200.200.101:80 {
                address 200.200.200.101
            }
        }
    }
    root@(ve11a)(cfg-sync In Sync)(Active)(/Common)(tmos) list ltm rule qux
    ltm rule qux {
        when HTTP_REQUEST {
      set q [URI::query [HTTP::uri] query]
      if { $q ne "" } {
        HTTP::uri [string map "$q ReplacedValue" [HTTP::uri]]
      }
    }
    }
    
     trace
    
    [root@ve11a:Active:In Sync] config  ssldump -Aed -nni 0.0 port 80
    New TCP connection 1: 172.28.24.1(37391) <-> 172.28.24.10(80)
    1400340463.6588 (0.0033)  C>S
    ---------------------------------------------------------------
    GET /URI?query=any_value&other=somethingelse HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Host: 172.28.24.10
    Accept: */*
    
    ---------------------------------------------------------------
    
    New TCP connection 2: 200.200.200.14(37391) <-> 200.200.200.101(80)
    1400340463.6622 (0.0016)  C>S
    ---------------------------------------------------------------
    GET /URI?query=ReplacedValue&other=somethingelse HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Host: 172.28.24.10
    Accept: */*
    
    ---------------------------------------------------------------
    
    • Moinul_Rony's avatar
      Moinul_Rony
      Icon for Altostratus rankAltostratus
      Thanks nitass, I wanted the irule to look for query=A in the URI and replace query=A to query=B Could I try using the condition if { $q eq "query=A" } { HTTP::uri [string map "$q Query=B" [HTTP::uri]] }
  • e.g.

     config
    
    [root@ve11a:Active:In Sync] config  tmsh list ltm rule qux
    ltm rule qux {
        when HTTP_REQUEST {
      set q [URI::query [HTTP::uri] query]
      log local0. "q = $q"
      if { $q eq "A" } {
        log local0. "origin uri = [HTTP::uri]"
        HTTP::uri [string map "query=$q query=B" [HTTP::uri]]
        log local0. "new uri = [HTTP::uri]"
      }
    }
    }
    
     /var/log/ltm
    
    [root@ve11a:Active:In Sync] config  tail -f /var/log/ltm
    May 18 21:32:58 ve11a info tmm[14715]: Rule /Common/qux : q = A
    May 18 21:32:58 ve11a info tmm[14715]: Rule /Common/qux : origin uri = /URI?query=A&other=somethingelse
    May 18 21:32:58 ve11a info tmm[14715]: Rule /Common/qux : new uri = /URI?query=B&other=somethingelse
    
    • Moinul_Rony's avatar
      Moinul_Rony
      Icon for Altostratus rankAltostratus
      Thanks nitass, that works perfectly. But now I have a slightly different requirement matching on the incoming hostname (red.x.com) I would want to add a value such as code=red and replace anything else with code=red example: Case 1: code=yellow gets replaced with code=red https://red.x.com/test/find.jsp?dodgy=bla&class=XY&code=yellow&run=Y&state=QLD should change to https://red.x.com/test/find.jsp?dodgy=bla&class=XY&code=red&run=Y&state=QLD code=red value not present -> add to the end of the URI https://red.x.com/test/find.jsp?dodgy=bla&class=XY&run=Y&state=QLD should change to https://red.x.com/test/find.jsp?dodgy=bla&class=XY&run=Y&state=QLD&code=red
  • e.g.

     config
    
    [root@ve11a:Active:In Sync] config  tmsh list ltm rule qux
    ltm rule qux {
        when HTTP_REQUEST {
      set q [URI::query [HTTP::uri] query]
      log local0. "q = $q"
      if { $q eq "A" } {
        log local0. "origin uri = [HTTP::uri]"
        HTTP::uri [string map "query=$q query=B" [HTTP::uri]]
        log local0. "new uri = [HTTP::uri]"
      }
    }
    }
    
     /var/log/ltm
    
    [root@ve11a:Active:In Sync] config  tail -f /var/log/ltm
    May 18 21:32:58 ve11a info tmm[14715]: Rule /Common/qux : q = A
    May 18 21:32:58 ve11a info tmm[14715]: Rule /Common/qux : origin uri = /URI?query=A&other=somethingelse
    May 18 21:32:58 ve11a info tmm[14715]: Rule /Common/qux : new uri = /URI?query=B&other=somethingelse
    
    • Moinul_Rony's avatar
      Moinul_Rony
      Icon for Altostratus rankAltostratus
      Thanks nitass, that works perfectly. But now I have a slightly different requirement matching on the incoming hostname (red.x.com) I would want to add a value such as code=red and replace anything else with code=red example: Case 1: code=yellow gets replaced with code=red https://red.x.com/test/find.jsp?dodgy=bla&class=XY&code=yellow&run=Y&state=QLD should change to https://red.x.com/test/find.jsp?dodgy=bla&class=XY&code=red&run=Y&state=QLD code=red value not present -> add to the end of the URI https://red.x.com/test/find.jsp?dodgy=bla&class=XY&run=Y&state=QLD should change to https://red.x.com/test/find.jsp?dodgy=bla&class=XY&run=Y&state=QLD&code=red
  • e.g.

     

     config
    
    [root@ve11a:Active:In Sync] config  tmsh list ltm rule qux
    ltm rule qux {
        when HTTP_REQUEST {
      if { [HTTP::host] eq "red.x.com" } {
        set q [URI::query [HTTP::uri] code]
    
        if { $q ne "" } {
          HTTP::uri [string map "$q red" [HTTP::uri]]
        } else {
          HTTP::uri "[HTTP::uri]&code=red"
        }
      }
    }
    }
    
     test1 http://red.x.com/test/find.jsp?dodgy=bla&class=XY&code=yellow&run=Y&state=QLD
    
    [root@ve11a:Active:In Sync] config  ssldump -Aed -nni 0.0 port 80
    New TCP connection 1: 172.28.24.1(38911) <-> 172.28.24.10(80)
    1401160959.5768 (0.0019)  C>S
    ---------------------------------------------------------------
    HEAD /test/find.jsp?dodgy=bla&class=XY&code=yellow&run=Y&state=QLD HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Accept: */*
    Host: red.x.com
    
    ---------------------------------------------------------------
    
    New TCP connection 2: 200.200.200.14(38911) <-> 200.200.200.101(80)
    1401160959.6111 (0.0340)  C>S
    ---------------------------------------------------------------
    HEAD /test/find.jsp?dodgy=bla&class=XY&code=red&run=Y&state=QLD HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Accept: */*
    Host: red.x.com
    
    ---------------------------------------------------------------
    
     test2 http://red.x.com/test/find.jsp?dodgy=bla&class=XY&run=Y&state=QLD
    
    [root@ve11a:Active:In Sync] config  ssldump -Aed -nni 0.0 port 80
    New TCP connection 1: 172.28.24.1(38912) <-> 172.28.24.10(80)
    1401161017.7365 (0.0039)  C>S
    ---------------------------------------------------------------
    HEAD /test/find.jsp?dodgy=bla&class=XY&run=Y&state=QLD HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Accept: */*
    Host: red.x.com
    
    ---------------------------------------------------------------
    
    New TCP connection 2: 200.200.200.14(38912) <-> 200.200.200.101(80)
    1401161017.7606 (0.0239)  C>S
    ---------------------------------------------------------------
    HEAD /test/find.jsp?dodgy=bla&class=XY&run=Y&state=QLD&code=red HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Accept: */*
    Host: red.x.com
    
    ---------------------------------------------------------------
    
     test3 http://red.x.com/test/find.jsp?dodgy=bla&class=XY&code=red&run=Y&state=QLD
    
    [root@ve11a:Active:In Sync] config  ssldump -Aed -nni 0.0 port 80
    New TCP connection 1: 172.28.24.1(38913) <-> 172.28.24.10(80)
    1401161081.6554 (0.0019)  C>S
    ---------------------------------------------------------------
    HEAD /test/find.jsp?dodgy=bla&class=XY&code=red&run=Y&state=QLD HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Accept: */*
    Host: red.x.com
    
    ---------------------------------------------------------------
    
    New TCP connection 2: 200.200.200.14(38913) <-> 200.200.200.101(80)
    1401161081.6615 (0.0018)  C>S
    ---------------------------------------------------------------
    HEAD /test/find.jsp?dodgy=bla&class=XY&code=red&run=Y&state=QLD HTTP/1.1
    User-Agent: curl/7.15.5 (i686-redhat-linux-gnu) libcurl/7.15.5 OpenSSL/0.9.8b zlib/1.2.3 libidn/0.6.5
    Accept: */*
    Host: red.x.com
    
    ---------------------------------------------------------------