diff --git a/.idea/.idea.HTTP2FileStreams/.idea/indexLayout.xml b/.idea/.idea.HTTP2FileStreams/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/.idea/.idea.HTTP2FileStreams/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/.idea.HTTP2FileStreams/.idea/vcs.xml b/.idea/.idea.HTTP2FileStreams/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/.idea.HTTP2FileStreams/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/DisableFormValueModelBindingAttribute.cs b/DisableFormValueModelBindingAttribute.cs new file mode 100644 index 0000000..65c2ccd --- /dev/null +++ b/DisableFormValueModelBindingAttribute.cs @@ -0,0 +1,20 @@ +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.AspNetCore.Mvc.ModelBinding; + +namespace HTTP2FileStreams; + +public class DisableFormValueModelBindingAttribute : Attribute, IResourceFilter +{ + public void OnResourceExecuting(ResourceExecutingContext context) + { + var formValueProviderFactory = context.ValueProviderFactories + .OfType() + .FirstOrDefault(); + if (formValueProviderFactory != null) + { + context.ValueProviderFactories.Remove(formValueProviderFactory); + } + } + + public void OnResourceExecuted(ResourceExecutedContext context) { } +} \ No newline at end of file diff --git a/HTTP2FileStreams.csproj b/HTTP2FileStreams.csproj index 5a25aeb..e6bf24d 100644 --- a/HTTP2FileStreams.csproj +++ b/HTTP2FileStreams.csproj @@ -6,4 +6,14 @@ enable + + + Always + + + + + + + diff --git a/Program.cs b/Program.cs index eef8c40..b2f90e9 100644 --- a/Program.cs +++ b/Program.cs @@ -1,3 +1,5 @@ +using Microsoft.AspNetCore.Server.Kestrel.Core; + namespace HTTP2FileStreams; public class Program @@ -5,9 +7,19 @@ public class Program public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); + builder.WebHost.ConfigureKestrel(options => + { + options.ConfigureEndpointDefaults(endpointOptions => + { + endpointOptions.Protocols = HttpProtocols.Http2; + }); + }); + builder.Services.AddControllers(); + var app = builder.Build(); - - app.MapGet("/", () => "Hello World!"); + app.MapControllers(); + app.UseDefaultFiles(); + app.UseStaticFiles(); app.Run(); } diff --git a/UploadController.cs b/UploadController.cs new file mode 100644 index 0000000..5e20f6f --- /dev/null +++ b/UploadController.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; + +namespace HTTP2FileStreams; + +[ApiController] +[Route("api/[controller]")] +public class UploadController : ControllerBase +{ + [HttpPost] + [DisableFormValueModelBinding] // Отключаем стандартный парсинг формы + public async Task Upload() + { + // Получаем имя файла из заголовка + var fileName = Request.Headers["X-File-Name"].ToString(); + if (string.IsNullOrEmpty(fileName)) + return BadRequest("File name header is missing"); + + fileName = Uri.UnescapeDataString(fileName); + + // Потоковая запись файла + if (!Directory.Exists("Uploads")) + Directory.CreateDirectory("Uploads"); + + var filePath = Path.Combine("Uploads", fileName); + await using var fileStream = System.IO.File.Create(filePath); + await Request.Body.CopyToAsync(fileStream); + + return Ok(new { + fileName, + size = fileStream.Length + }); + } +} \ No newline at end of file diff --git a/Uploads/Blockbench.exe b/Uploads/Blockbench.exe new file mode 100644 index 0000000..ad2a680 --- /dev/null +++ b/Uploads/Blockbench.exe @@ -0,0 +1 @@ +[object ReadableStream] \ No newline at end of file diff --git a/wwwroot/index.html b/wwwroot/index.html new file mode 100644 index 0000000..769d041 --- /dev/null +++ b/wwwroot/index.html @@ -0,0 +1,51 @@ + + + + HTTP2FileStreams test + + + + + \ No newline at end of file