Skip to content

Commit

Permalink
Multipart form-data (#4613)
Browse files Browse the repository at this point in the history
implement multipart/form-data operation
  • Loading branch information
chunyu3 committed Apr 26, 2024
1 parent c2796ea commit dac2fba
Show file tree
Hide file tree
Showing 201 changed files with 29,118 additions and 221 deletions.
3 changes: 2 additions & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
<!-- TODO we should figure out how to make our generator create the right thing for these two warnings https://github.com/Azure/autorest.csharp/issues/3706 -->
<NoWarn Condition="'$(IsTestGenerationSrcProject)' == 'true'">$(NoWarn);AZC0006;AZC0007</NoWarn>
<!-- TODO new project need this-->
<NoWarn Condition="'$(IsTestGenerationSrcProject)' == 'true'">$(NoWarn);AZC0008</NoWarn>
<NoWarn Condition="'$(IsTestGenerationSrcProject)' == 'true'">$(NoWarn);AZC0008</NoWarn>
<NoWarn Condition="'$(IsUnbranded)' == 'true'">AZC0107</NoWarn>
<IncludeSharedSourceInLocalBuild Condition="!$(MSBuildProjectName.StartsWith('AutoRest.')) And '$(IsTestGenerationTestProject)' != 'true'">true</IncludeSharedSourceInLocalBuild>
</PropertyGroup>

Expand Down
4 changes: 3 additions & 1 deletion eng/testProjects.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"encode/duration",
"payload/content-negotiation",
"payload/media-type",
"payload/multipart",
"payload/pageable",
"serialization/encoded-name/json",
"server/endpoint/not-defined",
Expand All @@ -54,7 +55,8 @@
"CadlRanchProjectsNonAzure":[
"type/array",
"type/dictionary",
"authentication/http/custom"
"authentication/http/custom",
"payload/multipart"
],
"TestServerProjects": [
"additionalProperties",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

// <auto-generated/>

#nullable disable

using System;
using System.Globalization;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using Azure.Core;
using Azure.Core.Pipeline;

namespace AppConfiguration
{
internal class MultipartFormDataRequestContent : RequestContent
{
private readonly System.Net.Http.MultipartFormDataContent _multipartContent;
private static readonly Random _random = new Random();
private static readonly char[] _boundaryValues = "0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz".ToCharArray();

public MultipartFormDataRequestContent()
{
_multipartContent = new System.Net.Http.MultipartFormDataContent(CreateBoundary());
}

public string ContentType
{
get
{
return _multipartContent.Headers.ContentType.ToString();
}
}

internal HttpContent HttpContent => _multipartContent;

private static string CreateBoundary()
{
Span<char> chars = new char[70];
byte[] random = new byte[70];
_random.NextBytes(random);
int mask = 255 >> 2;
for (int i = 0; i < 70; i++)
{
chars[i] = _boundaryValues[random[i] & mask];
}
return chars.ToString();
}

public void Add(string content, string name, string filename = null, string contentType = null)
{
Argument.AssertNotNull(content, nameof(content));
Argument.AssertNotNullOrEmpty(name, nameof(name));

Add(new StringContent(content), name, filename, contentType);
}

public void Add(int content, string name, string filename = null, string contentType = null)
{
Argument.AssertNotNull(content, nameof(content));
Argument.AssertNotNullOrEmpty(name, nameof(name));

string value = content.ToString("G", CultureInfo.InvariantCulture);
Add(new StringContent(value), name, filename, contentType);
}

public void Add(long content, string name, string filename = null, string contentType = null)
{
Argument.AssertNotNull(content, nameof(content));
Argument.AssertNotNullOrEmpty(name, nameof(name));

string value = content.ToString("G", CultureInfo.InvariantCulture);
Add(new StringContent(value), name, filename, contentType);
}

public void Add(float content, string name, string filename = null, string contentType = null)
{
Argument.AssertNotNull(content, nameof(content));
Argument.AssertNotNullOrEmpty(name, nameof(name));

string value = content.ToString("G", CultureInfo.InvariantCulture);
Add(new StringContent(value), name, filename, contentType);
}

public void Add(double content, string name, string filename = null, string contentType = null)
{
Argument.AssertNotNull(content, nameof(content));
Argument.AssertNotNullOrEmpty(name, nameof(name));

string value = content.ToString("G", CultureInfo.InvariantCulture);
Add(new StringContent(value), name, filename, contentType);
}

public void Add(decimal content, string name, string filename = null, string contentType = null)
{
Argument.AssertNotNull(content, nameof(content));
Argument.AssertNotNullOrEmpty(name, nameof(name));

string value = content.ToString("G", CultureInfo.InvariantCulture);
Add(new StringContent(value), name, filename, contentType);
}

public void Add(bool content, string name, string filename = null, string contentType = null)
{
Argument.AssertNotNull(content, nameof(content));
Argument.AssertNotNullOrEmpty(name, nameof(name));

string value = content ? "true" : "false";
Add(new StringContent(value), name, filename, contentType);
}

public void Add(Stream content, string name, string filename = null, string contentType = null)
{
Argument.AssertNotNull(content, nameof(content));
Argument.AssertNotNullOrEmpty(name, nameof(name));

Add(new StreamContent(content), name, filename, contentType);
}

public void Add(byte[] content, string name, string filename = null, string contentType = null)
{
Argument.AssertNotNull(content, nameof(content));
Argument.AssertNotNullOrEmpty(name, nameof(name));

Add(new ByteArrayContent(content), name, filename, contentType);
}

public void Add(BinaryData content, string name, string filename = null, string contentType = null)
{
Argument.AssertNotNull(content, nameof(content));
Argument.AssertNotNullOrEmpty(name, nameof(name));

Add(new ByteArrayContent(content.ToArray()), name, filename, contentType);
}

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);
}

public static void AddFilenameHeader(HttpContent content, string name, string filename)
{
ContentDispositionHeaderValue header = new ContentDispositionHeaderValue("form-data") { 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;
}

public override bool TryComputeLength(out long length)
{
if (_multipartContent.Headers.ContentLength is long contentLength)
{
length = contentLength;
return true;
}
length = 0;
return false;
}

public override void WriteTo(Stream stream, CancellationToken cancellationToken = default)
{
#if NET6_0_OR_GREATER
_multipartContent.CopyTo(stream, default, cancellationToken);
#else
#pragma warning disable AZC0107
_multipartContent.CopyToAsync(stream).EnsureCompleted();
#pragma warning restore AZC0107
#endif
}

public override async Task WriteToAsync(Stream stream, CancellationToken cancellationToken = default)
{
#if NET6_0_OR_GREATER
await _multipartContent.CopyToAsync(stream, cancellationToken).ConfigureAwait(false);
#else
await _multipartContent.CopyToAsync(stream).ConfigureAwait(false);
#endif
}

public override void Dispose()
{
_multipartContent.Dispose();
}
}
}

0 comments on commit dac2fba

Please sign in to comment.