mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-05 05:16:03 +00:00
Fix: Enforce 10MB upload limit for knowledge base with clear error handling (#1755)
* Initial plan * Set MAX_CONTENT_LENGTH to 10MB and add file size validation Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com> * Add custom error handler for 413 RequestEntityTooLarge Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com> * Refactor: Extract MAX_FILE_SIZE constant to avoid duplication Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com> * Fix file name extraction and add missing file validation Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com> * Apply file size validation to all upload endpoints consistently Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com> * Add frontend file size validation for knowledge base and plugin uploads Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com> * Remove file size validation from plugin uploads, keep only for knowledge base Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com> * perf: ui --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: RockChinQ <45992437+RockChinQ@users.noreply.github.com> Co-authored-by: Junyan Qin <rockchinq@gmail.com>
This commit is contained in:
@@ -31,19 +31,41 @@ class FilesRouterGroup(group.RouterGroup):
|
||||
@self.route('/documents', methods=['POST'], auth_type=group.AuthType.USER_TOKEN)
|
||||
async def _() -> quart.Response:
|
||||
request = quart.request
|
||||
|
||||
# Check file size limit before reading the file
|
||||
content_length = request.content_length
|
||||
if content_length and content_length > group.MAX_FILE_SIZE:
|
||||
return self.fail(400, 'File size exceeds 10MB limit. Please split large files into smaller parts.')
|
||||
|
||||
# get file bytes from 'file'
|
||||
file = (await request.files)['file']
|
||||
files = await request.files
|
||||
if 'file' not in files:
|
||||
return self.fail(400, 'No file provided in request')
|
||||
|
||||
file = files['file']
|
||||
assert isinstance(file, quart.datastructures.FileStorage)
|
||||
|
||||
file_bytes = await asyncio.to_thread(file.stream.read)
|
||||
extension = file.filename.split('.')[-1]
|
||||
file_name = file.filename.split('.')[0]
|
||||
|
||||
# Double-check actual file size after reading
|
||||
if len(file_bytes) > group.MAX_FILE_SIZE:
|
||||
return self.fail(400, 'File size exceeds 10MB limit. Please split large files into smaller parts.')
|
||||
|
||||
# Split filename and extension properly
|
||||
if '.' in file.filename:
|
||||
file_name, extension = file.filename.rsplit('.', 1)
|
||||
else:
|
||||
file_name = file.filename
|
||||
extension = ''
|
||||
|
||||
# check if file name contains '/' or '\'
|
||||
if '/' in file_name or '\\' in file_name:
|
||||
return self.fail(400, 'File name contains invalid characters')
|
||||
|
||||
file_key = file_name + '_' + str(uuid.uuid4())[:8] + '.' + extension
|
||||
file_key = file_name + '_' + str(uuid.uuid4())[:8]
|
||||
if extension:
|
||||
file_key += '.' + extension
|
||||
|
||||
# save file to storage
|
||||
await self.ap.storage_mgr.storage_provider.save(file_key, file_bytes)
|
||||
return self.success(
|
||||
|
||||
Reference in New Issue
Block a user