mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-01-07 21:00:49 +08:00
fix: Content-Disposition header format to comply with RFC 2183
Fixes #8914 The Content-Disposition header was set to `filename="name.ext"` which doesn't match RFC 2183 specification. This caused third-party libraries (e.g., Go's mime.ParseMediaType) to fail parsing the header. Changed to `inline; filename="name.ext"` format which properly includes the disposition-type as required by RFC 2183.
This commit is contained in:
parent
3a5f239cb6
commit
8595a48795
@ -511,7 +511,7 @@ class PromptServer():
|
||||
buffer.seek(0)
|
||||
|
||||
return web.Response(body=buffer.read(), content_type=f'image/{image_format}',
|
||||
headers={"Content-Disposition": f"filename=\"{filename}\""})
|
||||
headers={"Content-Disposition": f"inline; filename=\"{filename}\""})
|
||||
|
||||
if 'channel' not in request.rel_url.query:
|
||||
channel = 'rgba'
|
||||
@ -531,7 +531,7 @@ class PromptServer():
|
||||
buffer.seek(0)
|
||||
|
||||
return web.Response(body=buffer.read(), content_type='image/png',
|
||||
headers={"Content-Disposition": f"filename=\"{filename}\""})
|
||||
headers={"Content-Disposition": f"inline; filename=\"{filename}\""})
|
||||
|
||||
elif channel == 'a':
|
||||
with Image.open(file) as img:
|
||||
@ -548,7 +548,7 @@ class PromptServer():
|
||||
alpha_buffer.seek(0)
|
||||
|
||||
return web.Response(body=alpha_buffer.read(), content_type='image/png',
|
||||
headers={"Content-Disposition": f"filename=\"{filename}\""})
|
||||
headers={"Content-Disposition": f"inline; filename=\"{filename}\""})
|
||||
else:
|
||||
# Get content type from mimetype, defaulting to 'application/octet-stream'
|
||||
content_type = mimetypes.guess_type(filename)[0] or 'application/octet-stream'
|
||||
@ -560,7 +560,7 @@ class PromptServer():
|
||||
return web.FileResponse(
|
||||
file,
|
||||
headers={
|
||||
"Content-Disposition": f"filename=\"{filename}\"",
|
||||
"Content-Disposition": f"inline; filename=\"{filename}\"",
|
||||
"Content-Type": content_type
|
||||
}
|
||||
)
|
||||
|
||||
75
tests-unit/server_test/test_content_disposition.py
Normal file
75
tests-unit/server_test/test_content_disposition.py
Normal file
@ -0,0 +1,75 @@
|
||||
"""Tests for Content-Disposition header format (RFC 2183 compliance)
|
||||
|
||||
Relates to issue #8914: Content-Disposition Header not matching RFC2183 rules
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import re
|
||||
|
||||
|
||||
class TestContentDispositionHeader:
|
||||
"""Test Content-Disposition header format compliance with RFC 2183."""
|
||||
|
||||
def test_rfc2183_format_with_inline(self):
|
||||
"""Verify inline disposition type format matches RFC 2183."""
|
||||
filename = "test_image.png"
|
||||
header = f'inline; filename="{filename}"'
|
||||
|
||||
# RFC 2183 requires disposition-type followed by parameters
|
||||
# Format: disposition-type ";" disposition-parm
|
||||
pattern = r'^(inline|attachment);\s*filename="[^"]*"$'
|
||||
assert re.match(pattern, header), f"Header '{header}' does not match RFC 2183 format"
|
||||
|
||||
def test_rfc2183_format_with_attachment(self):
|
||||
"""Verify attachment disposition type format matches RFC 2183."""
|
||||
filename = "download.mp4"
|
||||
header = f'attachment; filename="{filename}"'
|
||||
|
||||
pattern = r'^(inline|attachment);\s*filename="[^"]*"$'
|
||||
assert re.match(pattern, header), f"Header '{header}' does not match RFC 2183 format"
|
||||
|
||||
def test_invalid_format_missing_disposition_type(self):
|
||||
"""Verify that format without disposition type is invalid."""
|
||||
filename = "test.jpg"
|
||||
invalid_header = f'filename="{filename}"'
|
||||
|
||||
pattern = r'^(inline|attachment);\s*filename="[^"]*"$'
|
||||
assert not re.match(pattern, invalid_header), \
|
||||
"Header without disposition type should not match RFC 2183 format"
|
||||
|
||||
@pytest.mark.parametrize("filename", [
|
||||
"image.png",
|
||||
"video.mp4",
|
||||
"file with spaces.jpg",
|
||||
"special_chars-123.webp",
|
||||
])
|
||||
def test_various_filenames(self, filename):
|
||||
"""Test RFC 2183 format with various filename patterns."""
|
||||
header = f'inline; filename="{filename}"'
|
||||
|
||||
# Should have disposition type before filename
|
||||
assert header.startswith("inline; ") or header.startswith("attachment; ")
|
||||
assert f'filename="{filename}"' in header
|
||||
|
||||
|
||||
class TestContentDispositionParsing:
|
||||
"""Test that Content-Disposition headers can be parsed by standard libraries."""
|
||||
|
||||
def test_parse_inline_disposition(self):
|
||||
"""Test parsing inline disposition header."""
|
||||
header = 'inline; filename="test.png"'
|
||||
|
||||
# Simple parsing test - split by semicolon
|
||||
parts = [p.strip() for p in header.split(';')]
|
||||
assert parts[0] in ('inline', 'attachment')
|
||||
assert 'filename=' in parts[1]
|
||||
|
||||
def test_extract_filename(self):
|
||||
"""Test extracting filename from header."""
|
||||
filename = "my_image.jpg"
|
||||
header = f'inline; filename="{filename}"'
|
||||
|
||||
# Extract filename using regex
|
||||
match = re.search(r'filename="([^"]*)"', header)
|
||||
assert match is not None
|
||||
assert match.group(1) == filename
|
||||
Loading…
Reference in New Issue
Block a user