app: raise tornado http exceptions in upload handler

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Eric Callahan 2023-10-30 10:15:35 -04:00
parent 4f32f477bd
commit e03dbe3251
No known key found for this signature in database
GPG Key ID: 5A1EB336DFB4C71B
1 changed files with 16 additions and 11 deletions

View File

@ -926,11 +926,15 @@ class FileUploadHandler(AuthorizedRequestHandler):
'file_manager') 'file_manager')
self.max_upload_size = max_upload_size self.max_upload_size = max_upload_size
self.parse_lock = Lock() self.parse_lock = Lock()
self.parse_error: Optional[ParseFailedException] = None self.parse_failed: bool = False
def prepare(self) -> None: def prepare(self) -> None:
super(FileUploadHandler, self).prepare() super(FileUploadHandler, self).prepare()
logging.info(f"Upload Request Received from {self.request.remote_ip}") content_type: str = self.request.headers.get("Content-Type", "")
logging.info(
f"Upload Request Received from {self.request.remote_ip}\n"
f"Content-Type: {content_type}"
)
fm: FileManager = self.server.lookup_component("file_manager") fm: FileManager = self.server.lookup_component("file_manager")
fm.check_write_enabled() fm.check_write_enabled()
if self.request.method == "POST": if self.request.method == "POST":
@ -952,24 +956,23 @@ class FileUploadHandler(AuthorizedRequestHandler):
self._parser.register(name, target) self._parser.register(name, target)
async def data_received(self, chunk: bytes) -> None: async def data_received(self, chunk: bytes) -> None:
if self.request.method == "POST" and self.parse_error is None: if self.request.method == "POST" and not self.parse_failed:
async with self.parse_lock: async with self.parse_lock:
evt_loop = self.server.get_event_loop() evt_loop = self.server.get_event_loop()
try: try:
await evt_loop.run_in_thread(self._parser.data_received, chunk) await evt_loop.run_in_thread(self._parser.data_received, chunk)
except ParseFailedException as err: except ParseFailedException:
self.parse_error = err logging.exception("Chunk Parsing Error")
self.parse_failed = True
async def post(self) -> None: async def post(self) -> None:
if self.parse_error is not None: if self.parse_failed:
self._file.on_finish() self._file.on_finish()
try: try:
os.remove(self._file.filename) os.remove(self._file.filename)
except Exception: except Exception:
pass pass
raise self.server.error( raise tornado.web.HTTPError(500, "File Upload Parsing Failed")
"File Upload Parsing Failed", 500
) from self.parse_error
form_args = {} form_args = {}
chk_target = self._targets.pop('checksum') chk_target = self._targets.pop('checksum')
calc_chksum = self._sha256_target.value.lower() calc_chksum = self._sha256_target.value.lower()
@ -982,9 +985,11 @@ class FileUploadHandler(AuthorizedRequestHandler):
os.remove(self._file.filename) os.remove(self._file.filename)
except Exception: except Exception:
pass pass
raise self.server.error( raise tornado.web.HTTPError(
422,
f"File checksum mismatch: expected {recd_cksum}, " f"File checksum mismatch: expected {recd_cksum}, "
f"calculated {calc_chksum}", 422) f"calculated {calc_chksum}"
)
for name, target in self._targets.items(): for name, target in self._targets.items():
if target.value: if target.value:
form_args[name] = target.value.decode() form_args[name] = target.value.decode()