Forum Discussion

Alexander_01_13's avatar
Alexander_01_13
Icon for Nimbostratus rankNimbostratus
Oct 31, 2014

irule for choosing pool and rewriting

Hi experts,

I need to write an irule for the following rewriting task.

 

http://host.domain.tld/example1/appname >> http://[example1_pool]/appname
http://host.domain.tld/example2/appname >> http://[example2_pool]/appname
http://host.domain.tld/example3/appname >> http://[example3_pool]/appname

 

So depending on the uri I want to choose the pool and also remove the portion between the first and second slash ("/example1").

The application listens on http://[backend_pool]/appname

The following irule does not do the job yet. Do I have to rewrite the answer also on event HTTP_RESONSE? Do I have to use the "STREAM" command?

Any help is appreciated! Regards, Alexander

 

when HTTP_REQUEST { 
    switch -glob -- [string tolower [HTTP::uri]] {
        "/example1" {
             redirect 
            HTTP::redirect http://[HTTP::host]/example1/appname
        }
        "/example1/*" {
        HTTP::uri [string map {"/example1" ""} [HTTP::uri]]
            pool APPNAME_POOL_example1
        }
        default {
             This final section takes all traffic that has not otherwise
             been accounted for 
            pool wwwserver_pool
        }
    }
}

 

6 Replies

  • Hi Alexander, do you think that ltm rewrite profile could be easier for you ? it is available starting 11.4 and can do this rewriting from gui. With ltm policy, you could do the pool selection as well from the gui.

     

  • I recommend doing a TCPDUMP of the traffic in both directions. If your response does not have the "/example1/*" in the uri when it replies then you could be getting redirected to the wwwserver_pool.

     

    Jason

     

  •  

    when HTTP_REQUEST {
     set HOST [string tolower [HTTP::host]]
      set HOST [string tolower [HTTP::uri]]
    
       if { ($HOST eq "host.domain.tld") and ($URI eq "/example1/appname")} {
           HTTP::uri  [string map {"/example1" ""} [HTTP::uri]]
             HTTP::host [string map {"host.domain.tld" "example1_pool"} [HTTP::host]]
             pool APPNAME_POOL_example1
    
       }
    }
    

     

    You would have to run some curl commands to figure out the response from the servers and possibly make changes to the response headers.

  • Hi Odaah,

    the code you provided does not rewrite the html response. So the first html page is loaded but the links to graphics etc. are broken.

    How can I change the response headers? The commands do not work similarly: 01070151:3: Rule [/projects/host.domain.tld_rewrite_irule] error: /projects/host.domain.tld_rewrite_irule:11: error: [command is not valid in current event context (HTTP_RESPONSE)][HTTP::host]

    Regards, Alex

  • this is just an example. it may not fully be what you are looking for but hope it helps.

     

     configuration
    
    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 { }
            stream { }
            tcp { }
        }
        rules {
            qux
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        vs-index 3
    }
    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 {
      STREAM::disable
      HTTP::header remove "Accept-Encoding"
    
      switch -glob -- [HTTP::uri] {
        "/example1/*" {
          HTTP::uri [string map {"/example1" ""} [HTTP::uri]]
          HTTP::host "example1.domain.tld"
        }
        default {
           do something
        }
      }
    }
    when HTTP_RESPONSE {
      if { [HTTP::header value Content-Type] contains "text" } {
        STREAM::expression {@http://example1.domain.tld@http://host.domain.tld/example1@@http://example2.domain.tld@http://host.domain.tld/example2@}
        STREAM::enable
      }
    }
    }
    
     original response
    
    [root@ve11a:Active:In Sync] config  curl http://200.200.200.101/test.html
    1:http://www.google.com
    2:http://example1.domain.tld/something
    3:http://example2.domain.tld/somethingelse
    4:http://www.yahoo.com
    
     trace
    
    [root@ve11a:Active:In Sync] config  ssldump -Aed -nni 0.0 port 80
    New TCP connection 1: 172.28.24.1(38472) <-> 172.28.24.10(80)
    1415022550.4740 (0.0014)  C>S
    ---------------------------------------------------------------
    GET /example1/test.html 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(38472) <-> 200.200.200.101(80)
    1415022550.4755 (0.0013)  C>S
    ---------------------------------------------------------------
    GET /test.html 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: example1.domain.tld
    Accept: */*
    
    ---------------------------------------------------------------
    
    1415022550.4778 (0.0022)  S>C
    ---------------------------------------------------------------
    HTTP/1.1 200 OK
    Date: Mon, 03 Nov 2014 13:34:43 GMT
    Server: Apache/2.2.3 (CentOS)
    Last-Modified: Mon, 03 Nov 2014 12:57:04 GMT
    ETag: "418999-81-e21e2800"
    Accept-Ranges: bytes
    Content-Length: 129
    Content-Type: text/html; charset=UTF-8
    
    1:http://www.google.com
    2:http://example1.domain.tld/something
    3:http://example2.domain.tld/somethingelse
    4:http://www.yahoo.com
    ---------------------------------------------------------------
    
    1415022550.4781 (0.0041)  S>C
    ---------------------------------------------------------------
    HTTP/1.1 200 OK
    Date: Mon, 03 Nov 2014 13:34:43 GMT
    Server: Apache/2.2.3 (CentOS)
    Last-Modified: Mon, 03 Nov 2014 12:57:04 GMT
    ETag: "418999-81-e21e2800"
    Accept-Ranges: bytes
    Content-Type: text/html; charset=UTF-8
    Transfer-Encoding: chunked
    
    8b
    1:http://www.google.com
    2:http://host.domain.tld/example1/something
    3:http://host.domain.tld/example2/somethingelse
    4:http://www.yahoo.com
    
    ---------------------------------------------------------------
    

     

  • Hi,

    I would like to share the solution we have finally found. We changed the rewriting task to a redirecting task. We do the following redirects:

     

     >> 
     >> 
     >> 
    

     

    For each exampleX we create a DNS entry and in the irule we switch the pool by the hostname. For encryption we get a wildcard certificate, which does not impose much of a security concern, because the domain.tld is used exclusively for this virtual server.

    Thanks to all for helping!

    Regards, Alex