return type or "application/octet-stream"
- # Payload
+ # Send Payload
- async def get_payload(self):
- """
- Fetches and returns the payload
- """
+ @property
+ async def payload(self):
# Open the package
p = await self.package.open()
# Read the payload in a separate thread
return await asyncio.to_thread(func)
+
+ async def sendfile(self, f, chunk_size=102400):
+ """
+ Sends the payload of the file into the given file descriptor
+ """
+ # XXX This should ideally not load the entire payload into memory at once
+
+ # Fetch the payload
+ payload = await self.payload
+
+ # Send the payload in chunks, so that we do not overwhelm Tornado
+ for i in range(0, self.size, chunk_size):
+ block = payload[i:i+chunk_size]
+
+ f.write(block)
(r"/packages", packages.IndexHandler),
(r"/packages/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})", packages.ShowHandler),
(r"/packages/([\w\-\+]+)", packages.NameHandler),
- (r"/package/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/download(.*)",
+ (r"/packages/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/download(.*)",
packages.FileDownloadHandler),
- (r"/package/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/view(.*)",
+ (r"/packages/([\w]{8}-[\w]{4}-[\w]{4}-[\w]{4}-[\w]{12})/view(.*)",
packages.FileViewHandler),
# Builds
# Send the filename
self.set_header("Content-Disposition",
- "attachment; filename=%s" % os.path.basename(file.name))
+ "attachment; filename=%s" % os.path.basename(file.path))
# These pages should not be indexed
self.add_header("X-Robots-Tag", "noindex")
- # XXX this should probably not be done in one large operation.
- # Instead we should send the file chunk by chunk.
-
- # Fetch the payload
- payload = await file.get_payload()
-
- # Send the payload to the client
- self.finish(payload)
+ # Send the payload
+ await file.sendfile(self)
class FileViewHandler(base.BaseHandler):
# These pages should not be indexed
self.add_header("X-Robots-Tag", "noindex")
- # Fetch payload
- payload = await file.get_payload()
-
- self.render("packages/view-file.html", package=package, file=file, payload=payload)
+ self.render("packages/view-file.html", package=package,
+ file=file, payload=await file.payload)
class DependenciesModule(ui_modules.UIModule):