Skip to content

[azure-core] Fix wrong content-type on multipart request with no file (#39163)#47831

Open
manmohanmirkar123 wants to merge 3 commits into
Azure:mainfrom
manmohanmirkar123:fix/39163-multipart-content-type
Open

[azure-core] Fix wrong content-type on multipart request with no file (#39163)#47831
manmohanmirkar123 wants to merge 3 commits into
Azure:mainfrom
manmohanmirkar123:fix/39163-multipart-content-type

Conversation

@manmohanmirkar123

Copy link
Copy Markdown

Summary

Fixes #39163.

When a multipart payload's file part is optional and omitted, azure-core inferred that the request was not multipart — because it decided based solely on whether files was non-empty — and set Content-Type: application/x-www-form-urlencoded. This mislabels a request that should be sent as multipart/form-data (e.g. a TypeSpec-defined body whose only file part is optional).

Change

Add an is_multipart_payload flag to HttpRequest, threaded into _set_body. When set, the urlencoded Content-Type is not applied, so the transport can set the correct multipart/form-data boundary even when no file is present.

# before: no way to express intent; forced to urlencoded
# after:
HttpRequest("POST", url, data={"field": "value"}, is_multipart_payload=True)
# -> Content-Type is not forced to application/x-www-form-urlencoded

Default behavior is unchanged: a data-only request without the flag is still urlencoded.

Testing

  • Added regression tests in test_rest_http_request.py:
    • a multipart request with form data and no file no longer sets the urlencoded Content-Type
    • a data-only request without the flag still sets application/x-www-form-urlencoded
  • Existing url-encoded / multipart / json request tests still pass.

Changelog

Added a Bugs Fixed entry under an unreleased azure-core section.

When a multipart payload's file part is optional and omitted, azure-core
inferred the request was not multipart (because `files` was empty) and set
Content-Type to application/x-www-form-urlencoded.

Add an `is_multipart_payload` flag to HttpRequest so callers can mark such a
request as multipart; when set, the urlencoded content-type is not applied and
the transport sets the correct multipart boundary.

Fixes Azure#39163
Copilot AI review requested due to automatic review settings July 3, 2026 10:40
@github-actions github-actions Bot added Community Contribution Community members are working on the issue customer-reported Issues that are reported by GitHub users external to the Azure organization. labels Jul 3, 2026
@github-actions

github-actions Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Thank you for your contribution @manmohanmirkar123! We will review the pull request and get back to you soon.

@manmohanmirkar123

manmohanmirkar123 commented Jul 3, 2026

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR targets azure-core’s REST HttpRequest body handling to avoid incorrectly forcing Content-Type: application/x-www-form-urlencoded for multipart form payloads when the (optional) file part is omitted, which breaks TypeSpec-generated multipart requests (issue #39163).

Changes:

  • Threads a new internal is_multipart_payload intent flag into HttpRequest._set_body to avoid applying the urlencoded Content-Type.
  • Adds regression tests covering the new multipart-without-file scenario and ensuring the default urlencoded behavior remains unchanged.
  • Adds an unreleased changelog entry documenting the fix.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
sdk/core/azure-core/azure/core/rest/_rest_py3.py Adds is_multipart_payload plumbing into request body setup to avoid urlencoded Content-Type for intended multipart payloads.
sdk/core/azure-core/tests/test_rest_http_request.py Adds regression tests for multipart form data without files and for default urlencoding behavior.
sdk/core/azure-core/CHANGELOG.md Documents the behavioral change under an unreleased version entry.

Comment on lines +161 to +169
if files:
default_headers, self._files = set_multipart_body(files)
if data:
default_headers, self._data = set_urlencoded_body(data, has_files=bool(files))
# Treat the payload as multipart when explicitly requested, so a multipart
# request whose only file part is optional (and omitted) is not encoded as
# application/x-www-form-urlencoded.
default_headers, self._data = set_urlencoded_body(
data, has_files=bool(files) or is_multipart_payload
)
Comment on lines +101 to +102
assert "Content-Type" not in request.headers
assert request.content == {"test": "123"}
Comment thread sdk/core/azure-core/CHANGELOG.md Outdated

### Bugs Fixed

- Fixed `HttpRequest` setting a `Content-Type` of `application/x-www-form-urlencoded` on multipart requests that carry form data but no file (e.g. when the file part is optional and omitted). Such requests can now be flagged with the internal `is_multipart_payload` keyword so the transport sets the correct multipart `Content-Type`. #39163
Addresses review feedback: previously `is_multipart_payload` only suppressed
the urlencoded Content-Type, but transports decide multipart vs urlencoded
based on `request.files`, so a data-only payload was still sent urlencoded.

When `is_multipart_payload` is set and no files are provided, encode the form
fields as file-less multipart parts (name, (None, value)) in `self._files` and
clear `self._data`, so both the requests and aiohttp transports build a real
multipart/form-data body.

Update the regression test to assert the multipart parts and the changelog to
match the wire behavior.
@manmohanmirkar123

Copy link
Copy Markdown
Author

Thanks for the review — addressed the multipart feedback in e7632bb1: data-only multipart payloads are now encoded as file-less multipart parts (self._files) with self._data cleared, so the requests and aiohttp transports build a real multipart/form-data body. Test and changelog updated to match.

The CHANGELOG has a `1.42.0 (Unreleased)` section for the multipart fix, but
`_version.py` was still `1.41.0` (already released), so the changelog
verification failed. Bump the package version to match.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Community Contribution Community members are working on the issue customer-reported Issues that are reported by GitHub users external to the Azure organization.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[azure-core][bug] wrong content-type in headers of multipart request when there is no file to send

2 participants