Moved continuation/range handling to extra function
This commit is contained in:
parent
9db41d5681
commit
94eea95d99
59
servefile
59
servefile
|
@ -68,6 +68,43 @@ class FileBaseHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
||||||
self.send_header('Content-Disposition', 'attachment; filename="%s"' % fileName)
|
self.send_header('Content-Disposition', 'attachment; filename="%s"' % fileName)
|
||||||
self.send_header('Content-Transfer-Encoding', 'binary')
|
self.send_header('Content-Transfer-Encoding', 'binary')
|
||||||
|
|
||||||
|
def isRangeRequest(self):
|
||||||
|
return "Range" in self.headers
|
||||||
|
|
||||||
|
def handleRangeRequest(self, fileLength):
|
||||||
|
""" Find out and handle continuing downloads.
|
||||||
|
|
||||||
|
Returns a tuple of a boolean, if this is a valid range request,
|
||||||
|
and a range. When the requested range is out of range, range is
|
||||||
|
set to None.
|
||||||
|
"""
|
||||||
|
fromto = None
|
||||||
|
if self.isRangeRequest():
|
||||||
|
cont = self.headers.get("Range").split("=")
|
||||||
|
if len(cont) > 1 and cont[0] == 'bytes':
|
||||||
|
fromto = cont[1].split('-')
|
||||||
|
if len(fromto) > 1:
|
||||||
|
if fromto[1] == '':
|
||||||
|
fromto[1] = fileLength - 1
|
||||||
|
try:
|
||||||
|
fromto[0] = int(fromto[0])
|
||||||
|
fromto[1] = int(fromto[1])
|
||||||
|
except:
|
||||||
|
return (False, None)
|
||||||
|
|
||||||
|
if fromto[0] >= fileLength or fromto[0] < 0 or fromto[1] >= fileLength or fromto[1]-fromto[0] < 0:
|
||||||
|
# oops, already done! (requested range out of range)
|
||||||
|
self.send_response(416)
|
||||||
|
self.send_header('Content-Range', 'bytes */%s' % fileLength)
|
||||||
|
self.end_headers()
|
||||||
|
return (True, None)
|
||||||
|
return (True, fromto)
|
||||||
|
# now we can wind the file *brrrrrr*
|
||||||
|
myfile.seek(fromto[0])
|
||||||
|
# broken request or no range header
|
||||||
|
pass
|
||||||
|
return (False, None)
|
||||||
|
|
||||||
class FileHandler(FileBaseHandler):
|
class FileHandler(FileBaseHandler):
|
||||||
filePath = "/dev/null"
|
filePath = "/dev/null"
|
||||||
fileLength = 0
|
fileLength = 0
|
||||||
|
@ -85,23 +122,12 @@ class FileHandler(FileBaseHandler):
|
||||||
return
|
return
|
||||||
myfile = open(self.filePath, 'rb')
|
myfile = open(self.filePath, 'rb')
|
||||||
|
|
||||||
# find out if this is a continuing download
|
(continueDownload, fromto) = self.handleRangeRequest(self.fileLength)
|
||||||
fromto = None
|
if continueDownload:
|
||||||
if "Range" in self.headers:
|
if not fromto:
|
||||||
cont = self.headers.get("Range").split("=")
|
# we are done
|
||||||
if len(cont) > 1 and cont[0] == 'bytes':
|
|
||||||
fromto = cont[1].split('-')
|
|
||||||
if len(fromto) > 1:
|
|
||||||
if fromto[1] == '':
|
|
||||||
fromto[1] = self.fileLength-1
|
|
||||||
fromto[0] = int(fromto[0])
|
|
||||||
fromto[1] = int(fromto[1])
|
|
||||||
if fromto[0] >= self.fileLength or fromto[0] < 0 or fromto[1] >= self.fileLength or fromto[1]-fromto[0] < 0:
|
|
||||||
# oops, already done!
|
|
||||||
self.send_response(416)
|
|
||||||
self.send_header('Content-Range', 'bytes */%s' % self.fileLength)
|
|
||||||
self.end_headers()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# now we can wind the file *brrrrrr*
|
# now we can wind the file *brrrrrr*
|
||||||
myfile.seek(fromto[0])
|
myfile.seek(fromto[0])
|
||||||
|
|
||||||
|
@ -124,7 +150,6 @@ class FileHandler(FileBaseHandler):
|
||||||
block = self.getChunk(myfile, fromto)
|
block = self.getChunk(myfile, fromto)
|
||||||
myfile.close()
|
myfile.close()
|
||||||
print "%s finished downloading" % (self.client_address[0])
|
print "%s finished downloading" % (self.client_address[0])
|
||||||
return
|
|
||||||
|
|
||||||
def getChunk(self, myfile, fromto):
|
def getChunk(self, myfile, fromto):
|
||||||
if fromto and myfile.tell()+self.blockSize >= fromto[1]:
|
if fromto and myfile.tell()+self.blockSize >= fromto[1]:
|
||||||
|
|
Loading…
Reference in New Issue