Forum Discussion

Gladney_7700's avatar
Gladney_7700
Historic F5 Account
Oct 18, 2011

HTTP Proxy iRule

I am trying to get an iRule working that essentially proxies and logs HTTP traffic. I am having trouble when the server issues a redirect. In the HTTP_RESPONSE event, I have tried to capture this, and the logs indicate that the redirect is being seen and processed, but user traffic dies at this point. Does anyone have any insight with this scenario?

 

 

Thanks!

 

 

when RULE_INIT {

 

set static::debug 1

 

Enter address of name server to query

 

set static::nameserver "x.x.x.x"

 

}

 

when HTTP_REQUEST {

 

if {$static::debug}{log -noname y.y.y.y local0.info ""}

 

if {$static::debug}{log -noname y.y.y.y local0.info "Entering HTTP REQUEST"}

 

if {$static::debug}{log -noname y.y.y.y local0.info "Raw Request: [HTTP::request]"}

 

set rawquery [HTTP::query]

 

if { $rawquery starts_with "https"}{

 

set host [findstr $rawquery "https://" 8 "/"]

 

if {$static::debug}{log -noname y.y.y.y local0.info "Value of SSL Host: $host"}

 

} else {

 

set host [findstr $rawquery "http://" 7 "/"]

 

if {$static::debug}{log -noname y.y.y.y local0.info "Value of Host: $host"}

 

}

 

if {[class match $host starts_with exempted]}{

 

if {$static::debug}{log -noname y.y.y.y local0.info "Matched List of Exempted"}

 

if {$static::debug}{log -noname y.y.y.y local0.info "Raw Query: $rawquery Host: $host"}

 

HTTP::respond 200

 

event disable all

 

return

 

 

}

 

if {[HTTP::uri] equals "/?"}{

 

log -noname y.y.y.y local0.info "HTTP URI only contained: [HTTP::uri]"

 

HTTP::respond 200

 

event disable all

 

return

 

}

 

if {$static::debug}{log -noname y.y.y.y local0.info "Raw Query: $rawquery Host: $host"}

 

set rawhostip [RESOLV::lookup @x.x.x.x $host]

 

set hostip [getfield $rawhostip " " 1]

 

if {$static::debug}{log -noname y.y.y.y local0.info "RawHost IP: $rawhostip"}

 

if {$static::debug}{log -noname y.y.y.y local0.info "Host IP: $hostip"}

 

if {$static::debug}{log -noname y.y.y.y local0.info "Host IP: $hostip"}

 

if { $rawquery starts_with "https"}{

 

set port 443

 

set hostlen [expr [string length $host] + 8]

 

set hostremoved [findstr $rawquery "https://" $hostlen]

 

if {$static::debug}{log -noname y.y.y.y local0.info "Value of SSL port: $port hostlen: $hostlen hostremoved: $hostremoved"}

 

} else {

 

set port 80

 

set hostlen [expr [string length $host] + 7]

 

set hostremoved [findstr $rawquery "http://" $hostlen]

 

if {$static::debug}{log -noname y.y.y.y local0.info "Value of SSL port: $port hostlen: $hostlen hostremoved: $hostremoved"}

 

}

 

if {$static::debug}{log -noname y.y.y.y local0.info "Host Len: $hostlen Host Removed: $hostremoved"}

 

if {$static::debug}{log -noname y.y.y.y local0.info "Host Len: $hostlen Host Removed: $hostremoved"}

 

if { $hostremoved ne "" }{

 

if {$static::debug}{log -noname y.y.y.y local0.info "hostremoved not empty. Changing URI to: $hostremoved"}

 

HTTP::uri $hostremoved

 

} else {

 

if {$static::debug}{log -noname y.y.y.y local0.info "hostremoved empty. Changing URI to /"}

 

HTTP::uri "/"

 

}

 

if {$static::debug}{log -noname y.y.y.y local0.info "Changing Host Header to: $host"}

 

HTTP::header replace "Host" $host

 

if { $hostip ne "" }{

 

if {$static::debug}{log -noname y.y.y.y local0.info "hostip isn't empty. Sending traffic to: $hostip:$port"}

 

node $hostip $port

 

log -noname y.y.y.y local0.info "Request to $rawquery sent to $host at IP $hostip"

 

}

 

}

 

when SERVER_CONNECTED {

 

if {$static::debug}{log -noname y.y.y.y local0.info "Entering SERVER CONNECTED"}

 

if {[LB::server port] == 443 } {

 

if {$static::debug}{log -noname y.y.y.y local0.info "SSL traffic applying profile"}

 

SSL::profile Wildcard.cardlytics-server

 

} else {

 

SSL::disable

 

}

 

}

 

when HTTP_RESPONSE {

 

if {$static::debug}{log -noname y.y.y.y local0.info "Entering HTTP RESPONSE Event"}

 

if { [HTTP::is_redirect]}{

 

if {$static::debug}{log -noname y.y.y.y local0.info "HTTP Redirect Caught"}

 

if {$static::debug}{log -naname y.y.y.y local0.info "Redirected to: [HTTP::header Location] with host of $host"}

 

HTTP::retry "GET [HTTP::header Location]\r\nHost: $host\r\n\r\n"

 

HTTP::respond 200

 

}

 

if { [HTTP::status] < 500}{

 

HTTP::respond 200

 

log -noname y.y.y.y local0.info "Received [HTTP::status] Response from Remote Host $host"

 

} else {

 

HTTP::respond 200

 

log -noname y.y.y.y local0.info "Received [HTTP::status] Response from Remote Host $host"

 

}

 

}
  • HTTP::retry "GET [HTTP::header Location]\r\nHost: $host\r\n\r\n"can you check if [HTTP::header Location] is correct HTTP::retry requires well-formed and complete header.

     

     

    HTTP::respond 200also, i think this is not needed.
  • Patrick_Chang_7's avatar
    Patrick_Chang_7
    Historic F5 Account
    HTTP::respond 200 short circuits the real response with an empty 200. If your HTTP::retry succeeds it will result in another call to HTTP_RESPONSE with a non redirect and a status less than 500.