Downloaded file using Chrome on Android shows increased file size and is corrupted with APPFirewall enabled

Downloaded file using Chrome on Android shows increased file size and is corrupted with APPFirewall enabled

book

Article ID: CTX232709

calendar_today

Updated On:

Description

  • Users on Chrome (63.x) on Android, when downloading files are seeing the filesize increase 1.5 times the actual file. e.g. a 10 MB file post download appears to be  ~15 MB and is corrupt.
  • This behavior is not seen if APP Firewall policy is disabled from the VIP.
  • This behavior is not seen with Chrome on PC / MAC even with APP Firewall policy Enabled

Resolution

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 Backend

5. 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.

Additional Information

https://support.citrix.com/article/CTX131488