diff --git a/CHANGELOG.md b/CHANGELOG.md index f91d1db4..c6f9de1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Release History +## 2.0.0-beta.6 (Unreleased) + +## Bugs Fixed + +- ([#72](https://github.com/openai/openai-dotnet/issues/72)) Fixed `filename` request encoding in operations using `multipart/form-data`, including `files` and `audio` + ## 2.0.0-beta.5 (2024-06-14) ## Features Added diff --git a/src/Utility/MultipartFormDataBinaryContent.cs b/src/Utility/MultipartFormDataBinaryContent.cs index 7a31f110..a1d04afd 100644 --- a/src/Utility/MultipartFormDataBinaryContent.cs +++ b/src/Utility/MultipartFormDataBinaryContent.cs @@ -34,19 +34,18 @@ public string ContentType internal HttpContent HttpContent => _multipartContent; - public void Add(Stream content, string name, string fileName = default, string contentType = null) + public void Add(Stream stream, string name, string fileName = default, string contentType = null) { - Argument.AssertNotNull(content, nameof(content)); - Argument.AssertNotNullOrEmpty(name, nameof(name)); + Argument.AssertNotNull(stream, nameof(stream)); - Add(new StreamContent(content), name, fileName, contentType); + StreamContent content = new(stream); + if (contentType is not null) + { + content.Headers.ContentType = MediaTypeHeaderValue.Parse(contentType); + } + Add(content, name, fileName); } - //public void Add(Stream stream, string name, string fileName = default) - //{ - // Add(new StreamContent(stream), name, fileName); - //} - public void Add(string content, string name, string fileName = default) { Add(new StringContent(content), name, fileName); @@ -76,48 +75,19 @@ public void Add(BinaryData content, string name, string fileName = default) Add(new ByteArrayContent(content.ToArray()), name, fileName); } - private void Add(HttpContent content, string name, string filename, string contentType) - { - if (filename != null) - { - Argument.AssertNotNullOrEmpty(filename, nameof(filename)); - AddFileNameHeader(content, name, filename); - } - if (contentType != null) - { - Argument.AssertNotNullOrEmpty(contentType, nameof(contentType)); - AddContentTypeHeader(content, contentType); - } - _multipartContent.Add(content, name); - } - private void Add(HttpContent content, string name, string fileName) { + Argument.AssertNotNull(content, nameof(content)); + Argument.AssertNotNull(name, nameof(name)); + if (fileName is not null) { - AddFileNameHeader(content, name, fileName); + _multipartContent.Add(content, name, fileName); } - - _multipartContent.Add(content, name); - } - - private static void AddFileNameHeader(HttpContent content, string name, string filename) - { - // Add the content header manually because the default implementation - // adds a `filename*` parameter to the header, which RFC 7578 says not - // to do. We are following up with the BCL team per correctness. - ContentDispositionHeaderValue header = new("form-data") + else { - Name = name, - FileName = filename - }; - content.Headers.ContentDisposition = header; - } - - public static void AddContentTypeHeader(HttpContent content, string contentType) - { - MediaTypeHeaderValue header = new MediaTypeHeaderValue(contentType); - content.Headers.ContentType = header; + _multipartContent.Add(content, name); + } } #if NET6_0_OR_GREATER diff --git a/tests/Files/FileTests.cs b/tests/Files/FileTests.cs index d42421f2..2f11a632 100644 --- a/tests/Files/FileTests.cs +++ b/tests/Files/FileTests.cs @@ -83,5 +83,17 @@ public void SerializeFileCollection() // TODO: Add this test. } + [Test] + public async Task NonAsciiFilename() + { + FileClient client = GetTestClient(); + string filename = "你好.txt"; + BinaryData fileContent = BinaryData.FromString("世界您好!这是个测试。"); + OpenAIFileInfo uploadedFile = IsAsync + ? await client.UploadFileAsync(fileContent, filename, FileUploadPurpose.Assistants) + : client.UploadFile(fileContent, filename, FileUploadPurpose.Assistants); + Assert.That(uploadedFile?.Filename, Is.EqualTo(filename)); + } + private static FileClient GetTestClient() => GetTestClient(TestScenario.Files); } \ No newline at end of file