fix(http-client-python): synthesize filename in multipart Content-Disposition for bare file inputs#10843
fix(http-client-python): synthesize filename in multipart Content-Disposition for bare file inputs#10843iscai-msft wants to merge 8 commits into
Conversation
commit: |
|
All changed packages have been documented.
Show changes
|
|
You can try these changes here
|
…ition When callers pass bare bytes/str/IO instead of a (filename, content) tuple for multipart file fields, the prepare_multipart_form_data helper now wraps them with a synthesized filename derived from IO.name or the field name. This ensures the Content-Disposition header includes filename= so servers that require it (e.g. for .zip detection) don't reject the upload. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
196355c to
4ad096a
Compare
…esis Add sync and async test variants that pass bare open() IO (without explicit filename tuples) to the uploadFileRequiredFilename, uploadFileSpecificContentType, and uploadFileArray Spector scenarios. These exercise _normalize_multipart_file_entry and verify the server receives filename= in Content-Disposition. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
| # (non-tuple) values - a tuple bypasses that default and falls back to the | ||
| # HTTP "text/plain" default instead. Setting it explicitly preserves the | ||
| # pre-existing behavior for bare bytes/IO across all transports. | ||
| return (filename, entry, "application/octet-stream") |
There was a problem hiding this comment.
I add default content-type "application/octet-stream" to keep consistent with sdk core behavior https://github.com/Azure/azure-sdk-for-python/blob/c8abdc18a0d51368f3ff7fc9dea71dbf131550e4/sdk/core/azure-core/azure/core/utils/_pipeline_transport_rest_shared.py#L374 so that SDK keep compatible in runtime. cc @iscai-msft / @tadelesh
Problem
When callers pass bare
bytes/str/IO(theFileContentvariant ofFileType) for multipart file fields, the generatedprepare_multipart_form_datahelper creates(field_name, bare_content). The HTTP library interprets this asContent-Disposition: form-data; name="field_name"with nofilename=attribute.Many servers require
filename=in theContent-Dispositionheader to recognize file uploads (e.g., servers that use the file extension to detect package type will reject with "At least one file must be uploaded").The tuple variants
(filename, content)and(filename, content, content_type)already work correctly since they producefilename=in the header.Fix
Added
_normalize_multipart_file_entryhelper inutils.py.jinja2that wraps bare content into a(filename, content)tuple:.name: derives filename viaos.path.basename()(e.g.,open('path/to/image.jpg')→filename="image.jpg")"profileImage") or"field_0","field_1"for list entriesAlso changed
elif multipart_entry:toelif multipart_entry is not None:to allow empty bytes (b"") to be uploaded.Files Changed
generator/pygen/codegen/templates/utils.py.jinja2: Added_normalize_multipart_file_entryhelper, updatedprepare_multipart_form_datagenerator/pygen/codegen/serializers/general_serializer.py: Addedimport osto generated utils imports