viewfile
service
to send static files over to the browser thus enforcing access rights on them. In doing
so it reads the static file into memory completely before handing it over to the HTTP web server
which takes over responsibility to contact the browser. This of course is far from optimal
as it introduces a lot of overhead by copying the static file several times in memory. The impact
on the overall system performance is even higher for large files being downloaded from a Foswiki
server. For now the only alternative solution to this problem is not to protect static files
by Foswiki's access control at all, and let the HTTP web server do its job on static files all
on its own. Web servers are in fact quite good in sending static files, even large ones. So the
best you can do is to leave this job to them.
Still you might require access control, even on large static files.
There's a quite unknown yet very important feature in Apache2, Nginx and Lighttpd, called "xsendfile", to interact with an upstream web application before sending a static file. This feature can be used to solve the above problem: it lets you control access to static files while still using the HTTP web server to do the heavy lifting.
This basically works like this:
X-Lighttp-send-file
, but not the data being requested, when access is granted, or an HTTP error otherwise
.../bin/xsendfile
replacing the standard .../bin/viewfile
. It differs from viewfile only in two respects
There are two parameters that need to be adjusted according to your web server's type and configuration:
$Foswiki::cfg{XSendFileContrib}{Header}
… the name of the HTTP header to trigger the X-Send-File feature in your web server (see below)
$Foswiki::cfg{XSendFileContrib}{Location}
… the uri prefix that the web server serves the actual static file from
$Foswiki::cfg{XSendFileContrib}{Locations}{pdf}
… the uri prefix for pdf files
"allow-x-send-file" => "enable"
to your fastcgi stanza
url.rewrite-once += ( "^/pub/((?!System|Applications|images|cache).*)/(.*?)$" => "/bin/xsendfile/$1/$2" ) $HTTP["url"] =~ "^/bin/" { alias.url += ( "/bin" => "/path/to/bin/foswiki.fcgi" ) fastcgi.server = ( ".fcgi" => (( ... "allow-x-send-file" => "enable" ), )) } $HTTP["url"] =~ "^/bin/xsendfile)" { expire.url = ( "" => "access 12 hours") }
In addition Nginx requires a special "location" stanza for internal use only. Protected files will be served from there one the web app checked the original uri the.
location ~ ^/pub/(System|Applications|images|cache)/ { root /path/to/foswiki; expires 12h; gzip_static on; } location /pub { rewrite ^/pub/(.*)$ /bin/xsendfile/$1; } location /protected_files { internal; alias /path/to/foswiki/pub/; } location /protected_files/pdf { internal; alias /path/to/foswiki/pub/; # disable Accept-Ranges header as it breaks cookie authentication with pdf.js max_ranges 0; }
XSendFile on XSendFilePath /path/to/pub RewriteRule ^/+pub/+(.*)$ /bin/xsendfile/$1 [L,PT]See https://tn123.org/mod_xsendfile/ for more information on how to compile
mod_xsendfile
and how to configure apache.
You do not need to install anything in the browser to use this extension. The following instructions are for the administrator who installs the extension on the server.
Open configure, and open the "Extensions" section. "Extensions Operation and Maintenance" Tab → "Install, Update or Remove extensions" Tab. Click the "Search for Extensions" button. Enter part of the extension name or description and press search. Select the desired extension(s) and click install. If an extension is already installed, it will not show up in the search results. You can also install from the shell by running the extension installer as the web server user: (Be sure to run as the webserver user, not as root!)cd /path/to/foswiki perl tools/extension_installer <NameOfExtension> installIf you have any problems, or if the extension isn't available in
configure
, then you can still install manually from the command-line. See https://foswiki.org/Support/ManuallyInstallingExtensions for more help.
Name | Version | Description |
---|---|---|
Foswiki::Contrib::FastCGIEngineContrib | >=0.9.5 | Optional. |
File::MMagic | >0 | Required. |
09 Oct 2020 | added {Locations} feature to be able to work around a bug in pdf.js not forwarding cookies in byte-range requests |
11 Jun 2018 | display reason why access to a file was denied |
12 Dec 2017 | fixed content encoding of a 403 warning; made file extension configurable that must be delivered in an "attachment" disposition mode |
11 Dec 2017 | return correct http error code when not authorized to access an attachment; optionally redirect to a login in case of an unauthorized access |
25 Sep 2017 | remove txt files from default dispositioning |
30 Nov 2016 | fixed encoding under Foswiki-2.x; detect 404 file not found properly; added support for rev parameter to access previous versions of an attachment; allow to specify content disposition (inline or attachment); allow to deliver and protect other content paths organized in parallel to the normal pub directory tree, for instance /pub/images for thumbnails |
17 Jul 2015 | added support for Foswiki-2.0 |
29 Aug 2014 | improved decoding and untainting url components |
28 May 2014 | fixed file check on wrong location |
15 Apr 2014 | untaint attachment filenames |
18 Mar 2014 | return a proper 404 for invalid filename parameters |
06 Nov 2013 | fixed filenames with spaces not being found |
01 Nov 2013 | added support for if-modified-since http headers |
22 May 2013 | using mime-magic as a fallback in case file extensions don't unveil the mime-type |
28 Mar 2013 | implemented {AccessRules} to allow any kind of access control list for attachments |
Author | Michael Daum |
Version | 6.00 |
Release | 20 Oct 2020 |
Description | A viewfile replacement to send static files efficiently |
Repository | https://github.com/foswiki/XSendFileContrib |
Copyright | 2013-2020, Michael Daum |
License | GPL (GNU General Public License) |
Home | https://foswiki.org/Extensions/XSendFileContrib |
Support | https://foswiki.org/Support/XSendFileContrib |