Moved FileHandler functions to FileBaseHandler

FileHandler hat core functionality used/needed by other Handlers.
master
Sebastian Lohff 12 years ago
parent 790607eabc
commit b11710da39

@ -101,43 +101,44 @@ class FileBaseHandler(BaseHTTPServer.BaseHTTPRequestHandler):
return (True, None)
return (True, fromto)
# broken request or no range header
pass
return (False, None)
class FileHandler(FileBaseHandler):
filePath = "/dev/null"
fileLength = 0
startTime = getDateStrNow()
def sendFile(self, filePath, fileLength=None, lastModified=None):
""" Send file with continuation support.
def do_HEAD(self):
if self.checkAndDoRedirect():
return
self.send_response(200)
self.sendContentHeaders(self.fileName, self.fileLength, self.startTime)
self.end_headers()
filePath: path to file to be sent
fileLength: length of file (if None is given this will be found out)
lastModified: time the file was last modified, None for "now"
"""
if not fileLength:
fileLength = os.stat(filePath)[ST_SIZE]
def do_GET(self):
if self.checkAndDoRedirect():
(responseCode, myfile) = self.getFileHandle(filePath)
if not myfile:
self.send_response(responseCode)
self.end_headers()
return
myfile = open(self.filePath, 'rb')
(continueDownload, fromto) = self.handleRangeRequest(self.fileLength)
(continueDownload, fromto) = self.handleRangeRequest(fileLength)
if continueDownload:
if not fromto:
# we are done
return
return True
# now we can wind the file *brrrrrr*
myfile.seek(fromto[0])
fileLength = self.fileLength
if fromto != None:
self.send_response(216)
self.send_header('Content-Range', 'bytes %s-%s/%s' % (fromto[0], fromto[1], self.fileLength))
self.send_header('Content-Range', 'bytes %s-%s/%s' % (fromto[0], fromto[1], fileLength))
fileLength = fromto[1] - fromto[0] + 1
else:
self.send_response(200)
self.sendContentHeaders(self.fileName, fileLength, self.startTime)
fileName = self.fileName
if not fileName:
fileName = os.path.basename(filePath)
self.sendContentHeaders(fileName, fileLength, lastModified)
self.end_headers()
block = self.getChunk(myfile, fromto)
while block:
@ -145,10 +146,11 @@ class FileHandler(FileBaseHandler):
self.wfile.write(block)
except socket.error, e:
print "%s ABORTED transmission (Reason %s: %s)" % (self.client_address[0], e[0], e[1])
return
return False
block = self.getChunk(myfile, fromto)
myfile.close()
print "%s finished downloading" % (self.client_address[0])
print "%s finished downloading %s" % (self.client_address[0], filePath)
return True
def getChunk(self, myfile, fromto):
if fromto and myfile.tell()+self.blockSize >= fromto[1]:
@ -157,6 +159,64 @@ class FileHandler(FileBaseHandler):
readsize = self.blockSize
return myfile.read(readsize)
def getFileHandle(self, path):
""" Get handle to a file.
Return a tuple of HTTP response code and file handle.
If the handle couldn't be acquired it is set to None
and an appropriate HTTP error code is returned.
"""
myfile = None
responseCode = 200
try:
myfile = open(path, 'rb')
except IOError, e:
responseCode = self.getResponseForErrno(e.errno)
return (responseCode, myfile)
def getFileLength(self, path):
""" Get length of a file.
Return a tuple of HTTP response code and file length.
If filelength couldn't be determined, it is set to -1
and an appropriate HTTP error code is returned.
"""
fileSize = -1
responseCode = 200
try:
fileSize = os.stat(path)[ST_SIZE]
except IOError, e:
responseCode = self.getResponseForErrno(e.errno)
return (responseCode, fileSize)
def getResponseForErrno(self, errno):
""" Return HTTP response code for an IOError errno """
if errno == 2:
return 404
elif errno == 13:
return 403
else:
return 500
class FileHandler(FileBaseHandler):
filePath = "/dev/null"
fileLength = 0
startTime = getDateStrNow()
def do_HEAD(self):
if self.checkAndDoRedirect():
return
self.send_response(200)
self.sendContentHeaders(self.fileName, self.fileLength, self.startTime)
self.end_headers()
def do_GET(self):
if self.checkAndDoRedirect():
return
self.sendFile(self.filePath, self.fileLength, self.startTime)
class TarFileHandler(FileBaseHandler):
target = None
compression = "none"

Loading…
Cancel
Save