summaryrefslogtreecommitdiff
path: root/paste/fileapp.py
diff options
context:
space:
mode:
authorianb <devnull@localhost>2005-12-18 21:19:02 +0000
committerianb <devnull@localhost>2005-12-18 21:19:02 +0000
commit79320015c183266927dd776f075189752d20fa3f (patch)
tree9abc12d5417d94e20a5e96f5325bba302306e221 /paste/fileapp.py
parent996f4fbc2119a6ff05aeb1efa55d4f3c58d45313 (diff)
downloadpaste-79320015c183266927dd776f075189752d20fa3f.tar.gz
Added -W option to tests, which will turn warnings into errors (warnings haven't actually been removed yet, though). Split response and fileapp from wsgilib. Some portions of wsgilib may still move to response module, this is just the first cut
Diffstat (limited to 'paste/fileapp.py')
-rw-r--r--paste/fileapp.py53
1 files changed, 53 insertions, 0 deletions
diff --git a/paste/fileapp.py b/paste/fileapp.py
new file mode 100644
index 0000000..f285e00
--- /dev/null
+++ b/paste/fileapp.py
@@ -0,0 +1,53 @@
+"""
+Static file sending application
+"""
+import os
+import mimetypes
+import httpexceptions
+
+class FileApp(object):
+ """
+ Returns an application that will send the file at the given
+ filename. Adds a mime type based on ``mimetypes.guess_type()``.
+ """
+ # @@: Should test things like last-modified, if-modified-since,
+ # etc.
+
+ def __init__(self, filename):
+ self.filename = filename
+
+ def __call__(self, environ, start_response):
+ type, encoding = mimetypes.guess_type(self.filename)
+ # @@: I don't know what to do with the encoding.
+ if not type:
+ type = 'application/octet-stream'
+ size = os.stat(self.filename).st_size
+ try:
+ file = open(self.filename, 'rb')
+ except (IOError, OSError), e:
+ exc = httpexceptions.HTTPForbidden(
+ 'You are not permitted to view this file (%s)' % e)
+ return exc.wsgi_application(
+ environ, start_response)
+ start_response('200 OK',
+ [('content-type', type),
+ ('content-length', str(size))])
+ return _FileIter(file)
+
+class _FileIter:
+
+ def __init__(self, fp, blocksize=4096):
+ self.file = fp
+ self.blocksize = blocksize
+
+ def __iter__(self):
+ return self
+
+ def next(self):
+ data = self.file.read(self.blocksize)
+ if not data:
+ raise StopIteration
+ return data
+
+ def close(self):
+ self.file.close()