#!/usr/bin/python
import base64
-import hashlib
-import hmac
import json
import logging
-import tempfile
import tornado.web
from .. import builds
raise tornado.web.HTTPError(error_code)
-# Uploads
-
-@tornado.web.stream_request_body
-class UploadHandler(BaseHandler):
- @tornado.web.authenticated
- def initialize(self):
- # Fetch the filename
- self.filename = self.get_argument("filename")
-
- # Fetch file size
- self.filesize = self.get_argument_int("size")
-
- # Check quota
- if isinstance(self.current_user, users.User):
- try:
- self.current_user.check_quota(self.filesize)
- except users.QuotaExceededError as e:
- raise tornado.web.HTTPError(400,
- "Quota exceeded for %s" % self.current_user) from e
-
- # Count how many bytes have been received
- self.bytes_read = 0
-
- # Allocate a temporary file
- self.f = self.backend.uploads.allocate_file()
-
- self.h, self.hexdigest = self._setup_digest()
-
- def data_received(self, data):
- """
- Called when some data is being received
- """
- self.bytes_read += len(data)
-
- # Abort if we have received more data than expected
- if self.bytes_read > self.filesize:
- # 422 - Unprocessable Entity
- raise tornado.web.HTTPError(422)
-
- # Update the digest
- self.h.update(data)
-
- # Write payload
- self.f.write(data)
-
- async def put(self):
- """
- Called after the entire file has been received
- """
- log.debug("Finished receiving data")
-
- # Finish computing the hexdigest
- computed_hexdigest = self.h.hexdigest()
-
- # Check if the hexdigest matches
- # If not, we will raise an error
- if not hmac.compare_digest(self.hexdigest, computed_hexdigest):
- # 422 - Unprocessable Entity
- raise tornado.web.HTTPError(422)
-
- # Create a new upload object
- with self.db.transaction():
- upload = self.backend.uploads.create(
- self.filename,
- self.f.name,
- builder=self.builder,
- user=self.user,
- )
-
- # Free the temporary file (to prevent cleanup)
- self.f = None
-
- # Send the ID of the upload back to the client
- self.finish({
- "id" : upload.uuid,
- "expires_at" : upload.expires_at.isoformat(),
- })
-
- def _setup_digest(self):
- # Fetch the digest argument
- digest = self.get_argument("digest")
-
- # Find the algorithm
- algo, delim, hexdigest = digest.partition(":")
-
- try:
- h = hashlib.new(algo)
- except ValueError as e:
- raise tornado.web.HTTPError(415) from e
-
- return h, hexdigest
-
- def on_connection_close(self):
- """
- Called when a connection was unexpectedly closed
- """
- # Try deleting the file
- if self.f:
- log.debug("Deleting temporary file %s" % self.f.name)
- os.unlink(self.f.name)
-
-
# Builds
class BuildsGetHandler(BaseHandler):
--- /dev/null
+#!/usr/bin/python3
+###############################################################################
+# #
+# Pakfire - The IPFire package management system #
+# Copyright (C) 2011 Pakfire development team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+import hashlib
+import hmac
+import logging
+import os
+import tornado.web
+
+from .handlers import BaseHandler
+from .. import users
+
+# Setup logging
+log = logging.getLogger("pakfire.hub.uploads")
+
+@tornado.web.stream_request_body
+class CreateHandler(BaseHandler):
+ @tornado.web.authenticated
+ def initialize(self):
+ # Fetch the filename
+ self.filename = self.get_argument("filename")
+
+ # Fetch file size
+ self.filesize = self.get_argument_int("size")
+
+ # Check quota
+ if isinstance(self.current_user, users.User):
+ try:
+ self.current_user.check_quota(self.filesize)
+ except users.QuotaExceededError as e:
+ raise tornado.web.HTTPError(400,
+ "Quota exceeded for %s" % self.current_user) from e
+
+ # Count how many bytes have been received
+ self.bytes_read = 0
+
+ # Allocate a temporary file
+ self.f = self.backend.uploads.allocate_file()
+
+ self.h, self.hexdigest = self._setup_digest()
+
+ def data_received(self, data):
+ """
+ Called when some data is being received
+ """
+ self.bytes_read += len(data)
+
+ # Abort if we have received more data than expected
+ if self.bytes_read > self.filesize:
+ # 422 - Unprocessable Entity
+ raise tornado.web.HTTPError(422)
+
+ # Update the digest
+ self.h.update(data)
+
+ # Write payload
+ self.f.write(data)
+
+ async def put(self):
+ """
+ Called after the entire file has been received
+ """
+ log.debug("Finished receiving data")
+
+ # Finish computing the hexdigest
+ computed_hexdigest = self.h.hexdigest()
+
+ # Check if the hexdigest matches
+ # If not, we will raise an error
+ if not hmac.compare_digest(self.hexdigest, computed_hexdigest):
+ # 422 - Unprocessable Entity
+ raise tornado.web.HTTPError(422)
+
+ # Create a new upload object
+ with self.db.transaction():
+ upload = self.backend.uploads.create(
+ self.filename,
+ self.f.name,
+ builder=self.builder,
+ user=self.user,
+ )
+
+ # Free the temporary file (to prevent cleanup)
+ self.f = None
+
+ # Send the ID of the upload back to the client
+ self.finish({
+ "id" : upload.uuid,
+ "expires_at" : upload.expires_at.isoformat(),
+ })
+
+ def _setup_digest(self):
+ # Fetch the digest argument
+ digest = self.get_argument("digest")
+
+ # Find the algorithm
+ algo, delim, hexdigest = digest.partition(":")
+
+ try:
+ h = hashlib.new(algo)
+ except ValueError as e:
+ raise tornado.web.HTTPError(415) from e
+
+ return h, hexdigest
+
+ def on_connection_close(self):
+ """
+ Called when a connection was unexpectedly closed
+ """
+ # Try deleting the file
+ if self.f:
+ log.debug("Deleting temporary file %s" % self.f.name)
+ os.unlink(self.f.name)