From 98df0fb9fe94b703325f09bf765904a11e8a7d4c Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 10 Feb 2021 14:31:31 +0800 Subject: ... --- .../Timeline/Formatters/ByteDataInputFormatter.cs | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 BackEnd/Timeline/Formatters/ByteDataInputFormatter.cs (limited to 'BackEnd/Timeline/Formatters/ByteDataInputFormatter.cs') diff --git a/BackEnd/Timeline/Formatters/ByteDataInputFormatter.cs b/BackEnd/Timeline/Formatters/ByteDataInputFormatter.cs new file mode 100644 index 00000000..2451ead6 --- /dev/null +++ b/BackEnd/Timeline/Formatters/ByteDataInputFormatter.cs @@ -0,0 +1,80 @@ +using Microsoft.AspNetCore.Mvc.Formatters; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using System; +using System.Threading.Tasks; +using Timeline.Models; + +namespace Timeline.Formatters +{ + /// + /// Formatter that reads body as byte data. + /// + public class ByteDataInputFormatter : InputFormatter + { + /// + /// + /// + public ByteDataInputFormatter() + { + SupportedMediaTypes.Add(MimeTypes.ImagePng); + SupportedMediaTypes.Add(MimeTypes.ImageJpeg); + SupportedMediaTypes.Add(MimeTypes.ImageGif); + SupportedMediaTypes.Add(MimeTypes.ImageWebp); + SupportedMediaTypes.Add(MimeTypes.TextPlain); + SupportedMediaTypes.Add(MimeTypes.TextMarkdown); + } + + /// + public override bool CanRead(InputFormatterContext context) + { + if (context == null) throw new ArgumentNullException(nameof(context)); + + if (context.ModelType == typeof(ByteData)) + return true; + + return false; + } + + /// + public override async Task ReadRequestBodyAsync(InputFormatterContext context) + { + var request = context.HttpContext.Request; + var contentLength = request.ContentLength; + + var logger = context.HttpContext.RequestServices.GetRequiredService>(); + + if (contentLength == null) + { + logger.LogInformation("Failed to read body as bytes. Content-Length is not set."); + return await InputFormatterResult.FailureAsync(); + } + + if (contentLength == 0) + { + logger.LogInformation("Failed to read body as bytes. Content-Length is 0."); + return await InputFormatterResult.FailureAsync(); + } + + var bodyStream = request.Body; + + var data = new byte[contentLength.Value]; + var bytesRead = await bodyStream.ReadAsync(data); + + if (bytesRead != contentLength) + { + logger.LogInformation("Failed to read body as bytes. Actual length of body is smaller than Content-Length."); + return await InputFormatterResult.FailureAsync(); + } + + var extraByte = new byte[1]; + if (await bodyStream.ReadAsync(extraByte) != 0) + { + logger.LogInformation("Failed to read body as bytes. Actual length of body is greater than Content-Length."); + return await InputFormatterResult.FailureAsync(); + } + + return await InputFormatterResult.SuccessAsync(new ByteData(data, request.ContentType)); + } + } +} -- cgit v1.2.3