upload: Add charset even on content-types guessed at download time.

This commit is contained in:
Alex Vandiver
2025-07-29 14:40:17 +00:00
committed by Tim Abbott
parent 0c6b3373be
commit e37ee13577
2 changed files with 25 additions and 0 deletions

View File

@@ -189,6 +189,17 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
self.assertEqual(result["Content-Type"], "application/octet-stream")
consume_response(result)
# Old files may be stored without a content-type in the
# database, in which case we try to guess at download time.
attachment = Attachment.objects.get(file_name="somefile")
self.assertEqual(attachment.content_type, "application/octet-stream")
attachment.content_type = None
attachment.save(update_fields=["content_type"])
result = self.client_get(url)
self.assertEqual(result.status_code, 200)
self.assertEqual(result["Content-Type"], "application/octet-stream")
consume_response(result)
uploaded_file = SimpleUploadedFile("somefile.txt", b"zulip!", content_type="")
result = self.api_post(
self.example_user("hamlet"), "/api/v1/user_uploads", {"file": uploaded_file}
@@ -202,6 +213,16 @@ class FileUploadTest(UploadSerializeMixin, ZulipTestCase):
self.assertEqual(result["Content-Type"], 'text/plain; charset="ascii"')
consume_response(result)
# As above, test without a stored content_type
attachment = Attachment.objects.get(file_name="somefile.txt")
self.assertEqual(attachment.content_type, 'text/plain; charset="ascii"')
attachment.content_type = None
attachment.save(update_fields=["content_type"])
result = self.client_get(url)
self.assertEqual(result.status_code, 200)
self.assertEqual(result["Content-Type"], 'text/plain; charset="ascii"')
consume_response(result)
def test_guess_content_type_charset(self) -> None:
uploaded_file = SimpleUploadedFile(
"somefile.txt", "नाम में क्या रक्खा हे".encode(), content_type="text/plain"

View File

@@ -38,8 +38,10 @@ from zerver.lib.thumbnail import (
get_image_thumbnail_path,
)
from zerver.lib.upload import (
attachment_vips_source,
check_upload_within_quota,
get_public_upload_root_url,
maybe_add_charset,
upload_message_attachment_from_request,
)
from zerver.lib.upload.local import assert_is_local_storage_path
@@ -132,6 +134,8 @@ def serve_local(
if content_type is None:
content_type = guess_type(filename)[0] or "application/octet-stream"
content_type = maybe_add_charset(content_type, attachment_vips_source(path_id))
download = force_download or bare_content_type(content_type) not in INLINE_MIME_TYPES
if settings.DEVELOPMENT: