Using a rewrite policy drop the "Accept-Ranges" header from the Server Response while forwarding to client. Without this header in server response, the client will not make parallel download requests using range request.
Example: Rewrite Action and Policy
add rewrite action del-range-req delete_http_header Accept-Ranges
add rewrite policy del-range-req-pol "HTTP.RES.HEADER(\"Accept-Ranges\").EXISTS" del-range-req
Bind this rewrite policy to the LB Vserver
bind lb vserver -policyName del-range-req-pol -priority 80 -gotoPriorityExpression NEXT -type RESPONSE
Problem Cause
Chrome on Android seems to be making parallel requests to download a single file,using
range requests. APPFW drops the "range" header from client request while forwarding to back-end server, which causes the problem. Below is the detailed explanation.
Say the real file size the client intends to download is 72299385 Bytes
[CLIENT]=====[NS]=====[SERVER]
====================================================================
Working Scenario - APPFW DISABLED or APPFW with only BASIC-CHECKS enabled
====================================================================
1. First request is a normal GET request for the file, this request is forwarded to the Backend
2. Backend responds with 200OK along with the content-length of 72299385, and the "Accept-Ranges: bytes" header , this response is forwarded to client and the download starts.
3. Now the client knows the file size is 72299385 Bytes (from content-length header in the response), and also that the server supports Range requests (the presence of Accept-Ranges in the response)
4. While the file is still being downloaded, client initiates another parallel Get request for the same file but includes the header "Range: Bytes=36149692-" , i.e. bytes in the range of 36149692 to end of the file” this is half of the “Content-length” received in the original response. In short this is a parallel request to download the 2nd half of the file.This request is forwarded to the Backend as is.
5. Backend responds with "206 partial-content" + "content-range: bytes 3614962-72299384/72299385" , this is the back-end response for the requested byte range. This request is forwarded to the Client the download of the 2nd half starts.
===== At this point, two downloads are in progress=====
The first request for the entire file #2
The second request for the 2nd half of the file #5
============================================
6. Once the first download reaches halfway mark, the client terminates the TCP connection FIN and also a RST (just in case)
7. The Second request is also closed once download is done.
At the end of all this, the client has the first half of the file from the 1st request and the second half of the file from the 2nd request and it constructs the actual file.
====================================================================
Non-Working Scenario - APPFW with ADVANCED-CHECKS enabled
====================================================================
1. First request is a normal GET request for the file, this request is forwarded to the Backend
2. Backend responds with 200OK along with the content-length of 72299385, and the "Accept-Ranges: bytes" header , this response is forwarded to client and the download starts.
3. Now the client knows the file size is 72299385 Bytes (from content-length header in the response), and also that the server supports Range requests (the presence of Accept-Ranges in the response)
4. While the file is still being downloaded, client initiates another parallel Get request for the same file but includes the header "Range: Bytes=36149692-" , i.e. bytes in the range of 36149692 to end of the file” this is half of the “Content-length” received in the original response. In short this is a parallel request to download the 2nd half of the file.
APPFW with advanced checks enabled, drops the "range" header from the client request (expected) and forwards to Backend5. Without the range header, Backend responds with entire file 200OK along with the content-length of 72299385. This is forwarded back to client and download starts
===== At this point, two downloads are in progress=====
The first request for the entire file #2
The second request
also for the entire file #5
============================================
6. Once the first download reaches halfway mark, the client terminates the TCP connection FIN and also a RST (just in case)
7. The Second request is also closed once download is done.
At the end, the client has the
first half of the file from the first request. and the
Entire file from the 2nd request. Then the client seems to merge this and end up with a file 1.5 times the original size and the file of course is corrupt.