Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add 'multipart/form-data' support for file uploads #1372

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
1 change: 1 addition & 0 deletions src/Ocelot/Multiplexer/MultiplexingMiddleware.cs
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ private static HttpContext Copy(HttpContext source)
target.Request.Body = source.Request.Body;
target.Request.ContentLength = source.Request.ContentLength;
target.Request.ContentType = source.Request.ContentType;
target.Request.Form = source.Request.Form;
target.Request.Host = source.Request.Host;
target.Request.Method = source.Request.Method;
target.Request.Path = source.Request.Path;
Expand Down
49 changes: 39 additions & 10 deletions src/Ocelot/Request/Mapper/RequestMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

using Ocelot.Configuration;

using Microsoft.AspNetCore.Http;
Expand Down Expand Up @@ -41,6 +41,10 @@ public async Task<Response<HttpRequestMessage>> Map(HttpRequest request, Downstr
}
}

private static bool IsMultipartContentType(string contentType)
=> !string.IsNullOrEmpty(contentType)
&& contentType.Contains("multipart/form-data", StringComparison.OrdinalIgnoreCase);

private static async Task<HttpContent> MapContent(HttpRequest request)
{
if (request.Body == null || (request.Body.CanSeek && request.Body.Length <= 0))
Expand All @@ -49,12 +53,39 @@ private static async Task<HttpContent> MapContent(HttpRequest request)
}

// Never change this to StreamContent again, I forgot it doesnt work in #464.
var content = new ByteArrayContent(await ToByteArray(request.Body));
HttpContent content;

if (IsMultipartContentType(request.ContentType))
{
content = new MultipartFormDataContent();
if (request.Form != null && request.Form.Files != null)
{
foreach (var f in request.Form.Files)
{
using var memStream = new MemoryStream();
await f.CopyToAsync(memStream);
var fileContent = new ByteArrayContent(memStream.ToArray());
((MultipartFormDataContent)content).Add(fileContent, f.Name, f.FileName);
}
}

if (!string.IsNullOrEmpty(request.ContentType))
if (request.Form != null)
{
foreach (var key in request.Form.Keys)
{
var strContent = new StringContent(request.Form[key]);
((MultipartFormDataContent)content).Add(strContent, key);
}
}
}
else
{
content.Headers
.TryAddWithoutValidation("Content-Type", new[] { request.ContentType });
content = new ByteArrayContent(await ToByteArray(request.Body));
if (!string.IsNullOrEmpty(request.ContentType))
{
content.Headers
.TryAddWithoutValidation("Content-Type", new[] { request.ContentType });
}
}

AddHeaderIfExistsOnRequest("Content-Language", content, request);
Expand Down Expand Up @@ -108,11 +139,9 @@ private static async Task<byte[]> ToByteArray(Stream stream)
{
await using (stream)
{
using (var memStream = new MemoryStream())
{
await stream.CopyToAsync(memStream);
return memStream.ToArray();
}
using var memStream = new MemoryStream();
await stream.CopyToAsync(memStream);
return memStream.ToArray();
}
}
}
Expand Down