Source: Foswiki Blog

Foswiki Blog Working around a nasty bug in PDF.js

When opening a PDF file in your browser you most probably are using mozilla's PDF.js component. Recently it started to fail reading large PDF files that are stored on Foswiki and require authentication: files seemed to be corrupt missing the bulk of their data. This was another long journey of debugging all sorts of involved components - Foswiki authentication modules, XSendFileContrib, different browsers and web servers. It turns out that there is a nasty bug in PDF.js - which is part of any browser-based PDF reader as shipped with chrome based browsers. It simply fails to read large PDF files when they are stored on a CMS imposing authentication and authorization. The PDF.js reader and web servers exchange chunks of large files being split up in parts as the user continues to read the file. This is called partial downloading or range requests. When resuming these partial downloads, PDF.js fails to authenticate again against the web server, i.e. it does not send any cookie information the way it did with the initial chunk. Thus Foswiki will reject to deliver the rest of the PDF as it seems to be queried by the unauthenticated default user. As PDF.js is so widely spread being shipped with browsers, we cannot wait for it to be fixed and all people to upgrade their browsers. So we have to come up with a solution that mitigates the bad situation in some way. We will do so on the server side by disabling partial downloads for PDF files only. Note that this bug in PDF.js will only affect you when PDF files are particularly large and require authentication to be accessed. The latest version 6.00 of XSendFileContrib allows to configure different (internal) locations for each filetype to be served from. So partial downloads may still be in place streaming files in a secure well performing way from within Foswiki, but disable partial downloads for PDFs specifically. A full example of an NGINX config will look something like this: # no auth required for system assets such as css and js location ~ ^/pub/(System|Applications)/ { root /path/to/foswiki; expires 12h; gzip_static on; } # require auth for any other static file location /pub { rewrite ^/pub/(.*)$ /bin/xsendfile/$1; } # default internal location location /protected_files { internal; alias /path/to/foswiki/pub/; } # internal location for pdf but # disable Accept-Ranges header as it breaks cookie authentication with pdf.js location /protected_files/pdf { internal; alias /path/to/foswiki/pub/; max_ranges 0; } Foswiki can then be configured to serve respective filetypes from their internal web server location: $Foswiki::cfg{XSendFileContrib}{Location}= "/protected_files"; $Foswiki::cfg{XSendFileContrib}{Locations}{pdf}= "/protected_files/pdf"; I leave it to you to provide a matching config example for apache. This implementation is being tracked here. Tags: bugs, http, nginx, partial-downloads, pdf, performance, range-requests, security, web-server

Read full article »
Est. Annual Revenue
$100K-5.0M
Est. Employees
1-25
CEO Avatar

CEO

Update CEO

CEO Approval Rating

- -/100

Read more