Skip to content

Commit 9768f1f

Browse files
Fix Content-Type header bugs in file downloads and MIME type handling (#14124)
Fixes #14118 This commit fixes multiple bugs related to MIME type handling in file downloads: 1. Fixed tuple-as-string bug where mimetypes.guess_type() was used directly in f-strings, resulting in invalid Content-Type headers like "('image/png', None)" instead of "image/png" 2. Added fallback to "application/octet-stream" when MIME type cannot be determined (when guess_type returns None) 3. Fixed incorrect content type for JSON exports (was "json" instead of "application/json") 4. Fixed potential AttributeError crash in inline_image template tag when guess_type returns None and code attempted to call .startswith() on None Files changed: - dojo/api_v2/views.py: Risk acceptance file download (API endpoint) - dojo/utils.py: Generic file response helper function - dojo/finding/views.py: Finding image downloads and JSON template export - dojo/engagement/views.py: Risk acceptance proof downloads - dojo/templatetags/display_tags.py: Inline image template tag All file downloads now properly set Content-Type headers with appropriate fallbacks for unknown file types.
1 parent cc52641 commit 9768f1f

5 files changed

Lines changed: 6 additions & 6 deletions

File tree

dojo/api_v2/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ def download_proof(self, request, pk=None):
751751
# send file
752752
response = FileResponse(
753753
file_handle,
754-
content_type=f"{mimetypes.guess_type(str(file_path))}",
754+
content_type=mimetypes.guess_type(str(file_path))[0] or "application/octet-stream",
755755
status=status.HTTP_200_OK,
756756
)
757757
response["Content-Length"] = file_object.size

dojo/engagement/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1568,7 +1568,7 @@ def download_risk_acceptance(request, eid, raid):
15681568
(Path(settings.MEDIA_ROOT) / "risk_acceptance.path.name").open(mode="rb")))
15691569
response["Content-Disposition"] = f'attachment; filename="{risk_acceptance.filename()}"'
15701570
mimetype, _encoding = mimetypes.guess_type(risk_acceptance.path.name)
1571-
response["Content-Type"] = mimetype
1571+
response["Content-Type"] = mimetype or "application/octet-stream"
15721572
return response
15731573

15741574

dojo/finding/views.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2175,7 +2175,7 @@ def templates(request):
21752175
@user_has_global_permission(Permissions.Finding_Edit)
21762176
def export_templates_to_json(request):
21772177
leads_as_json = serializers.serialize("json", Finding_Template.objects.all())
2178-
return HttpResponse(leads_as_json, content_type="json")
2178+
return HttpResponse(leads_as_json, content_type="application/json")
21792179

21802180

21812181
def ensure_template_tags_in_finding_model(template):
@@ -2444,7 +2444,7 @@ class Original(ImageSpec):
24442444
response = StreamingHttpResponse(FileIterWrapper(image))
24452445
response["Content-Disposition"] = "inline"
24462446
mimetype, _encoding = mimetypes.guess_type(file_name)
2447-
response["Content-Type"] = mimetype
2447+
response["Content-Type"] = mimetype or "application/octet-stream"
24482448
return response
24492449

24502450

dojo/templatetags/display_tags.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ def inline_image(image_file):
452452
# TODO: This code might need better exception handling or data processing
453453
if img_types := mimetypes.guess_type(image_file.file.name):
454454
img_type = img_types[0]
455-
if img_type.startswith("image/"):
455+
if img_type and img_type.startswith("image/"):
456456
img_data = base64.b64encode(image_file.file.read())
457457
return f"data:{img_type};base64, {img_data.decode('utf-8')}"
458458
return ""

dojo/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2404,7 +2404,7 @@ def generate_file_response_from_file_path(
24042404
response = FileResponse(
24052405
path.open("rb"),
24062406
filename=full_file_name,
2407-
content_type=f"{mimetypes.guess_type(file_path)}",
2407+
content_type=mimetypes.guess_type(file_path)[0] or "application/octet-stream",
24082408
)
24092409
# Add some important headers
24102410
response["Content-Disposition"] = f'attachment; filename="{full_file_name}"'

0 commit comments

Comments
 (0)