Skip to content

Commit 0467952

Browse files
Quote multipart form parameter names by default (RFC 7578) (#2357)
* Quote multipart form parameter names by default (RFC 7578) Change MultipartFormQuoteParameters default from false to true so that parameter names in Content-Disposition headers are quoted consistently with file parameter names, as required by RFC 7578. Fixes #2271 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Apply parameter name quoting to body parts in multipart form data Extend MultipartFormQuoteParameters to also cover BodyParameter parts added via AddBody, ensuring consistent Content-Disposition name quoting across all multipart form parts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3582f73 commit 0467952

File tree

3 files changed

+7
-8
lines changed

3 files changed

+7
-8
lines changed

src/RestSharp/Request/RequestContent.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ void AddBody(bool hasPostParameters, BodyParameter bodyParameter) {
143143
if (name.IsEmpty())
144144
mpContent.Add(bodyContent);
145145
else
146-
mpContent.Add(bodyContent, name);
146+
mpContent.Add(bodyContent, request.MultipartFormQuoteParameters ? $"\"{name}\"" : name);
147147
Content = mpContent;
148148
}
149149
else {

src/RestSharp/Request/RestRequest.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,9 @@ public RestRequest(Uri resource, Method method = Method.Get)
8787

8888
/// <summary>
8989
/// When set to true, parameter values in a multipart form data requests will be enclosed in
90-
/// quotation marks. Default is false. Enable it if the remote endpoint requires parameters
91-
/// to be in quotes (for example, FreshDesk API).
90+
/// quotation marks. Default is true, as per RFC 7578.
9291
/// </summary>
93-
public bool MultipartFormQuoteParameters { get; set; }
92+
public bool MultipartFormQuoteParameters { get; set; } = true;
9493

9594
/// <summary>
9695
/// When set to true, the form boundary part of the content type will be enclosed in

test/RestSharp.Tests.Integrated/MultipartFormDataTests.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void Dispose() {
3131
const string ContentDispositionString = $"{KnownHeaders.ContentDisposition}: form-data;";
3232

3333
const string Expected =
34-
$"--{{0}}{LineBreak}{ContentTypeString}{LineBreak}{ContentDispositionString} name=foo{LineBreak}{LineBreak}bar{LineBreak}" +
34+
$"--{{0}}{LineBreak}{ContentTypeString}{LineBreak}{ContentDispositionString} name=\"foo\"{LineBreak}{LineBreak}bar{LineBreak}" +
3535
$"--{{0}}{LineBreak}{ContentTypeString}{LineBreak}{ContentDispositionString} name=\"a name with spaces\"{LineBreak}{LineBreak}somedata{LineBreak}" +
3636
$"--{{0}}--{LineBreak}";
3737

@@ -41,7 +41,7 @@ public void Dispose() {
4141
$"{LineBreak}{KnownHeaders.ContentDisposition}: form-data; name=\"fileName\"; filename=\"TestFile.txt\"" +
4242
$"{LineBreak}{LineBreak}This is a test file for RestSharp.{LineBreak}" +
4343
$"--{{0}}{LineBreak}{KnownHeaders.ContentType}: application/json; {CharsetString}" +
44-
$"{LineBreak}{KnownHeaders.ContentDisposition}: form-data; name=controlName" +
44+
$"{LineBreak}{KnownHeaders.ContentDisposition}: form-data; name=\"controlName\"" +
4545
$"{LineBreak}{LineBreak}test{LineBreak}" +
4646
$"--{{0}}--{LineBreak}";
4747

@@ -199,7 +199,7 @@ public async Task MultipartFormData_Without_File_Creates_A_Valid_RequestBody() {
199199

200200
var expectedBody = new[] {
201201
ContentTypeString,
202-
$"{ContentDispositionString} name={multipartName}",
202+
$"{ContentDispositionString} name=\"{multipartName}\"",
203203
bodyData
204204
};
205205

@@ -228,7 +228,7 @@ public async Task PostParameter_contentType_in_multipart_form() {
228228

229229
var actual = capturer.Body!.Replace("\n", string.Empty).Split('\r');
230230
actual[1].Should().Be("Content-Type: application/json; charset=utf-8");
231-
actual[2].Should().Be($"Content-Disposition: form-data; name={parameterName}");
231+
actual[2].Should().Be($"Content-Disposition: form-data; name=\"{parameterName}\"");
232232
actual[4].Should().Be(parameterValue);
233233
}
234234
}

0 commit comments

Comments
 (0)