Skip to content

Commit

Permalink
Fixed the boundary quotes
Browse files Browse the repository at this point in the history
  • Loading branch information
alexeyzimarev committed Mar 29, 2023
1 parent 76dfa39 commit 51054b6
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 23 deletions.
26 changes: 14 additions & 12 deletions src/RestSharp/Request/RequestContent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public HttpContent BuildContent() {
void AddFiles() {
if (!_request.HasFiles() && !_request.AlwaysMultipartFormData) return;

var mpContent = new MultipartFormDataContent(GetOrSetFormBoundary());
var mpContent = CreateMultipartFormDataContent();

foreach (var file in _request.Files) {
var stream = file.GetFile();
Expand All @@ -58,10 +58,7 @@ void AddFiles() {

var dispositionHeader = file.Options.DisableFilenameEncoding
? ContentDispositionHeaderValue.Parse($"form-data; name=\"{file.Name}\"; filename=\"{file.FileName}\"")
: new ContentDispositionHeaderValue("form-data") {
Name = $"\"{file.Name}\"",
FileName = $"\"{file.FileName}\""
};
: new ContentDispositionHeaderValue("form-data") { Name = $"\"{file.Name}\"", FileName = $"\"{file.FileName}\"" };
if (!file.Options.DisableFileNameStar) dispositionHeader.FileNameStar = file.FileName;
fileContent.Headers.ContentDisposition = dispositionHeader;

Expand Down Expand Up @@ -102,11 +99,7 @@ HttpContent GetSerialized() {

var contentType = body.ContentType.Or(serializer.Serializer.ContentType);

return new StringContent(
content,
_client.Options.Encoding,
contentType.Value
);
return new StringContent(content, _client.Options.Encoding, contentType.Value);
}
}

Expand All @@ -117,6 +110,15 @@ static bool BodyShouldBeMultipartForm(BodyParameter bodyParameter) {

string GetOrSetFormBoundary() => _request.FormBoundary ?? (_request.FormBoundary = Guid.NewGuid().ToString());

MultipartFormDataContent CreateMultipartFormDataContent() {
var boundary = GetOrSetFormBoundary();
var mpContent = new MultipartFormDataContent(boundary);
var contentType = new MediaTypeHeaderValue("multipart/form-data");
contentType.Parameters.Add(new NameValueHeaderValue(nameof(boundary), GetBoundary(boundary, _request.MultipartFormQuoteParameters)));
mpContent.Headers.ContentType = contentType;
return mpContent;
}

void AddBody(bool hasPostParameters) {
if (!_request.TryGetBodyParameter(out var bodyParameter)) return;

Expand All @@ -125,7 +127,7 @@ void AddBody(bool hasPostParameters) {
// we need to send the body
if (hasPostParameters || _request.HasFiles() || BodyShouldBeMultipartForm(bodyParameter!) || _request.AlwaysMultipartFormData) {
// here we must use multipart form data
var mpContent = Content as MultipartFormDataContent ?? new MultipartFormDataContent(GetOrSetFormBoundary());
var mpContent = Content as MultipartFormDataContent ?? CreateMultipartFormDataContent();
var ct = bodyContent.Headers.ContentType?.MediaType;
var name = bodyParameter!.Name.IsEmpty() ? ct : bodyParameter.Name;

Expand Down Expand Up @@ -155,7 +157,7 @@ void AddPostParameters(GetOrPostParameter[] postParameters) {

mpContent.Add(
new StringContent(postParameter.Value?.ToString() ?? "", _client.Options.Encoding, postParameter.ContentType.Value),
GetBoundary(parameterName, _request.MultipartFormQuoteParameters)
parameterName
);
}
}
Expand Down
36 changes: 25 additions & 11 deletions test/RestSharp.Tests.Integrated/MultipartFormDataTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ public MultipartFormDataTests(ITestOutputHelper output) {
$"--{{0}}--{LineBreak}";

const string ExpectedFileAndBodyRequestContent =
"--{0}" +
$"{LineBreak}{KnownHeaders.ContentType}: application/octet-stream" +
"--{0}" +
$"{LineBreak}{KnownHeaders.ContentType}: application/octet-stream" +
$"{LineBreak}{KnownHeaders.ContentDisposition}: form-data; name=\"fileName\"; filename=\"TestFile.txt\"" +
$"{LineBreak}{LineBreak}This is a test file for RestSharp.{LineBreak}" +
$"--{{0}}{LineBreak}{KnownHeaders.ContentType}: application/json; {CharsetString}" +
$"{LineBreak}{KnownHeaders.ContentDisposition}: form-data; name=controlName" +
$"{LineBreak}{LineBreak}test{LineBreak}" +
$"{LineBreak}{LineBreak}This is a test file for RestSharp.{LineBreak}" +
$"--{{0}}{LineBreak}{KnownHeaders.ContentType}: application/json; {CharsetString}" +
$"{LineBreak}{KnownHeaders.ContentDisposition}: form-data; name=controlName" +
$"{LineBreak}{LineBreak}test{LineBreak}" +
$"--{{0}}--{LineBreak}";

const string ExpectedDefaultMultipartContentType = "multipart/form-data; boundary=\"{0}\"";
Expand Down Expand Up @@ -76,11 +76,24 @@ public async Task AlwaysMultipartFormData_WithParameter_Execute() {
Assert.Null(response.ErrorException);
}

[Fact]
public async Task MultipartFormData_NoBoundaryQuotes() {
var request = new RestRequest("/", Method.Post) { AlwaysMultipartFormData = true };

AddParameters(request);
request.MultipartFormQuoteParameters = false;

var response = await _client.ExecuteAsync(request);

var expected = string.Format(Expected, request.FormBoundary);

response.Content.Should().Be(expected);
RequestHandler.CapturedContentType.Should().Be($"multipart/form-data; boundary={request.FormBoundary}");
}

[Fact]
public async Task MultipartFormData() {
var request = new RestRequest("/", Method.Post) {
AlwaysMultipartFormData = true
};
var request = new RestRequest("/", Method.Post) { AlwaysMultipartFormData = true };

AddParameters(request);

Expand All @@ -91,7 +104,8 @@ public async Task MultipartFormData() {
_output.WriteLine($"Expected: {expected}");
_output.WriteLine($"Actual: {response.Content}");

Assert.Equal(expected, response.Content);
response.Content.Should().Be(expected);
RequestHandler.CapturedContentType.Should().Be($"multipart/form-data; boundary=\"{request.FormBoundary}\"");
}

[Fact]
Expand Down Expand Up @@ -187,4 +201,4 @@ public async Task ShouldHaveJsonContentType() {

var response = await _client.ExecuteAsync(request);
}
}
}

0 comments on commit 51054b6

Please sign in to comment.