Skip to content

Commit

Permalink
Allow filesystem dependency injection, read file in chunks of configu…
Browse files Browse the repository at this point in the history
…rable size to control memory usage
  • Loading branch information
alekstorm committed Nov 18, 2011
1 parent 41d8d85 commit c14de32
Showing 1 changed file with 28 additions and 18 deletions.
46 changes: 28 additions & 18 deletions vortex/resources.py
Expand Up @@ -6,7 +6,7 @@
import time
import uuid

from vortex import Application, HTTPResponse, Resource, authenticate, format, http_date, json2xml, signed_cookie, xsrf
from vortex import Application, HTTPResponse, HTTPStream, Resource, authenticate, format, http_date, json2xml, signed_cookie, xsrf
from vortex.responses import *

class DictResource(Resource):
Expand Down Expand Up @@ -58,19 +58,24 @@ def put(request):


class StaticFileResource(Resource):
def __init__(self, path, cache_max_age=60*60*24*365*10): # 10 years in seconds
def __init__(self, path, os=os, open=open,
chunk_size=64*2**10, # 64kB
cache_max_age=60*60*24*365*10): # 10 years in seconds
Resource.__init__(self)
self.path = path
self.os = os
self.open = open
self.chunk_size = chunk_size
self.cache_max_age = cache_max_age

def get(self, request, **kwargs):
if not os.path.exists(self.path):
if not self.os.path.exists(self.path):
return HTTPNotFoundResponse()
if not os.path.isfile(self.path):
return HTTPForbiddenResponse(entity='%s is not a file' % self.path)
if not self.os.path.isfile(self.path):
return HTTPMethodNotAllowedResponse(allowed=[])

# Don't send the result if the content has not been modified since the If-Modified-Since
modified = os.stat(self.path).st_mtime
modified = self.os.stat(self.path).st_mtime
if 'If-Modified-Since' in request.headers and time.mktime(email.utils.parsedate(request.headers['If-Modified-Since'])) >= modified:
return HTTPNotModifiedResponse()

Expand All @@ -84,20 +89,25 @@ def get(self, request, **kwargs):
if cache_time > 0:
headers['Expires'] = http_date(time.mktime((datetime.datetime.utcnow() + datetime.timedelta(seconds=cache_time)).timetuple()))
headers['Cache-Control'] = 'max-age=' + str(cache_time)
else:
headers['Cache-Control'] = 'public'

if request.method == 'HEAD':
entity = ''
else:
file = open(self.path, 'rb')
try:
entity = file.read()
finally:
file.close()

return HTTPResponse(entity=entity, headers=headers)
response = HTTPResponse(headers=headers)

if request.method == 'HEAD':
response.entity = ''
return response

stream = HTTPStream(request, response)
file = self.open(self.path, 'rb')
try:
while True:
chunk = file.read(self.chunk_size)
if len(chunk) == 0:
break
stream.write(chunk)
finally:
file.close()

stream.finish()

def __getitem__(self, name):
if not self.os.path.isdir(self.path):
Expand Down

0 comments on commit c14de32

Please sign in to comment.