Forum Discussion
iRule to insert header ntCoent-Length based in URI
Hello everyone, this time I ask for your help because I am trying to find the way to insert a header named ntCoent-Length which contains the total length in bytes of the content requested. I am balancing the pools based with URIs, which are contained in datagroups, so this insert just should be with certain URIs, contained in this example in the datagroup_C. I designed this iRule but when I tried to log the value it doesn't return nothing, so I am pretty sure it is not inserting the header and the value.
when HTTP_REQUEST {
if { [class match [HTTP::uri] starts_with "datag_A"] } {
pool Pool_A
} elseif { [class match [HTTP::uri] starts_with "datag_B"] } {
pool Pool_B
} elseif { [class match [HTTP::uri] starts_with "datag_C"] } {
HTTP::collect
set urimatch 1
pool Pool_C
} elseif {
pool Pool_default
}
}
when HTTP_RESPONSE_DATA {
if { [info exists urimatch] } {
set ntCoent [HTTP::payload length]
HTTP::release
}
}
when HTTP_RESPONSE {
if { [info exists urimatch] } {
HTTP::header insert ntCoent-Length $ntCoent
log local0. "HTTP ntCoent-Length header = [HTTP::header value "ntCoent-Length"]"
}
}
I have tried a lot of iRules, but it seems this is closer, I also tried to do it by a Traffic Policy but I don't know how to trigger the HTTP::collect within the policy, my policy was moreless:
Match the following conditions:
HTTP URI PATH starts with /example at request
Don the following:
Insert HTTP Header named= ntCoent-Length with value [HTTP::payload length] at response time
Log message The ntCoent-Lenght value is [HTTP::header value ntCoent-Length] at response time
But it doesn't return any value, can you help me please or give me a hint.
Thanks a lot!!!!!
- HamishCirrocumulus
Do you really want to include the total length in the header? It's just not scalable. Admittedly you could possibly have a situation where all your responses are small enough to do this, but in reality... Probably not
is there a reason you can't simply enable chunking on the client side?
H
- Ivan_383Nimbostratus
Hi Hamish, thanks a lot for your answer, the reason why I must include that header is because I am migrating this configuration from a Citrix netscaler, which balances to a legacy application server, I offered to enable the chunking within the http profile, , I am not sure why they need this header within the application, but unfortunatelly I must meet the requierement exactly as they asked. Thanks a lot!!!
- crodriguezRet. Employee
I spotted several issues in your iRule. First, HTTP_RESPONSE occurs before HTTP_RESPONSE_DATA. (See https://devcentral.f5.com/s/question/0D51T00006i7X94/irule-event-order-http for more info.) That means, the HTTP::header insert for ntCoent needs to occur in the HTTP_RESPONSE_DATA event rather than in the HTTP_RESPONSE event. Second, HTTP_RESPONSE_DATA occurs after an HTTP::collect command. You have one HTTP::collect command but it is in the HTTP_REQUEST event, so it applies to the client-side request payload, not the server-side response payload.
I tested an alternative scenario below that might work for you or at least get you started, since I don't have the benefit of testing with your application. I decided to log the Content-Length header as sent by the server, too. I could not get the iRule to trigger the HTTP_RESPONSE_DATA event unless I specified a value on the HTTP::collect command:
when HTTP_REQUEST { # Set default pool and no URI match set urimatch 0 pool pool_default if { [class match [HTTP::uri] starts_with "datatag_A"] } { pool pool_A } elseif { [class match [HTTP::uri] starts_with "datatag_B"] } { pool pool_B } elseif { [class match [HTTP::uri] starts_with "datatag_C"] } { pool pool_C # This request needs an ntCoent header inserted in the response set urimatch 1 } } when HTTP_RESPONSE { if { $urimatch } { log local0. "HTTP RESPONSE Content-Length header is [HTTP::header Content-Length]" # Adjust as needed. Will not work with no value HTTP::collect 100000 } } when HTTP_RESPONSE_DATA { if { $urimatch } { log local0. "HTTP RESPONSE DATA payload length is [HTTP::payload length]" HTTP::header insert ntCoent [HTTP::payload length] HTTP::release } }
...and here is the log output it produced when just 1 of the URI's I requested matched my Data Group C:
Jun 21 10:48:49 bigip4 info tmm[9908]: Rule /Common/test_devcentral_irule <HTTP_RESPONSE>: HTTP RESPONSE Content-Length header is 22666 Jun 21 10:48:49 bigip4 info tmm[9908]: Rule /Common/test_devcentral_irule <HTTP_RESPONSE_DATA>: HTTP RESPONSE DATA payload length is 22666
So, at that point, you might as well just pass the value contained in the Content-Length header. If I used a lower value, such as HTTP::collect 1, the HTTP_RESPONSE_DATA event still only triggered once, and there was a discrepancy between the Content-Length header and the HTTP::payload length, as expected. I tested on BIG-IP v14.1.0.
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com