Forum Discussion

vjori_231074's avatar
vjori_231074
Icon for Nimbostratus rankNimbostratus
Apr 17, 2018

Persistence: HTTP 200 OK to client hangs when server sends HTTP responses with Transfer-Encoding: chunked

All my problems come because I need an irule to persist sessions based on an specific field that goes through inside an HTTP packet.

First the client need to do a Login and with the response we persist the session_id.

  • HTTP POST
  • HTTP 200 OK (session_id)
  • HTTP GET (session_id)

With the following irule i'm able to do that if the response comes with the header content-length. The problem is that we discovered that if the 200 OK from Login comes with Transfer-Encoding: chunked the 200 OK is received by F5 but the 200 OK that has to be sent to the client not. Bigip persists the connection but the connection between bigip and the client hangs and we are not sending the 200 OK to the client till the client closes the connection (tcp), after 60 seconds we saw the FIN,ACK and then the bigip sends the 200 OK to the client. 😞

    when HTTP_REQUEST {
    log local0. "HTTP_REQUEST"
  if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 1048576}{
    set content_length [HTTP::header "Content-Length"]
  } else {
      set content_length 1048576
  }
  if { $content_length > 0} {
    HTTP::collect $content_length
}
}
when HTTP_REQUEST_DATA {
    set SessionId [findstr [HTTP::payload] "SessionId>" 10 "<"]
    if { not ([string length $SessionId] == 0)  } {
    log local0. "Persist in HTTP_REQUEST_DATA for not login operations $SessionId"
    persist uie $SessionId 300
    }
}
when HTTP_RESPONSE {

  if {[HTTP::header exists "Content-Length"] && [HTTP::header "Content-Length"] <= 1048577}{
    set content_length [HTTP::header "Content-Length"]
  } else {
      set content_length 1048577
  }
  if { $content_length > 0} {
    HTTP::collect $content_length
  }

}

when HTTP_RESPONSE_DATA {

    set SessionId [findstr [HTTP::payload] "sessionId>" 10 "<"]
    if {[HTTP::payload] contains "Login"} {
       log local0. "Persist in HTTP_RESPONSE_DATA for login $SessionId"
       catch { persist add uie $SessionId 300 }
    }
}
`


This is the configuration of the rest of the elements.

`ltm virtual /Common/VS_TEST {
        destination /Common/10.105.108.5:8998
        ip-protocol tcp
        mask 255.255.255.255
        persist {
            /Common/sessionid_profile {
                default yes
            }
        }
        pool /Common/OPCO1_INT_PROV_AGENT_Pool
        profiles {
            /Common/http { }
            /Common/oneconnect { }
            /Common/tcp { }
        }
        source 0.0.0.0/0
        source-address-translation {
            type automap
        }
        translate-address enabled
        translate-port enabled
    }

I tried also changing the http profile, but it didn't solve my problem.

Best Regards and Thanks in advance. Victor Jori