/// <summary> /// Checks whether the media-type is supported /// </summary> /// <param name="compressionManager">HTTP compression manager</param> /// <param name="mediaType">Media-type</param> /// <returns>Result of check (true - supported; false - not supported)</returns> public static bool IsSupportedMediaType(this IHttpCompressionManager compressionManager, string mediaType) { if (string.IsNullOrWhiteSpace(mediaType)) { return(false); } Func <string, bool> supportedMediaTypePredicate = compressionManager.SupportedMediaTypePredicate; if (supportedMediaTypePredicate != null) { return(supportedMediaTypePredicate(mediaType)); } return(MediaTypeHelpers.IsTextBasedMediaType(mediaType)); }
public async Task <IActionResult> Upload(string filename) { if (string.IsNullOrWhiteSpace(filename)) { return(BadRequest("`filename` query parameter must be supplied")); } var name = Path.GetFileNameWithoutExtension(filename); var extension = Path.GetExtension(filename); var upload = new Upload { Id = await _slugGenerator.GenerateSlugAsync(Request.HttpContext.RequestAborted), Name = name, Extension = extension, OriginalFileNameWithExtension = Path.GetFileName(filename), MediaType = MediaTypeHelpers.GetMediaTypeFromExtension(extension), CodeLanguage = CodeLanguageHelpers.GetLanageFromExtension(extension), Length = Request.ContentLength.GetValueOrDefault(), UserId = _userManager.GetUserId(User), CreatedBy = _userManager.GetUserName(User) }; await _context.Uploads.AddAsync(upload, Request.HttpContext.RequestAborted); await _context.SaveChangesAsync(Request.HttpContext.RequestAborted); await _store.WriteAllBytesAsync(upload, Request.Body, Request.HttpContext.RequestAborted); upload.Status = UploadStatus.Complete; // File is fully uploaded, don't let the user cancel this request await _context.SaveChangesAsync(); return (new JsonResult( new { id = upload.Id, path = Url.Page("/Upload", values: new { id = upload.Id }), url = Url.PageLink("/Upload", values: new { id = upload.Id }), delete = Url.ActionLink("DeleteUpload", values: new { id = upload.Id }), raw = Url.ActionLink("Raw", values: new { id = upload.Id }), download = Url.ActionLink("Download", values: new { id = upload.Id }) })); }
private async Task <IActionResult> GetFile(string id, string contentDispositionType) { if (string.IsNullOrWhiteSpace(id)) { return(NotFound()); } var upload = await _context.Uploads .FirstOrDefaultAsync(x => x.Id == id && !x.PendingForDeletionAt.HasValue, Request.HttpContext.RequestAborted); if (upload == null) { return(NotFound()); } var range = Request.GetTypedHeaders().Range; var result = await _store.DownloadAsync(upload, range, Request.HttpContext.RequestAborted); if (result.ContentRange != null) { Response.StatusCode = (int)HttpStatusCode.PartialContent; Response.Headers.Add("Accept-Ranges", "bytes"); Response.Headers.Add("Content-Range", result.ContentRange); } Response.Headers.Add("Content-Disposition", $"{contentDispositionType};filename={upload.Name + upload.Extension}"); if (MediaTypeHelpers.ParseMediaType(upload.MediaType) == MediaType.Text) { return(File(result.Stream, "text/plain", true)); } else { return(File(result.Stream, upload.MediaType, true)); } }
private async Task InvokeInternal(HttpContext context) { var options = _options.CurrentValue; RequestBufferingStream?requestBufferingStream = null; Stream?originalBody = null; if ((HttpLoggingFields.Request & options.LoggingFields) != HttpLoggingFields.None) { var request = context.Request; var list = new List <KeyValuePair <string, object?> >( request.Headers.Count + DefaultRequestFieldsMinusHeaders); if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestProtocol)) { AddToList(list, nameof(request.Protocol), request.Protocol); } if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestMethod)) { AddToList(list, nameof(request.Method), request.Method); } if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestScheme)) { AddToList(list, nameof(request.Scheme), request.Scheme); } if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestPath)) { AddToList(list, nameof(request.PathBase), request.PathBase); AddToList(list, nameof(request.Path), request.Path); } if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestQuery)) { AddToList(list, nameof(request.QueryString), request.QueryString.Value); } if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestHeaders)) { FilterHeaders(list, request.Headers, options._internalRequestHeaders); } if (options.LoggingFields.HasFlag(HttpLoggingFields.RequestBody)) { if (MediaTypeHelpers.TryGetEncodingForMediaType(request.ContentType, options.MediaTypeOptions.MediaTypeStates, out var encoding)) { originalBody = request.Body; requestBufferingStream = new RequestBufferingStream( request.Body, options.RequestBodyLogLimit, _logger, encoding); request.Body = requestBufferingStream; } else { _logger.UnrecognizedMediaType(); } } var httpRequestLog = new HttpRequestLog(list); _logger.RequestLog(httpRequestLog); } ResponseBufferingStream? responseBufferingStream = null; IHttpResponseBodyFeature?originalBodyFeature = null; try { var response = context.Response; if (options.LoggingFields.HasFlag(HttpLoggingFields.ResponseBody)) { originalBodyFeature = context.Features.Get <IHttpResponseBodyFeature>() !; // TODO pool these. responseBufferingStream = new ResponseBufferingStream(originalBodyFeature, options.ResponseBodyLogLimit, _logger, context, options.MediaTypeOptions.MediaTypeStates, options); response.Body = responseBufferingStream; context.Features.Set <IHttpResponseBodyFeature>(responseBufferingStream); } await _next(context); if (requestBufferingStream?.HasLogged == false) { // If the middleware pipeline didn't read until 0 was returned from readasync, // make sure we log the request body. requestBufferingStream.LogRequestBody(); } if (responseBufferingStream == null || responseBufferingStream.FirstWrite == false) { // No body, write headers here. LogResponseHeaders(response, options, _logger); } if (responseBufferingStream != null) { var responseBody = responseBufferingStream.GetString(responseBufferingStream.Encoding); if (!string.IsNullOrEmpty(responseBody)) { _logger.ResponseBody(responseBody); } } } finally { responseBufferingStream?.Dispose(); if (originalBodyFeature != null) { context.Features.Set(originalBodyFeature); } requestBufferingStream?.Dispose(); if (originalBody != null) { context.Request.Body = originalBody; } } }
private Func <IServiceProvider, DefaultTusConfiguration> CreateTusConfiguration(StorageType storageType) => (serviceProvider) => { var logger = serviceProvider.GetService <ILoggerFactory>().CreateLogger <Startup>(); return(new DefaultTusConfiguration { Store = new HoneydewTusStore(serviceProvider), UrlPath = "/api/tusupload", MetadataParsingStrategy = MetadataParsingStrategy.AllowEmptyValues, Events = new Events { OnAuthorizeAsync = ctx => { if (!ctx.HttpContext.User.Identity.IsAuthenticated) { ctx.FailRequest(HttpStatusCode.Unauthorized); } return Task.CompletedTask; }, OnBeforeCreateAsync = ctx => { // Partial files are not complete so we do not need to validate // the metadata in our example. if (ctx.FileConcatenation is FileConcatPartial) { return Task.CompletedTask; } if (!ctx.Metadata.ContainsKey("name") || ctx.Metadata["name"].HasEmptyValue || string.IsNullOrWhiteSpace(ctx.Metadata["name"].GetString(Encoding.UTF8))) { ctx.FailRequest("name metadata must be specified."); } return Task.CompletedTask; }, OnCreateCompleteAsync = async ctx => { logger.LogInformation($"Created file {ctx.FileId} using {ctx.Store.GetType().FullName}"); var name = ctx.Metadata["name"].GetString(Encoding.UTF8); var mediaType = MediaTypeHelpers.GetMediaTypeFromMetadata(ctx.Metadata); var filename = Path.GetFileNameWithoutExtension(name); var extension = Path.GetExtension(name); var scope = serviceProvider.CreateScope(); var userManager = scope .ServiceProvider .GetService <UserManager <User> >(); await using var context = scope .ServiceProvider .GetService <ApplicationDbContext>(); await context.Uploads.AddAsync( new Upload { Id = ctx.FileId, Name = filename, Extension = extension, OriginalFileNameWithExtension = Path.GetFileName(name), MediaType = mediaType, CodeLanguage = CodeLanguageHelpers.GetLanageFromExtension(extension), Length = ctx.UploadLength, Metadata = ctx.HttpContext.Request.Headers[HeaderConstants.UploadMetadata], UserId = userManager.GetUserId(ctx.HttpContext.User), CreatedBy = userManager.GetUserName(ctx.HttpContext.User) }, ctx.CancellationToken); await context.SaveChangesAsync(ctx.CancellationToken); }, OnBeforeDeleteAsync = ctx => { // Can the file be deleted? If not call ctx.FailRequest(<message>); return Task.CompletedTask; }, OnDeleteCompleteAsync = ctx => { logger.LogInformation($"Deleted file {ctx.FileId} using {ctx.Store.GetType().FullName}"); return Task.CompletedTask; }, OnFileCompleteAsync = async ctx => { logger.LogInformation($"Upload of {ctx.FileId} completed using {ctx.Store.GetType().FullName}"); await using var context = serviceProvider .CreateScope() .ServiceProvider .GetService <ApplicationDbContext>(); var upload = await context.Uploads.FindAsync(ctx.FileId); upload.Status = UploadStatus.Complete; // Don't want the user to be able to cancel await context.SaveChangesAsync(); } },