Forum Discussion

Rusty_Hale_8009's avatar
Rusty_Hale_8009
Icon for Nimbostratus rankNimbostratus
Jan 25, 2005

Help getting iRule to persist on info in the payload

I need to be able to go down into the payload and grab a hash value and then use that value to persist with. I have a base rule that I am testing just to get my syntax right.

 

 

when HTTP_REQUEST_DATA {

 

set content_length 429496

 

HTTP::collect $content_length

 

set rpc-id {[findstr [HTTP::payload] "Authorization:" 14, 20]}

 

log local0. "WE RECORDED [$rpc-id] AS THE PERSIST VARIABLE"

 

HTTP::release

 

}

 

 

The app is actually rpc over http for Exchange 2003. Since RPC over http does not have a http header, I have to find a value in the payload and use that to persist with. With Ethereal, I found an authenication hash value but my rule keeps giving me an error:

 

 

TCL error: Rule rpc-persist - can't read "rpc": no such variable while executing "log local0. "WE RECORDED $rpc-id AS THE PERSIST VARIABLE""

 

 

Right now, I am just trying to get a value into the variable. I have not even attempted to add the code to do the persistence. Any help would be appreciated. Thanks.
  • bl0ndie_127134's avatar
    bl0ndie_127134
    Historic F5 Account
    You don't need to add a square braket when dereferencing variables in tcl. Try this syntax.

    log local0. "WE RECORDED $rpc-id AS THE PERSIST VARIABLE"
  • drteeth_127330's avatar
    drteeth_127330
    Historic F5 Account
    If that doesn't work, try this:

    log local0. "WE RECORDED ${rpc-id} AS THE PERSIST VARIABLE"

    I believe the braces are required due to the hyphen in your variable name.
  • I changed the iRule to:

     

     

    when HTTP_REQUEST_DATA {

     

    set content_length 429496

     

    HTTP::collect $content_length

     

    set rpc-id "TEST-LOG"

     

    {[findstr [HTTP::payload] "Authorization:" 14, 20]}

     

    log local0. "WE RECORDED ${rpc-id} AS THE PERSIST VARIABLE"

     

    HTTP::release

     

    }

     

     

    I added the fourth line so that I could see if I can get ANY value into the variable. I am tailing the ltm log file to see if any entries appear and I am getting nothing in the log file.
  • bl0ndie_127134's avatar
    bl0ndie_127134
    Historic F5 Account
    Are you handling the HTTP_REQUEST event? HTTP::collect *must* be called from HTTP_REQUEST/HTTP_RESPONSE events otherwise HTTP_REQUEST_DATA/HTTP_RESPONSE_DATA events will not fire. That would explain why you are not seing any log entries.
  • So it should look something like this?

     

     

    when HTTP_REQUEST {

     

    set content_length 429496

     

    HTTP::collect $content_length

     

    set rpc-id "TEST-LOG"

     

    {[findstr [HTTP::payload] "Authorization:" 14, 20]}

     

    log local0. "WE RECORDED ${rpc-id} AS THE PERSIST VARIABLE"

     

    HTTP::release

     

    }
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    Rusty,

    You are pretty close.

    Here is a better explanation of the HTTP_REQUEST and HTTP_REQUEST_DATA events. I would hope this is in the manual, but I'm going to repeat it here for the sake of the forum.

    The http processing first parses the HTTP method and request headers. At the completion of this processing the HTTP_REQUEST event is evaluated. Next, the http processing resumes handling the content, potentially collecting and buffering it if an HTTP::collect command was issued in the HTTP_REQUEST event. When either the amount specified on the HTTP::collect command or the entire content (specified in the Content-Length header) is collected, the HTTP_REQUEST_DATA event is evaluated. The HTTP::release command is then used to release the collected content to be delivered to the destination server.

    So, since you are trying to dig into the content, you will need at least these two events. The HTTP_REQUEST event would set up the collection and the HTTP_REQUEST_DATA event is where you would then search for the content and perform your desired action. I would suggest that you use the Content-Length header to determine the length instead of the arbitrary number 429496, but I am not familiar with your app, so maybe that is the right number in your case. I used the Content-Length in the example below, but you should be able to easily change it back if you need to. I also renamed your rpc-id variable to rpc_id as hyphens are somewhat of a pain to deal with in Tcl and you always have to bracket the variable expansion with {} braces.

    Based on this, your rule should look more like this:

       
       when HTTP_REQUEST {    
          set content_length [HTTP::header Content-Length]   
          HTTP::collect $content_length   
       }   
       when HTTP_REQUEST_DATA {   
          set rpc_id [findstr [HTTP::payload] "Authorization:" 14 20]   
          persist uie $rpc_id   
          log local0. "WE RECORDED $rpc_id AS THE PERSIST VARIABLE"    
          HTTP::release    
       }   
       

  • That was a huge help. The log file shows that the variable is empty. I just have a couple of questions. The current rule is looking in the http header. Since the information I am trying to get is in the payload, should I not be using payload instead of header? This is the string I am trying to get in the variable:

     

     

    Authorization: Basic SomeBase64EncodedValue

     

     

  • bl0ndie_127134's avatar
    bl0ndie_127134
    Historic F5 Account
    Rusty, the value for Authorization is in the HTTP header, so you don't need to call HTTP::collect in order to extract and persist on that value. Here is a modified rule that I think will do the trick.

    when HTTP_REQUEST {       
             set rpc_id [HTTP::header value "Authorization"]   
             persist uie $rpc_id      
             log local0. "WE RECORDED ${rpc_id} AS THE PERSIST VARIABLE"       
          }      
       

    FYI, HTTP::username & HTTP::password will decode and extact the credentials for you.