Browse Source

Try to avoid HTTP compression in load_file (#919)

Web servers might use HTTP compression (Content-Encoding) to send
data, including the image files v86 uses.  Unfortunately, the data
ranges used in AsyncXHRBuffer are in terms of the raw image files and
not the compressed file (where in fact data might need to be pulled
from several ranges and decompressed, and it might be hard to know what
ranges of the compressed file represent what parts of the original
file).

This patch uses two techniques to try and handle this issue:

1. First, we send the nonstandard X-Accept-Encoding header, which some
web servers respect.
2. Second, if we notice a web server has responded to a Range request
with a response with a Content-Encoding header distinct from
"identity" (i.e., with compressed data), we log an error message to
the console.
Joe Osborn 7 months ago
parent
commit
a014a449b3
2 changed files with 10 additions and 0 deletions
  1. 1 0
      src/buffer.js
  2. 9 0
      src/lib.js

+ 1 - 0
src/buffer.js

@@ -742,6 +742,7 @@
                 },
                 headers: {
                     Range: "bytes=0-0",
+                    "X-Accept-Encoding": "identity"
                 }
             });
         };

+ 9 - 0
src/lib.js

@@ -578,6 +578,7 @@ function load_file(filename, options, n_tries)
         let start = options.range.start;
         let end = start + options.range.length - 1;
         http.setRequestHeader("Range", "bytes=" + start + "-" + end);
+        http.setRequestHeader("X-Accept-Encoding", "identity");
 
         // Abort if server responds with complete file in response to range
         // request, to prevent downloading large files from broken http servers
@@ -604,6 +605,14 @@ function load_file(filename, options, n_tries)
             }
             else if(http.response)
             {
+                if(options.range)
+                {
+                    let enc = http.getResponseHeader("Content-Encoding");
+                    if(enc && enc !== "identity")
+                    {
+                        console.error("Server sent Content-Encoding in response to ranged request", {filename, enc});
+                    }
+                }
                 options.done && options.done(http.response, http);
             }
         }