Forum Discussion

yuanqiang_22112's avatar
yuanqiang_22112
Icon for Nimbostratus rankNimbostratus
Aug 08, 2016

irulse for http request

Hello everyone : please help me check the irules , it is right ?

 

when HTTP_REQUEST { if { [HTTP::host] equals "gp.study.teacheredu.cn" } { pool gp_study_teacheredu } elseif { [HTTP::uri] equals "http://study.teacheredu.cn/proj/proj/tlogin/hbGp?token=" }{ pool study_teacheredu_gpnl } elseif { [HTTP::uri] equals "http://study.teacheredu.cn/proj/proj/tlogin/hbNl?token=" }{ pool study_teacheredu_gpnl } else { pool study_teacheredu } }

 

4 Replies

  •  

    when HTTP_REQUEST { 
       if { [HTTP::host] equals "gp.study.teacheredu.cn" } { 
          pool gp_study_teacheredu 
       } elseif { [HTTP::uri] equals "http://study.teacheredu.cn/proj/proj/tlogin/hbGp?token=" } { 
          pool study_teacheredu_gpnl 
       } elseif { [HTTP::uri] equals "http://study.teacheredu.cn/proj/proj/tlogin/hbNl?token=" } { 
          pool study_teacheredu_gpnl 
       } else { 
          pool study_teacheredu 
       } 
    }
    

     

    Maybe try it this way...

     

    when HTTP_REQUEST {
       if { [string tolower [HTTP::host]] equals "gp.study.teacheredu.cn" } {
          pool gp_study_teacheredu
       } else {
          switch -glob [HTTP::uri] {
             "/proj/proj/tlogin/hbGp?token=*" { 
                pool study_teacheredu_gpnl 
             }
             "/proj/proj/tlogin/hbNl?token=*" { 
                pool study_teacheredu_gpnl 
             }
             default { 
                pool study_teacheredu 
             }
          }
       }
    }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
    

     

    • ekaleido's avatar
      ekaleido
      Icon for Cirrus rankCirrus

      I don't know that it was wrong, I just changed the HTTP::uri lines and changed to a switch instead of elsif to make it a little easier to read.

       

  • @yuanqiang, there are two issues with the original iRule. Our use of the term "uri" in HTTP::uri is a bit of a misnomer. All URLs are instances of a URI, and while RFC 7230 refers to the requested object as a "Request-Target", RFC 2616 much more ambiguously referred to it as a "Request-URI". That is, when an HTTP Request Start-Line is:

    GET /foo/bar/baz.html?this=that&here=there HTTP/1.1

    /foo/bar/baz.html?this=that&here=there is the Request-Target according to RFC 7230, but is called the Request-URI in RFC 2616. However, let's say the User-Agent made the following request:

    http://www.f5.com/foo/bar/baz.html?this=that&here=there

    That would be the URL, and at the same time, the URI for the request.

    Why all of this pedantic background? Well, while the absolute URL is in fact the URI, because of the age of iRules, F5 uses HTTP::uri to identify the Request-Target (aka, the Request-URI), not the absolute URL/URI.

    In your code above, you do this, for example:

     

    elseif { [HTTP::uri] equals "http://study.teacheredu.cn/proj/proj/tlogin/hbGp?token="
    

     

    That, however, will never match a request. Let us say that the user requested:

     

    http://study.teacheredu.cn/proj/proj/tlogin/hbGp?token=
    

     

    Then the following would be true:

     

    HTTP::method       == GET
    HTTP::host         == study.teacheredu.cn
    HTTP::header host  == study.teacheredu.cn
    HTTP::uri          == /proj/proj/tlogin/hbGp?token=
    HTTP::path         == /proj/proj/tlogin/hbGp
    HTTP::query        == token=
    

     

    There is no way to retrieve the exact URL entered in the User-Agent URL bar because that's not how the User-Agent will send it (unless the BIG-IP is configured to operate as an HTTP forward proxy and the User-Agent knows that). Instead, the request above would be sent in an HTTP Request message as follows:

     

    GET /proj/proj/tlogin/hbGp?token= HTTP/1.1
    Host: study.teacheredu.cn
      ... other headers here ...
    

     

    The second issue with your original iRule is a bit more subtle. All of the following are equivalent hostnames:

     

    study.teacheredu.cn
    STUDY.TEACHEREDU.CN
    sTuDy.TeAcHeReDu.Cn
    

     

    That is, hostnames are case indifferent. Thus, you should normalize the case when comparing hostnames (incidentally, this is NOT true for the Request-Target; those ARE case-sensitive, though some filesystems may not treat them as such). @ekaleido solves this in the usual fashion with the to string as part of the switch.

    I hope you find this helpful :).