Support for sending files with less common extensions; mimetype, downloadability, gzipping
This file provides for downloading and serving pages. It is invoked by urlHandler and download.
- What MIME type should be associated with the file:
mimetype($file)
- Is downoad of the file allowed:
downloadable($file, $mimetype)
- Produce a gzipped version of the file for compressed transmission:
ensuregzfile($frfile)
- Send or download a page
The main difference between downloading and serving a page
is that download includes a Content-Disposition
header giving a file name for saving the file.
Otherwise both include the headers Content-Type
,
and Content-Length
.
Actual treatment of files served with a Content-Disposition
varies between browsers.
In FireFox for most file types, a download shows a dialog box
asking whether to save the file or open it with some appropriate application.
Mostly-reliable lists of Mime types can be had by googling "mime type list".
("Mostly-reliable" is the best you can expect. Implementations of the types
are idiosyncratic.) When writing this code I made my own list, now available as
/mime.xls.
MIME Type
Browsers treat files depending on their "type". Some they present as text, images, or sounds, and yet others are delivered to various external applications. Some files are simply saved to disk and left for the user deal with. The browser chooses the action based (usually) on the "Content-Type
" header sent prior to the actual file contents. This code goes to some lengths to set a proper Content-Type
, computing it variously by extension,
by php's finfo_file
, by the Unix file
program,
or fail-all-else by defaulting to application/octet-stream
. For the first of these, this is the map from extension to MIME type:
|
downloadable |
|
protected |
|
Ext |
Mime type |
|
Ext |
Mime type |
|
bmp |
image/bmp |
|
c |
text/plain |
|
css |
text/css |
|
h |
text/plain |
|
gif |
image/gif |
|
csh |
text/plain |
|
htm |
text/html |
|
doc |
application/msword |
|
html |
text/html |
|
docx |
AVOO.wordprocessingml.document |
|
ico |
image/x-icon |
|
jar |
application/java-archive |
|
jpg |
image/jpeg |
|
jnlp |
application/x-java-jnlp-file |
|
js |
text/javascript |
|
ppt |
application/vnd.ms-powerpoint |
|
pdf |
application/pdf |
|
pptx |
AVOO.presentationml.presentation |
|
php |
text/plain |
|
xls |
application/vnd.ms-excel |
|
png |
image/png |
|
xlsx |
AVOO.spreadsheetml.sheet |
|
txt |
text/plain |
|
xml |
appplication/xml |
AVOO = application/vnd.openxmlformats-officedocument
function simplemime($file)
-
Test for a limited set of extensions
and return the corresponding MIME type.
For other extensions, return
null
.
Only the extension is examined; $file
may exist or not;
and it may be file- or site-rooted. The known extensions are bmp
, css
, gif
, htm
, html
, ico
, jpg
, js
, pdf
, php
, png
, txt
.
function hardmime($frfile)
-
Determine and return the mimetype of a file.
$frfile
must be file-rooted. Assumes that the
extension is not one of those tested by simplemime
.
If $frfile
is unreadable results are unpredictable.
Tries these strategies, accepting the value of the first that succeeds:
- test for some common-ish extensions
- call
finfo_file
, is it exists
- invoke
/usr/bin/file -i -b
- invoke
/usr/bin/file
and check the result for xml
or text
- default to
application/octet-stream
.
Intended as an internal function; if you call it, please follow the parameter requirements carefully.
function mimetype($file)
-
Determines the body of a
Content-Type
header line; the format is:
mimetype; charset=xxxx
$file
must be site-rooted. Returns null
if $file
is not readable.
Uses the strategies of simplemime
and hardmime
, above.
function downloadable($file, $mime = null)
-
Determines whether a file is downloadable.
If so, its mime type is returned.
If not,
null
is returned.
$file
must be site-rooted.
If it is not readable, return null.
If the $mime
argument is null, mimetype()
is called to get the value.
A file is downloadable if
- its extensions is one of
those known to
simplemime
- its mimetype is
audio/
or video/
- it is matches an element in its directory's
downloadable
property.
The list in the downloadable
property includes exact-match and partial-match items. A file name matches an exact-match item if both are the same. A partial match item contains one asterisk in addition to letters and digits. A name matches if it starts with the string before the asterix
and ends with the string after the asterix.
function ensuregzfile($frfile)
-
Given a file-rooted file name, say
f.x
, ensure that either it is gzipped itself
or there is a coresponding and newer gzipped version named f.x.gz
.
Return the file-rooted name of that gzipped file.
function sendpage($file, $download)
- Just as urlHandler is a front-end for parsing an incoming URL, this method is a back-end for sending a page as determined from the URL parse. The
$file
parameter is the site-rooted address of the page to send. If $download
is true, the page is not PHP-evaluated, but is sent as iteself with a Content-disposition suggesting that the file be saved rather than displayed. The downloadable() method is checked to ensure that the page is legal for sending. Depending on circumstances, most or all of these headers are generated: Content-Type
, Content-Length
, Content-Disposition
.
-