示例#1
0
        public async Task PostImportAsync()
        {
            using (ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                if (HttpContext.Request.HasFormContentType == false)
                {
                    HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest; // Bad request
                    using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        context.Write(writer, new DynamicJsonValue
                        {
                            ["Type"]  = "Error",
                            ["Error"] = "This endpoint requires form content type"
                        });
                        return;
                    }
                }

                var operationId = GetLongQueryString("operationId", false) ?? Database.Operations.GetNextOperationId();
                var token       = CreateOperationToken();

                var result = new SmugglerResult();
                await Database.Operations.AddOperation(Database, "Import to: " + Database.Name,
                                                       Operations.OperationType.DatabaseImport,
                                                       onProgress =>
                {
                    return(Task.Run(async() =>
                    {
                        try
                        {
                            var boundary = MultipartRequestHelper.GetBoundary(
                                MediaTypeHeaderValue.Parse(HttpContext.Request.ContentType),
                                MultipartRequestHelper.MultipartBoundaryLengthLimit);
                            var reader = new MultipartReader(boundary, HttpContext.Request.Body);
                            DatabaseSmugglerOptionsServerSide options = null;

                            while (true)
                            {
                                var section = await reader.ReadNextSectionAsync().ConfigureAwait(false);
                                if (section == null)
                                {
                                    break;
                                }

                                if (ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition) == false)
                                {
                                    continue;
                                }

                                if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                                {
                                    var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                                    if (key != "importOptions")
                                    {
                                        continue;
                                    }

                                    BlittableJsonReaderObject blittableJson;
                                    if (section.Headers.ContainsKey("Content-Encoding") && section.Headers["Content-Encoding"] == "gzip")
                                    {
                                        using (var gzipStream = new GZipStream(section.Body, CompressionMode.Decompress))
                                        {
                                            blittableJson = await context.ReadForMemoryAsync(gzipStream, "importOptions");
                                        }
                                    }
                                    else
                                    {
                                        blittableJson = await context.ReadForMemoryAsync(section.Body, "importOptions");
                                    }

                                    options = JsonDeserializationServer.DatabaseSmugglerOptions(blittableJson);
                                    continue;
                                }

                                if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition) == false)
                                {
                                    continue;
                                }

                                var stream = new GZipStream(section.Body, CompressionMode.Decompress);
                                DoImportInternal(context, stream, options, result, onProgress, token);
                            }
                        }
                        catch (Exception e)
                        {
                            result.AddError($"Error occurred during import. Exception: {e.Message}");
                            onProgress.Invoke(result.Progress);
                            throw;
                        }

                        return (IOperationResult)result;
                    }));
                }, operationId, token).ConfigureAwait(false);

                WriteImportResult(context, result, ResponseBodyStream());
            }
示例#2
0
        public async Task <IFormCollection> ReadFormAsync(CancellationToken cancellationToken)
        {
            if (Form != null)
            {
                return(Form);
            }

            if (!HasFormContentType)
            {
                throw new InvalidOperationException("Incorrect Content-Type: " + _request.ContentType);
            }

            cancellationToken.ThrowIfCancellationRequested();

            _request.EnableRewind();

            IDictionary <string, StringValues> formFields = null;
            var files = new FormFileCollection();

            // Some of these code paths use StreamReader which does not support cancellation tokens.
            using (cancellationToken.Register(_request.HttpContext.Abort))
            {
                var contentType = ContentType;
                // Check the content-type
                if (HasApplicationFormContentType(contentType))
                {
                    var encoding = FilterEncoding(contentType.Encoding);
                    formFields = await FormReader.ReadFormAsync(_request.Body, encoding, cancellationToken);
                }
                else if (HasMultipartFormContentType(contentType))
                {
                    var formAccumulator = new KeyValueAccumulator();

                    var boundary        = GetBoundary(contentType);
                    var multipartReader = new MultipartReader(boundary, _request.Body);
                    var section         = await multipartReader.ReadNextSectionAsync(cancellationToken);

                    while (section != null)
                    {
                        var headers = new HeaderDictionary(section.Headers);
                        ContentDispositionHeaderValue contentDisposition;
                        ContentDispositionHeaderValue.TryParse(headers[HeaderNames.ContentDisposition], out contentDisposition);
                        if (HasFileContentDisposition(contentDisposition))
                        {
                            // Find the end
                            await section.Body.DrainAsync(cancellationToken);

                            var file = new FormFile(_request.Body, section.BaseStreamOffset.Value, section.Body.Length)
                            {
                                Headers = headers,
                            };
                            files.Add(file);
                        }
                        else if (HasFormDataContentDisposition(contentDisposition))
                        {
                            // Content-Disposition: form-data; name="key"
                            //
                            // value

                            var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                            MediaTypeHeaderValue mediaType;
                            MediaTypeHeaderValue.TryParse(headers[HeaderNames.ContentType], out mediaType);
                            var encoding = FilterEncoding(mediaType?.Encoding);
                            using (var reader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                            {
                                var value = await reader.ReadToEndAsync();

                                formAccumulator.Append(key, value);
                            }
                        }
                        else
                        {
                            System.Diagnostics.Debug.Assert(false, "Unrecognized content-disposition for this section: " + headers[HeaderNames.ContentDisposition]);
                        }

                        section = await multipartReader.ReadNextSectionAsync(cancellationToken);
                    }

                    formFields = formAccumulator.GetResults();
                }
            }

            // Rewind so later readers don't have to.
            _request.Body.Seek(0, SeekOrigin.Begin);

            Form = new FormCollection(formFields, files);
            return(Form);
        }
示例#3
0
        private ParserState ProcessRequest(HttpRequestMessageBuilder request, ParserState currentState, string content)
        {
            switch (currentState)
            {
            case ParserState.RequestLine:
                // From RFC2616: "In the interest of robustness, servers SHOULD ignore any empty line(s) received where a Request-Line is expected."
                if (content.Length == 0)
                {
                    return(currentState);
                }

                var requestLine = content.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                // Verbs are case-sensitive
                switch (requestLine.Length > 0 ? requestLine[0] : null)
                {
                case "OPTIONS":
                    request.Method = HttpMethod.Options;
                    break;

                case "GET":
                    request.Method = HttpMethod.Get;
                    break;

                case "HEAD":
                    request.Method = HttpMethod.Head;
                    break;

                case "POST":
                    request.Method = HttpMethod.Post;
                    break;

                case "PUT":
                    request.Method = HttpMethod.Put;
                    break;

                case "DELETE":
                    request.Method = HttpMethod.Delete;
                    break;

                case "TRACE":
                    request.Method = HttpMethod.Trace;
                    break;

                default: break;
                }

                request.RequestUri = ResolveTargetUri(requestLine.Length > 1 ? requestLine[1] : "/");

                var     protocolVersion = Regex.Match(requestLine.Length > 2 ? requestLine[2] : null, "HTTP/(?<version>.*)").Groups["version"].Value;
                Version version;
                if (Version.TryParse(protocolVersion, out version))
                {
                    request.Version = version;
                }

                return(ParserState.RequestHeaders);

            case ParserState.RequestHeaders:
                // empty line signals end of request header
                if (content.Length > CrLf.Length)
                {
                    // Header names are case-insensitive
                    var header      = content.Split(new[] { ':' }, 2, StringSplitOptions.RemoveEmptyEntries);
                    var headerName  = header.Length > 0 ? header[0].Trim() : null;
                    var headerValue = header.Length > 1 ? header[1].Trim() : null;
                    if (headerName != null && headerValue != null)
                    {
                        switch (headerName.ToUpperInvariant())
                        {
                        case "RANGE":
                            // fixes issue in HttpClient for WP where a Range header with no upper range
                            // results in an InvalidOperationException - "Nullable object must have a value"
                            if (headerValue.EndsWith("-"))
                            {
                                headerValue += long.MaxValue.ToString();
                            }

                            request.Headers.Add(headerName, headerValue);
                            break;

                        case "REFERER":
                            headerValue = ResolveTargetUri(headerValue).AbsoluteUri;
                            request.Headers.Add(headerName, headerValue);
                            break;

                        case "HOST":
                            break;

                        case "CONNECTION":
                            break;

                        case "ALLOW":
                        case "CONTENT-ENCODING":
                        case "CONTENT-LANGUAGE":
                            request.ContentHeaders[headerName] = headerValue;
                            break;

                        case "CONTENT-DISPOSITION":
                            ContentDispositionHeaderValue contentDisposition;
                            if (ContentDispositionHeaderValue.TryParse(headerValue, out contentDisposition))
                            {
                                request.ContentHeaders[headerName] = contentDisposition;
                            }

                            break;

                        case "CONTENT-LENGTH":
                            long contentLength;
                            if (long.TryParse(headerValue, out contentLength))
                            {
                                request.ContentHeaders[headerName] = contentLength;
                            }

                            break;

                        case "CONTENT-LOCATION":
                            var contentLocation = ResolveTargetUri(headerValue).AbsoluteUri;
                            request.ContentHeaders[headerName] = contentLocation;
                            break;

                        case "CONTENT-MD5":
                            // currently not supported
                            break;

                        case "CONTENT-RANGE":
                            ContentRangeHeaderValue contentRange;
                            if (ContentRangeHeaderValue.TryParse(headerValue, out contentRange))
                            {
                                request.ContentHeaders[headerName] = contentRange;
                            }

                            break;

                        case "CONTENT-TYPE":
                            MediaTypeHeaderValue contentType;
                            if (MediaTypeHeaderValue.TryParse(headerValue, out contentType))
                            {
                                request.ContentHeaders[headerName] = contentType;
                            }

                            break;

                        case "CONTENT-EXPIRES":
                        case "CONTENT-LASTMODIFIED":
                            DateTimeOffset expires;
                            if (DateTimeOffset.TryParse(headerValue, out expires))
                            {
                                request.ContentHeaders[headerName] = expires;
                            }

                            break;

                        case "USER-AGENT":
                            request.Headers.TryAddWithoutValidation("User-Agent", headerValue.Replace(")", "; WAT)"));
                            break;

                        case "COOKIE":
                            // filter out cookies for other domains
                            var filteredCookies = this.cookieManager.FilterCookiesForCurrentRequest(request.RequestUri, headerValue);
                            if (!string.IsNullOrWhiteSpace(filteredCookies))
                            {
                                request.Headers.Add(headerName, filteredCookies);
                            }

                            break;

                        default:
                            request.Headers.Add(headerName, headerValue);
                            break;
                        }
                    }
                }
                else
                {
                    currentState = ParserState.RequestBody;
                }

                break;

            case ParserState.RequestBody:
                request.Content = new StringContent(content);
                currentState    = ParserState.Complete;
                break;
            }

            return(currentState);
        }
示例#4
0
        public async Task PostImportAsync()
        {
            DocumentsOperationContext context;

            using (ContextPool.AllocateOperationContext(out context))
            {
                if (HttpContext.Request.HasFormContentType == false)
                {
                    HttpContext.Response.StatusCode = 400; // Bad request
                    using (var writer = new BlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        context.Write(writer, new DynamicJsonValue
                        {
                            ["Type"]  = "Error",
                            ["Error"] = "This endpoint requires form content type"
                        });
                        return;
                    }
                }

                var operationId = GetLongQueryString("operationId", required: true) ?? -1;
                var token       = CreateOperationToken();
                var sp          = Stopwatch.StartNew();

                var result = new ImportResult();
                await Database.Operations.AddOperation("Import to: " + Database.Name,
                                                       DatabaseOperations.PendingOperationType.DatabaseImport,
                                                       onProgress =>
                {
                    return(Task.Run(async() =>
                    {
                        try
                        {
                            var boundary = MultipartRequestHelper.GetBoundary(
                                MediaTypeHeaderValue.Parse(HttpContext.Request.ContentType),
                                MultipartRequestHelper.MultipartBoundaryLengthLimit);
                            var reader = new MultipartReader(boundary, HttpContext.Request.Body);
                            DatabaseSmugglerOptions smugglerOptions = null;

                            while (true)
                            {
                                var section = await reader.ReadNextSectionAsync().ConfigureAwait(false);
                                if (section == null)
                                {
                                    break;
                                }

                                ContentDispositionHeaderValue contentDisposition;
                                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition,
                                                                                                         out contentDisposition);

                                if (hasContentDispositionHeader == false)
                                {
                                    continue;
                                }

                                if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                                {
                                    var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                                    if (key != "importOptions")
                                    {
                                        continue;
                                    }

                                    var blittableJson = await context.ReadForMemoryAsync(section.Body, "importOptions");
                                    smugglerOptions = JsonDeserializationServer.DatabaseSmugglerOptions(blittableJson);
                                    continue;
                                }

                                if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition) == false)
                                {
                                    continue;
                                }

                                var stream = new GZipStream(section.Body, CompressionMode.Decompress);
                                var fileImport =
                                    await DoImportInternal(context, stream, smugglerOptions, onProgress).ConfigureAwait(false);
                                result.DocumentsCount += fileImport.DocumentsCount;
                                result.Warnings.AddRange(fileImport.Warnings);
                                result.IdentitiesCount += fileImport.IdentitiesCount;
                                result.Message = fileImport.Message;
                                result.RevisionDocumentsCount += fileImport.RevisionDocumentsCount;
                                result.IndexesCount += fileImport.IndexesCount;
                                result.TransformersCount += fileImport.TransformersCount;
                            }
                        }
                        catch (Exception e)
                        {
                            result.Message = $"Error occured during export. Exception: {e.Message}";
                            result.Exception = e.ToString();
                        }

                        return (IOperationResult)result;
                    }));
                }, operationId, token).ConfigureAwait(false);

                WriteImportResult(context, sp, result, ResponseBodyStream());
            }
        }
        public async Task <IActionResult> Upload()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
            }

            // Used to accumulate all the form url encoded key value pairs in the
            // request.
            var    formAccumulator = new KeyValueAccumulator();
            string targetFilePath  = null;

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        targetFilePath = Path.GetTempFileName();
                        using (var targetStream = System.IO.File.Create(targetFilePath))
                        {
                            await section.Body.CopyToAsync(targetStream);

                            _logger.LogInformation("Copied the uploaded file '{TargetFilePath}'", targetFilePath);
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"
                        //
                        // value

                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key, value);

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to a model
            var user = new User();
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);

            var bindingSuccessful = await TryUpdateModelAsync(user, prefix : "",
                                                              valueProvider : formValueProvider);

            if (!bindingSuccessful)
            {
                if (!ModelState.IsValid)
                {
                    return(BadRequest(ModelState));
                }
            }

            var uploadedData = new UploadedData()
            {
                Name     = user.Name,
                Age      = user.Age,
                Zipcode  = user.Zipcode,
                FilePath = targetFilePath
            };

            return(Json(uploadedData));
        }
        private async Task <MediaModel> TryLoadMediaModelAsync()
        {
            var model = new MediaModel();

            try
            {
                var formAccumulator = new KeyValueAccumulator();
                var boundary        = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), DefaultFormOptions.MultipartBoundaryLengthLimit);
                var reader          = new MultipartReader(boundary.Value, HttpContext.Request.Body);

                var section = await reader.ReadNextSectionAsync();

                while (section != null)
                {
                    var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition);

                    if (hasContentDispositionHeader)
                    {
                        if (contentDisposition == null || !contentDisposition.DispositionType.Equals("form-data"))
                        {
                            continue;
                        }

                        if (contentDisposition.FileName.HasValue || contentDisposition.FileNameStar.HasValue)
                        {
                            if (!SupportedMimeTypes.Contains(section.ContentType))
                            {
                                throw new NotSupportedException($"{section.ContentType}");
                            }

                            var targetFilePath = Path.GetTempFileName();
                            using (var targetStream = System.IO.File.Create(targetFilePath))
                            {
                                await section.Body.CopyToAsync(targetStream);

                                _logger.LogInformation($"Copied the uploaded file '{targetFilePath}'");
                            }
                            model.FilePath = targetFilePath;
                            model.FileName = contentDisposition.FileName.Value;
                        }
                        else
                        {
                            var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                            var encoding = GetEncoding(section);
                            using (var streamReader = new StreamReader(section.Body, encoding, true, 1024, true))
                            {
                                var value = await streamReader.ReadToEndAsync();

                                if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                                {
                                    value = string.Empty;
                                }
                                formAccumulator.Append(key.Value, value.ToLower());

                                if (formAccumulator.ValueCount > DefaultFormOptions.ValueCountLimit)
                                {
                                    throw new InvalidDataException($"Form key count limit {DefaultFormOptions.ValueCountLimit} exceeded.");
                                }
                            }
                        }
                    }
                    section = await reader.ReadNextSectionAsync();
                }
                var formValueProvider = new FormValueProvider(BindingSource.Form, new FormCollection(formAccumulator.GetResults()), CultureInfo.CurrentCulture);
                var bindingSuccessful = await TryUpdateModelAsync(model, string.Empty, formValueProvider);

                if (bindingSuccessful)
                {
                    return(model);
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e, e.Message);
                if (!string.IsNullOrEmpty(model.FileName) && System.IO.File.Exists(model.FileName))
                {
                    System.IO.File.Delete(model.FileName);
                }

                ModelState.AddModelError(string.Empty, e.Message);
            }
            return(null);
        }
        public async Task <ActionResult> Post(bool thumbinal = false, bool forContent = false)
        {
            logger.LogDebug("Start FileController Post");
            // Check if the request contains multipart/form-data.
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                logger.LogError($"The request couldn't be processed (Error 1).");
                return(BadRequest($"The request couldn't be processed (Error 1)."));
            }

            try
            {
                var boundary = MultipartRequestHelper.GetBoundary(
                    MediaTypeHeaderValue.Parse(Request.ContentType),
                    _defaultFormOptions.MultipartBoundaryLengthLimit);
                var reader = new MultipartReader(boundary, HttpContext.Request.Body);

                List <ObjectFileField> files = new List <ObjectFileField>();
                var section = await reader.ReadNextSectionAsync();

                while (section != null)
                {
                    var hasContentDispositionHeader =
                        ContentDispositionHeaderValue.TryParse(
                            section.ContentDisposition, out var contentDisposition);

                    if (hasContentDispositionHeader)
                    {
                        if (MultipartRequestHelper
                            .HasFileContentDisposition(contentDisposition))
                        {
                            // Don't trust the file name sent by the client. To display
                            // the file name, HTML-encode the value.
                            var trustedFileNameForDisplay = WebUtility.HtmlEncode(
                                contentDisposition.FileName.Value);

                            logger.LogInformation("the raw file name is : " + trustedFileNameForDisplay);

                            var             extension     = Path.GetExtension(contentDisposition.FileName.Value);
                            long            fileSizeLimit = long.Parse(mConfiguration["SiteSettings:FileUpload:FileSizeLimit"]);
                            FileStorageInfo info          =
                                await storageService.SaveFileAsync(section.Body, extension, thumbinal, trustedFileNameForDisplay);

                            logger.LogDebug("file save path : " + info.FileUri);
                            //FileHelper.ProcessStreamedFile(section, contentDisposition,
                            //     _permittedExtensions, fileSizeLimit);

                            files.Add(new ObjectFileField()
                            {
                                FileName = trustedFileNameForDisplay,
                                //FileFullPath = info.FileUri,

                                FileUrl       = string.Format("/api/Files/DownloadFile/{0}/{1}", info.FileUniqueName, WebUtility.UrlEncode(trustedFileNameForDisplay)),
                                FileExtension = extension,
                                Updated       = info.LastUpdated,
                                Created       = info.Creation,
                                FileCRC       = info.CRC,
                                FileSize      = (int)(info.Size / 1024),
                            });


                            //only care about single document.
                            if (forContent)
                            {
                                break;
                            }
                        }

                        // Drain any remaining section body that hasn't been consumed and
                        // read the headers for the next section.
                        section = await reader.ReadNextSectionAsync();
                    }
                }

                //return the action result.
                ActionResult result = forContent ? this.Ok(new UploadFile()
                {
                    uploaded = 1, fileName = files[0].FileName, url = files[0].FileUrl
                })
                            : this.Ok(new { status = "success", files = files });

                logger.LogDebug("End FileController Post");
                return(result);
            }
            catch (Exception ex)
            {
                logger.LogError(ex.Message);
                return(BadRequest(ex.GetBaseException().Message));
            }
        }
示例#8
0
        public async Task <MultiPartRequestDto> HandleMultiPartRequest(HttpRequest request)
        {
            if (!IsMultipartContentType(request.ContentType))
            {
                throw new Exception($"Expected a multipart request, but got {request.ContentType}");
            }

            var formAccumulator = new KeyValueAccumulator();

            var boundary = GetBoundary(
                MediaTypeHeaderValue.Parse(request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, request.Body);

            var section = await reader.ReadNextSectionAsync();

            var media = new List <AddFileDto>();

            while (section != null)
            {
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (HasFileContentDisposition(contentDisposition))
                    {
                        var processedMedia = await _fileService.ProcessStreamedFileAsync(section, contentDisposition);

                        var mediaDto = new AddFileDto
                        {
                            File          = processedMedia,
                            FileExtension = Path.GetExtension(contentDisposition.FileName.Value),
                        };
                        media.Add(mediaDto);
                    }
                    else if (HasFormDataContentDisposition(contentDisposition))
                    {
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);

                        using (var streamReader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                        {
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined",
                                              StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }

                            formAccumulator.Append(key, value);

                            if (formAccumulator.ValueCount >
                                int.MaxValue)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                section = await reader.ReadNextSectionAsync();
            }

            //request.Body.Position = 0;

            var formAccumulatorResults = formAccumulator.GetResults();
            var formValueProvider      = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulatorResults),
                CultureInfo.CurrentCulture);

            return(new MultiPartRequestDto
            {
                FormValueProvider = formValueProvider,
                File = media,
            });
        }
        public async Task <IActionResult> Upload()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
            }

            // Used to accumulate all the form url encoded key value pairs in the request
            var formAccumulator = new KeyValueAccumulator();

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                DefaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            using (_logger.BeginScope(new
            {
                Boundary = boundary,
                Request.ContentType
            }))
            {
                _logger.LogTrace("Reading next section");
                var section = await reader.ReadNextSectionAsync();

                while (section != null)
                {
                    var hasContentDispositionHeader =
                        ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);

                    if (hasContentDispositionHeader)
                    {
                        _logger.LogTrace("Content Disposition Header: {0}", section.ContentDisposition);

                        if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                        {
                            var fileName = contentDisposition.FileName.Value;

                            if (!SubmissionDataFormFileNamesLazy.Value.Contains(contentDisposition.Name.Value))
                            {
                                _logger.LogInformation($"Unknown file '{contentDisposition.Name.Value}' with fileName: '{fileName}' is being ignored.");
                                // Drains any remaining section body that has not been consumed and
                                // reads the headers for the next section.
                                section = await reader.ReadNextSectionAsync();

                                continue;
                            }

                            formAccumulator.Append(contentDisposition.Name.Value, fileName);

                            var path = await _tempFileService.CreateFromStreamAsync(fileName, section.Body);

                            _logger.LogInformation($"Copied the uploaded file '{fileName}' to path: '{path}'");
                        }
                        else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                        {
                            // Content-Disposition: form-data; name="key"
                            //
                            // value

                            // Do not limit the key name length here because the
                            // multipart headers length limit is already in effect.
                            var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);

                            _logger.LogDebug("Retrieving value for {0}", key);

                            var encoding = GetEncoding(section);
                            using (var streamReader = new StreamReader(
                                       section.Body,
                                       encoding,
                                       detectEncodingFromByteOrderMarks: true,
                                       bufferSize: 1024,
                                       leaveOpen: true))
                            {
                                // The value length limit is enforced by MultipartBodyLengthLimit
                                var value = await streamReader.ReadToEndAsync();

                                if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                                {
                                    value = String.Empty;
                                }

                                formAccumulator.Append(key.Value, value);

                                if (formAccumulator.ValueCount > DefaultFormOptions.ValueCountLimit)
                                {
                                    throw new InvalidDataException(
                                              $"Form key count limit {DefaultFormOptions.ValueCountLimit} exceeded.");
                                }
                            }
                        }
                    }

                    // Drains any remaining section body that has not been consumed and
                    // reads the headers for the next section.
                    section = await reader.ReadNextSectionAsync();
                }
            }

            // Bind form data to a model
            var submissionData = new SubmissionData();

            var bindingSuccessful = await BindDataAsync(submissionData, formAccumulator.GetResults());

            if (!bindingSuccessful)
            {
                if (!ModelState.IsValid)
                {
                    return(BadRequest(ModelState));
                }
            }

            var requiredFormFileProperties = typeof(SubmissionData).GetProperties()
                                             .Where(p => p.GetCustomAttributes(typeof(RequiredAttribute), true).Any())
                                             .Where(p => p.GetCustomAttributes(typeof(FormFileAttribute), true).Any());

            foreach (var requiredFormFileProperty in requiredFormFileProperties)
            {
                var fileName = requiredFormFileProperty.GetValue(submissionData);
                if (!_tempFileService.Files.Contains(fileName))
                {
                    ModelState.AddModelError(requiredFormFileProperty.Name, $"File '{requiredFormFileProperty.Name}' with name: '{fileName}' not found in request.");
                    return(BadRequest(ModelState));
                }
            }

            var repositoryOwner = User.Claims.FirstOrDefault(c => c.Type == "urn:msbloc:repositoryOwner")?.Value;
            var repositoryName  = User.Claims.FirstOrDefault(c => c.Type == "urn:msbloc:repositoryName")?.Value;

            var checkRun = await _logAnalyzerService.SubmitAsync(
                repositoryOwner,
                repositoryName,
                submissionData.CommitSha,
                submissionData.CloneRoot,
                _tempFileService.GetFilePath(submissionData.BinaryLogFile));

            return(Json(checkRun));
        }
示例#10
0
        /// <summary>
        /// Creates a data element by reading the first multipart element or body of the request.
        /// </summary>
        private async Task <(Stream, DataElement)> ReadRequestAndCreateDataElementAsync(HttpRequest request, string elementType, List <Guid> refs, Instance instance)
        {
            DateTime creationTime = DateTime.UtcNow;
            Stream   theStream    = null;

            string contentType     = null;
            string contentFileName = null;
            long   fileSize        = 0;

            if (MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                // Only read the first section of the mulitpart message.
                MediaTypeHeaderValue mediaType = MediaTypeHeaderValue.Parse(request.ContentType);
                string boundary = MultipartRequestHelper.GetBoundary(mediaType, _defaultFormOptions.MultipartBoundaryLengthLimit);

                MultipartSection section = null;

                MultipartReader reader = new MultipartReader(boundary, request.Body);
                section = await reader.ReadNextSectionAsync();

                theStream   = section.Body;
                contentType = section.ContentType;

                bool hasContentDisposition = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition);

                if (hasContentDisposition)
                {
                    contentFileName = HttpUtility.UrlDecode(contentDisposition.FileName.ToString());
                    fileSize        = contentDisposition.Size ?? 0;
                }
            }
            else
            {
                theStream = request.Body;
                if (request.Headers.TryGetValue("Content-Disposition", out StringValues headerValues))
                {
                    string        contentDisposition = headerValues.ToString();
                    List <string> contenDispValues   = contentDisposition.Split(';').ToList();

                    string fileNameValue = contenDispValues.FirstOrDefault(x => x.Contains("filename", StringComparison.CurrentCultureIgnoreCase));

                    if (!string.IsNullOrEmpty(fileNameValue))
                    {
                        string[] valueParts = fileNameValue.Split('=');

                        if (valueParts.Count() == 2)
                        {
                            contentFileName = HttpUtility.UrlDecode(valueParts[1]);
                        }
                    }
                }

                contentType = request.ContentType;
            }

            string user = null;

            DataElement newData = DataElementHelper.CreateDataElement(elementType, refs, instance, creationTime, contentType, contentFileName, fileSize, user);

            return(theStream, newData);
        }
        public async Task <IActionResult> Post()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
            }

            // Used to accumulate all the form url encoded key value pairs in the
            // request.
            var    formAccumulator = new KeyValueAccumulator();
            string targetFilePath  = null;

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        targetFilePath = Path.GetTempFileName();
                        using (var targetStream = System.IO.File.Create(targetFilePath))
                        {
                            await section.Body.CopyToAsync(targetStream);

                            Console.WriteLine($"Copied the uploaded file '{targetFilePath}'");
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"
                        //
                        // value

                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key.ToString(), value);

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }
            IDictionary <string, StringValues> parameters = formAccumulator.GetResults();

            if (parameters.ContainsKey(PARAM_ID_CONCEPT_LIE))
            {
                Debugger.Log((int)LogLevel.Information, "Info", parameters[PARAM_ID_CONCEPT_LIE].ToString());
            }
            else
            {
                Debugger.Log((int)LogLevel.Error, "Info", $"La requête ne contenait pas le paramètre {PARAM_ID_CONCEPT_LIE}");
            }
            return(Ok(new
            {
                FilePath = targetFilePath
            }));
        }
示例#12
0
        public async Task <ActionResult <BlobInfo[]> > UploadAssetAsync([FromQuery] string folderUrl, [FromQuery] string url = null, [FromQuery] string name = null)
        {
            // https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-3.1
            if (url == null && !MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
            }

            var retVal = new List <BlobInfo>();

            if (url != null)
            {
                var fileName = name ?? HttpUtility.UrlDecode(Path.GetFileName(url));
                var fileUrl  = folderUrl + "/" + fileName;
                using (var client = new WebClient())
                    using (var blobStream = _blobProvider.OpenWrite(fileUrl))
                        using (var remoteStream = client.OpenRead(url))
                        {
                            remoteStream.CopyTo(blobStream);
                            var blobInfo = AbstractTypeFactory <BlobInfo> .TryCreateInstance();

                            blobInfo.Name        = fileName;
                            blobInfo.RelativeUrl = fileUrl;
                            blobInfo.Url         = _urlResolver.GetAbsoluteUrl(fileUrl);
                            retVal.Add(blobInfo);
                        }
            }
            else
            {
                var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);
                var reader   = new MultipartReader(boundary, HttpContext.Request.Body);

                var section = await reader.ReadNextSectionAsync();

                if (section != null)
                {
                    var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);

                    if (hasContentDispositionHeader)
                    {
                        if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                        {
                            var fileName = contentDisposition.FileName.Value;

                            var targetFilePath = folderUrl + "/" + fileName;

                            using (var targetStream = _blobProvider.OpenWrite(targetFilePath))
                            {
                                await section.Body.CopyToAsync(targetStream);
                            }

                            var blobInfo = AbstractTypeFactory <BlobInfo> .TryCreateInstance();

                            blobInfo.Name        = fileName;
                            blobInfo.RelativeUrl = targetFilePath;
                            blobInfo.Url         = _urlResolver.GetAbsoluteUrl(targetFilePath);
                            blobInfo.ContentType = MimeTypeResolver.ResolveContentType(fileName);
                            retVal.Add(blobInfo);
                        }
                    }
                }
            }

            return(Ok(retVal.ToArray()));
        }
示例#13
0
        public async Task <IActionResult> UploadDatabase()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                ModelState.AddModelError("File",
                                         $"The request couldn't be processed (Error 1).");
                // Log error

                return(BadRequest(ModelState));
            }

            // Accumulate the form data key-value pairs in the request (formAccumulator).
            var formAccumulator               = new KeyValueAccumulator();
            var trustedFileNameForDisplay     = string.Empty;
            var untrustedFileNameForStorage   = string.Empty;
            var trustedFilePathStorage        = string.Empty;
            var trustedFileNameForFileStorage = string.Empty;
            var streamedFileContent           = new byte[0];
            var streamedFilePhysicalContent   = new byte[0];

            // List Byte for file storage
            List <byte[]> filesByteStorage         = new List <byte[]>();
            List <string> filesNameStorage         = new List <string>();
            var           fileStoredData           = new Dictionary <string, byte[]>();
            List <string> storedPaths              = new List <string>();
            List <string> storedPathDictionaryKeys = new List <string>();

            // List to Submit
            List <ClamSectionTVShowSubCategorySeasonItem> episodeList = new List <ClamSectionTVShowSubCategorySeasonItem>();

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader =
                    ContentDispositionHeaderValue.TryParse(
                        section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper
                        .HasFileContentDisposition(contentDisposition))
                    {
                        untrustedFileNameForStorage = contentDisposition.FileName.Value;
                        // Don't trust the file name sent by the client. To display
                        // the file name, HTML-encode the value.
                        trustedFileNameForDisplay = WebUtility.HtmlEncode(
                            contentDisposition.FileName.Value);

                        //streamedFileContent =
                        //    await FileHelpers.ProcessStreamedFile(section, contentDisposition,
                        //        ModelState, _permittedExtentions, _fileSizeLimit);

                        streamedFilePhysicalContent = await FileHelpers.ProcessStreamedFile(
                            section, contentDisposition, ModelState,
                            _permittedExtentions, _fileSizeLimit);

                        filesNameStorage.Add(trustedFileNameForDisplay);
                        filesByteStorage.Add(streamedFilePhysicalContent);
                        fileStoredData.Add(trustedFileNameForDisplay, streamedFilePhysicalContent);

                        if (!ModelState.IsValid)
                        {
                            return(BadRequest(ModelState));
                        }
                    }
                    else if (MultipartRequestHelper
                             .HasFormDataContentDisposition(contentDisposition))
                    {
                        // Don't limit the key name length because the
                        // multipart headers length limit is already in effect.
                        var key = HeaderUtilities
                                  .RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);

                        if (encoding == null)
                        {
                            ModelState.AddModelError("File",
                                                     $"The request couldn't be processed (Error 2).");
                            // Log error

                            return(BadRequest(ModelState));
                        }

                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by
                            // MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined",
                                              StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }

                            formAccumulator.Append(key, value);

                            if (formAccumulator.ValueCount >
                                _defaultFormOptions.ValueCountLimit)
                            {
                                // Form key count limit of
                                // _defaultFormOptions.ValueCountLimit
                                // is exceeded.
                                ModelState.AddModelError("File",
                                                         $"The request couldn't be processed (Error 3).");
                                // Log error

                                return(BadRequest(ModelState));
                            }
                        }
                    }
                }

                // Drain any remaining section body that hasn't been consumed and
                // read the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to the model
            var formData          = new StreamFormData();
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);
            var bindingSuccessful = await TryUpdateModelAsync(formData, prefix : "",
                                                              valueProvider : formValueProvider);

            //trustedFilePathStorage = String.Format("{0}\\{1}\\{2}\\{3}\\{4}",
            //    //_targetFilePath,
            //    _targetFolderPath,
            //    formData.CategoryId,
            //    formData.TVShowId,
            //    formData.SeasonId,
            //    Path.GetRandomFileName());

            if (!bindingSuccessful)
            {
                ModelState.AddModelError("File",
                                         "The request couldn't be processed (Error 5).");
                // Log error

                return(BadRequest(ModelState));
            }

            // **WARNING!**
            // In the following example, the file is saved without
            // scanning the file's contents. In most production
            // scenarios, an anti-virus/anti-malware scanner API
            // is used on the file before making the file available
            // for download or for use by other systems.
            // For more information, see the topic that accompanies
            // this sample app.

            //Directory.CreateDirectory(trustedFilePathStorage);

            //using (var targetStream = System.IO.File.Create(
            //                Path.Combine(trustedFilePathStorage, trustedFileNameForDisplay)))
            //{
            //    await targetStream.WriteAsync(streamedFilePhysicalContent);

            //    _logger.LogInformation(
            //        "Uploaded file '{TrustedFileNameForDisplay}' saved to " +
            //        "'{TargetFilePath}' as {TrustedFileNameForFileStorage}",
            //        trustedFileNameForDisplay, trustedFilePathStorage,
            //        trustedFileNameForDisplay);
            //}
            foreach (var item in fileStoredData)
            {
                trustedFilePathStorage = String.Format("{0}\\{1}\\{2}\\{3}\\{4}",
                                                       //_targetFilePath,
                                                       _targetFolderPath,
                                                       formData.CategoryId,
                                                       formData.TVShowId,
                                                       formData.SeasonId,
                                                       Path.GetRandomFileName());
                Directory.CreateDirectory(trustedFilePathStorage);

                using (var targetStream = System.IO.File.Create(
                           Path.Combine(trustedFilePathStorage, item.Key)))
                {
                    await targetStream.WriteAsync(item.Value);

                    _logger.LogInformation(
                        "Uploaded file '{TrustedFileNameForDisplay}' saved to " +
                        "'{TargetFilePath}' as {TrustedFileNameForFileStorage}",
                        item.Key, trustedFilePathStorage,
                        item.Key);
                }
                //storedPaths.Add(Path.Combine(trustedFilePathStorage, item.Key));
                //storedPathDictionaryKeys.Add(item.Key);
                episodeList.Add(new ClamSectionTVShowSubCategorySeasonItem()
                {
                    ItemPath    = Path.Combine(trustedFilePathStorage, item.Key),
                    ItemTitle   = item.Key,
                    Size        = item.Value.Length,
                    DateCreated = DateTime.Now,
                    CategoryId  = formData.CategoryId,
                    TVShowId    = formData.TVShowId,
                    SeasonId    = formData.SeasonId
                });
            }

            //var file = new ClamSectionTVShowSubCategorySeasonItem()
            //{
            //    ItemPath = Path.Combine(trustedFilePathStorage, trustedFileNameForDisplay),
            //    ItemTitle = untrustedFileNameForStorage,
            //    Size = streamedFilePhysicalContent.Length,
            //    DateCreated = DateTime.Now,
            //    CategoryId = formData.CategoryId,
            //    TVShowId = formData.TVShowId,
            //    SeasonId = formData.SeasonId
            //};
            //_context.Add(file);

            await _context.AddRangeAsync(episodeList);

            await _context.SaveChangesAsync();

            var url = String.Format("{0}/{1}/season/{2}/episodes/{3}",
                                    formData.UrlCategory,
                                    formData.UrlSection,
                                    formData.UrlSubSection,
                                    formData.CategoryId
                                    );

            return(RedirectToAction("Episode", "TVShow", new { id = formData.CategoryId, show = formData.TVShowId, season = formData.SeasonId,
                                                               category = formData.UrlCategory, section = formData.UrlSection, subsection = formData.UrlSubSection }));
        }
示例#14
0
        public async Task <ParseBodyAndSavePacketsResult> ParseBodyAndSavePackets(MessageHeaders messageHeaders, HttpRequest request)
        {
            var cancellationToken = request.HttpContext.RequestAborted;

            cancellationToken.ThrowIfCancellationRequested();

            var    format   = messageHeaders.Format ?? TransportConstants.RequestFormDataFormat;
            string boundary = null;

            if (format == TransportConstants.RequestFormDataFormat)
            {
                int fileSectionBufferSize = 81920;

                // если данные formdata упорядочены в потоке запроса (бинарные данные должны идти после большинства метаданных о пакете)
                if (messageHeaders.Hints?.Contains(MessageHints.OrderedFormData) == true)
                {
                    var indexToPacketDataItem    = new Dictionary <int, PacketFormDataItem>();
                    var indexToPacketBytes       = new Dictionary <int, byte[]>();
                    var indexToConfigurationItem = new Dictionary <int, ConfigurationRequestDataItem>();

                    if (MediaTypeHeaderValue.TryParse(request.ContentType, out var contentType))
                    {
                        boundary = HeaderUtilities.GetBoundary(contentType, 70);
                    }

                    var multipartReader = new MultipartReader(boundary, request.Body)
                    {
                        //ValueCountLimit = _options.ValueCountLimit,
                        //KeyLengthLimit = _options.KeyLengthLimit,
                        //ValueLengthLimit = _options.ValueLengthLimit,

                        HeadersCountLimit  = int.MaxValue,
                        HeadersLengthLimit = int.MaxValue,
                        BodyLengthLimit    = long.MaxValue,
                    };

                    //PacketFormDataItem current = null;
                    //byte[] currentBytes = null;
                    var agentId = messageHeaders.GetAgentIdData();
                    var section = await multipartReader.ReadNextSectionAsync(cancellationToken);

                    while (section != null)
                    {
                        // Parse the content disposition here and pass it further to avoid reparsings
                        if (!ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition))
                        {
                            throw new InvalidDataException("Form section has invalid Content-Disposition value: " + section.ContentDisposition);
                        }

                        if (contentDisposition.IsFileDisposition())
                        {
                            var fileSection = new FileMultipartSection(section, contentDisposition);

                            var name     = fileSection.Name;
                            var fileName = fileSection.FileName;
                            var packetId = fileSection.FileName;
                            var result   = GetFormPathDataFromEntry(name);
                            if (result != null && result.Parts.Count == 3 && result.Parts[0] == TransportConstants.FormDataPacketsProp)
                            {
                                if (int.TryParse(result.Parts[1], out var index))
                                {
                                    var item        = indexToPacketDataItem[index];
                                    var providerKey = item.ProviderKey;

                                    var packetItem = indexToPacketDataItem[index];
                                    if (packetItem.PacketId != packetId)
                                    {
                                        throw new InvalidDataException($"Incorrect format for form-data message. Section {name} has invalid FileName.");
                                    }

                                    var bytes = await ReadToEnd(fileSection.FileStream, fileSectionBufferSize, cancellationToken);

                                    indexToPacketBytes.Add(index, bytes);
                                }
                                else
                                {
                                    throw new InvalidDataException($"Incorrect format for form-data message. Section {name} does not have index suffix.");
                                }
                            }
                            else
                            {
                                throw new InvalidDataException($"Incorrect format for form-data message. Section {name} incorrect.");
                            }
                        }
                        else if (contentDisposition.IsFormDisposition())
                        {
                            var formDataSection = new FormMultipartSection(section, contentDisposition);

                            // Content-Disposition: form-data; name="key"
                            //
                            // value

                            // Do not limit the key name length here because the multipart headers length limit is already in effect.
                            var key   = formDataSection.Name;
                            var value = await formDataSection.GetValueAsync();

                            var result = GetFormPathDataFromEntry(key);
                            if (result != null && result.Parts.Count == 3 && result.Parts[0] == TransportConstants.FormDataPacketsProp)
                            {
                                if (int.TryParse(result.Parts[1], out var index))
                                {
                                    if (!indexToPacketDataItem.TryGetValue(index, out var dataItem))
                                    {
                                        //// сохраняем предыдущий
                                        //if (current != null)
                                        //{
                                        //    await this.packetsStore.AddIfNotExistsPacketPartAsync(agentId, this.CreateAddPacketRequest(current, currentBytes));
                                        //}

                                        dataItem = new PacketFormDataItem();
                                        indexToPacketDataItem.Add(index, dataItem);
                                    }

                                    if (!dataItem.FillProperty(result.Parts[2], value))
                                    {
                                        throw new InvalidDataException($"Incorrect format for form-data message. Section {key} incorrect.");
                                    }
                                }
                                else
                                {
                                    throw new InvalidDataException($"Incorrect format for form-data message. Section {key} does not have index suffix.");
                                }
                            }
                            else if (result != null && result.Parts.Count == 3 && result.Parts[0] == TransportConstants.FormDataConfigurationProp)
                            {
                                if (int.TryParse(result.Parts[1], out var index))
                                {
                                    if (!indexToConfigurationItem.TryGetValue(index, out var dataItem))
                                    {
                                        dataItem = new ConfigurationRequestDataItem();
                                        indexToConfigurationItem.Add(index, dataItem);
                                    }

                                    if (!dataItem.FillProperty(result.Parts[2], value))
                                    {
                                        throw new InvalidDataException($"Incorrect format for form-data message. Section {key} incorrect.");
                                    }
                                }
                                else
                                {
                                    throw new InvalidDataException($"Incorrect format for form-data message. Section {key} does not have index suffix.");
                                }
                            }
                            else
                            {
                                // ignore or throw?
                            }

                            //if (formAccumulator.ValueCount > _options.ValueCountLimit)
                            //{
                            //    throw new InvalidDataException($"Form value count limit {_options.ValueCountLimit} exceeded.");
                            //}
                        }
                        else
                        {
                            System.Diagnostics.Debug.Assert(false, "Unrecognized content-disposition for this section: " + section.ContentDisposition);
                        }

                        section = await multipartReader.ReadNextSectionAsync(cancellationToken);
                    }

                    // сохраняем все
                    var addResult = indexToPacketDataItem.Any()
                                ? await this.packetsStore.AddIfNotExistsPacketsPartsAsync(agentId, indexToPacketDataItem.Select(x =>
                    {
                        var bytes = indexToPacketBytes[x.Key];
                        return(this.CreateAddPacketRequest(agentId, x.Value, bytes));
                    }).ToList())
                                : AddAddPacketsPartsResult.EmptyResult();

                    return(new ParseBodyAndSavePacketsResult
                    {
                        TransferedPackets = indexToPacketDataItem.Values
                                            .Select(x => {
                            var fromAddResult = addResult.Results.Single(r => r.Request.PacketId == x.PacketId);
                            return new TransferedPacketResponse
                            {
                                PacketId = x.PacketId,
                                ProviderKey = x.ProviderKey,
                                //AgentIdData = agentId,
                                Result = fromAddResult.Success
                                                ? TransferedProcessingResult.Saved
                                                : TransferedProcessingResult.Error,
                                StorageToken = fromAddResult.StorageToken,
                                Id = fromAddResult.Id,
                            };
                        }).ToList(),
                        ConfigurationsStats = indexToConfigurationItem.Values,
                    });
                }
                else
                {
                    var indexToPacketDataItem    = new Dictionary <string, PacketFormDataItem>();
                    var indexToPacketBytes       = new Dictionary <string, byte[]>();
                    var indexToConfigurationItem = new Dictionary <string, ConfigurationRequestDataItem>();
                    var agentId = messageHeaders.GetAgentIdData();

                    foreach (var item in request.Form)
                    {
                        var key   = item.Key;
                        var value = item.Value;

                        var result = GetFormPathDataFromEntry(key);
                        if (result != null && result.Parts.Count == 3 && result.Parts[0] == TransportConstants.FormDataPacketsProp)
                        {
                            var index = result.Parts[1];
                            if (!indexToPacketDataItem.TryGetValue(index, out var dataItem))
                            {
                                dataItem = new PacketFormDataItem();
                                indexToPacketDataItem.Add(index, dataItem);
                            }

                            if (!dataItem.FillProperty(result.Parts[2], value))
                            {
                                throw new InvalidDataException($"Incorrect format for form-data message. Section {key} incorrect.");
                            }
                        }

                        if (result != null && result.Parts.Count == 3 && result.Parts[0] == TransportConstants.FormDataConfigurationProp)
                        {
                            var index = result.Parts[1];
                            if (!indexToConfigurationItem.TryGetValue(index, out var dataItem))
                            {
                                dataItem = new ConfigurationRequestDataItem();
                                indexToConfigurationItem.Add(index, dataItem);
                            }

                            if (!dataItem.FillProperty(result.Parts[2], value))
                            {
                                throw new InvalidDataException($"Incorrect format for form-data message. Section {key} incorrect.");
                            }
                        }
                    }

                    foreach (var file in request.Form.Files)
                    {
                        var pair = indexToPacketDataItem
                                   .FirstOrDefault(x => x.Value.PacketId == file.FileName);

                        if (default(KeyValuePair <string, PacketFormDataItem>).Equals(pair))
                        {
                            var item        = pair.Value;
                            var providerKey = item.ProviderKey;
                            var packetId    = item.PacketId;

                            using (var fileStream = file.OpenReadStream())
                            {
                                var currentBytes = await ReadToEnd(fileStream, fileSectionBufferSize, cancellationToken);

                                indexToPacketBytes.Add(pair.Key, currentBytes);
                            }
                        }
                    }

                    // сохраняем все
                    var addResult = indexToPacketDataItem.Any()
                                ? await this.packetsStore.AddIfNotExistsPacketsPartsAsync(agentId, indexToPacketDataItem.Select(x =>
                    {
                        var bytes = indexToPacketBytes[x.Key];
                        return(this.CreateAddPacketRequest(agentId, x.Value, bytes));
                    }).ToList())
                                : AddAddPacketsPartsResult.EmptyResult();

                    return(new ParseBodyAndSavePacketsResult
                    {
                        TransferedPackets = indexToPacketDataItem.Values
                                            .Select(x =>
                        {
                            var fromAddResult = addResult.Results
                                                .Single(r => r.Request.PacketId == x.PacketId);
                            return new TransferedPacketResponse
                            {
                                PacketId = x.PacketId,
                                ProviderKey = x.ProviderKey,
                                //AgentIdData = agentId,
                                Result = fromAddResult.Success
                                                                    ? TransferedProcessingResult.Saved
                                                                    : TransferedProcessingResult.Error,
                                StorageToken = fromAddResult.StorageToken,
                                Id = fromAddResult.Id,
                            };
                        }).ToList(),
                        ConfigurationsStats = indexToConfigurationItem.Values,
                    });
                }
            }
            else
            {
                throw new NotSupportedException($"format {format} is not supported");
            }
        }
        private async Task <IFormCollection> InnerReadFormAsync(CancellationToken cancellationToken)
        {
            if (!HasFormContentType)
            {
                throw new InvalidOperationException("Incorrect Content-Type: " + _request.ContentType);
            }

            cancellationToken.ThrowIfCancellationRequested();

            if (_options.BufferBody)
            {
                _request.EnableRewind(_options.MemoryBufferThreshold, _options.BufferBodyLengthLimit);
            }

            FormCollection     formFields = null;
            FormFileCollection files      = null;

            // Some of these code paths use StreamReader which does not support cancellation tokens.
            using (cancellationToken.Register((state) => ((HttpContext)state).Abort(), _request.HttpContext))
            {
                var contentType = ContentType;
                // Check the content-type
                if (HasApplicationFormContentType(contentType))
                {
                    var encoding = FilterEncoding(contentType.Encoding);
                    using (var formReader = new FormReader(_request.Body, encoding)
                    {
                        ValueCountLimit = _options.ValueCountLimit,
                        KeyLengthLimit = _options.KeyLengthLimit,
                        ValueLengthLimit = _options.ValueLengthLimit,
                    })
                    {
                        formFields = new FormCollection(await formReader.ReadFormAsync(cancellationToken));
                    }
                }
                else if (HasMultipartFormContentType(contentType))
                {
                    var formAccumulator = new KeyValueAccumulator();

                    var boundary        = GetBoundary(contentType, _options.MultipartBoundaryLengthLimit);
                    var multipartReader = new MultipartReader(boundary, _request.Body)
                    {
                        HeadersCountLimit  = _options.MultipartHeadersCountLimit,
                        HeadersLengthLimit = _options.MultipartHeadersLengthLimit,
                        BodyLengthLimit    = _options.MultipartBodyLengthLimit,
                    };
                    var section = await multipartReader.ReadNextSectionAsync(cancellationToken);

                    while (section != null)
                    {
                        ContentDispositionHeaderValue contentDisposition;
                        ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);
                        if (HasFileContentDisposition(contentDisposition))
                        {
                            // Enable buffering for the file if not already done for the full body
                            section.EnableRewind(_request.HttpContext.Response.RegisterForDispose,
                                                 _options.MemoryBufferThreshold, _options.MultipartBodyLengthLimit);
                            // Find the end
                            await section.Body.DrainAsync(cancellationToken);

                            var name     = HeaderUtilities.RemoveQuotes(contentDisposition.Name) ?? string.Empty;
                            var fileName = HeaderUtilities.RemoveQuotes(contentDisposition.FileName) ?? string.Empty;

                            FormFile file;
                            if (section.BaseStreamOffset.HasValue)
                            {
                                // Relative reference to buffered request body
                                file = new FormFile(_request.Body, section.BaseStreamOffset.Value, section.Body.Length, name, fileName);
                            }
                            else
                            {
                                // Individually buffered file body
                                file = new FormFile(section.Body, 0, section.Body.Length, name, fileName);
                            }
                            file.Headers = new HeaderDictionary(section.Headers);

                            if (files == null)
                            {
                                files = new FormFileCollection();
                            }
                            if (files.Count >= _options.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form value count limit {_options.ValueCountLimit} exceeded.");
                            }
                            files.Add(file);
                        }
                        else if (HasFormDataContentDisposition(contentDisposition))
                        {
                            // Content-Disposition: form-data; name="key"
                            //
                            // value

                            // Do not limit the key name length here because the mulipart headers length limit is already in effect.
                            var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                            MediaTypeHeaderValue mediaType;
                            MediaTypeHeaderValue.TryParse(section.ContentType, out mediaType);
                            var encoding = FilterEncoding(mediaType?.Encoding);
                            using (var reader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                            {
                                // The value length limit is enforced by MultipartBodyLengthLimit
                                var value = await reader.ReadToEndAsync();

                                formAccumulator.Append(key, value);
                                if (formAccumulator.ValueCount > _options.ValueCountLimit)
                                {
                                    throw new InvalidDataException($"Form value count limit {_options.ValueCountLimit} exceeded.");
                                }
                            }
                        }
                        else
                        {
                            System.Diagnostics.Debug.Assert(false, "Unrecognized content-disposition for this section: " + section.ContentDisposition);
                        }

                        section = await multipartReader.ReadNextSectionAsync(cancellationToken);
                    }

                    if (formAccumulator.HasValues)
                    {
                        formFields = new FormCollection(formAccumulator.GetResults(), files);
                    }
                }
            }

            // Rewind so later readers don't have to.
            if (_request.Body.CanSeek)
            {
                _request.Body.Seek(0, SeekOrigin.Begin);
            }

            if (formFields != null)
            {
                Form = formFields;
            }
            else if (files != null)
            {
                Form = new FormCollection(null, files);
            }
            else
            {
                Form = FormCollection.Empty;
            }

            return(Form);
        }
示例#16
0
        public async Task Process(
            HttpRequest request,
            Func <NameValueCollection, Stream> getDestinationStream,
            Action <FileUploadStatus> statusUpdate,
            Action <FormOptions> optionsAction,
            Action <NameValueCollection> postProcess = null
            )
        {
            if (!request.ContentType.IsMultipartContentType())
            {
                throw new InvalidOperationException($"Expected a multipart request, but got {request.ContentType}");
            }

            if (optionsAction != null)
            {
                optionsAction.Invoke(_formOptions);
            }

            string boundary = request.ContentType.GetBoundary();

            NameValueCollection metadata = new NameValueCollection();
            MultipartReader     reader   = new MultipartReader(boundary, request.Body);
            MultipartSection    section  = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                bool hasContentDispositionHeader = ContentDispositionHeaderValue
                                                   .TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (contentDisposition.HasFormDataContentDisposition())
                    {
                        //add form values to metadata collection
                        var encoding = section.GetEncoding();
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            string value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            metadata = value.ParseFormValues();
                        }
                    }

                    if (contentDisposition.HasFileContentDisposition())
                    {
                        metadata.Add("original-name", HeaderUtilities.RemoveQuotes(contentDisposition.FileName).Value);

                        try
                        {
                            Stream           targetStream = getDestinationStream.Invoke(metadata);
                            FileUploadStatus status       = new FileUploadStatus
                            {
                                Metadata = metadata,
                                Key      = metadata["monitor-key"] ?? $"{metadata["group-key"]}-{metadata["original-name"]}",
                                Size     = Int64.Parse(metadata["size"] ?? "1E9")
                            };

                            await Save(section.Body, targetStream, status, statusUpdate);

                            if (postProcess != null)
                            {
                                postProcess.Invoke(metadata);
                            }
                        }
                        catch (Exception ex)
                        {
                            throw ex;
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }
        }
示例#17
0
        public async Task <IActionResult> SaveFileToPhysicalFolder()
        {
            var boundary = HeaderUtilities.RemoveQuotes(
                MediaTypeHeaderValue.Parse(Request.ContentType).Boundary
                ).Value;

            var reader = new MultipartReader(boundary, Request.Body);

            var section = await reader.ReadNextSectionAsync();

            var formAccumelator = new KeyValueAccumulator();

            while (section != null)
            {
                var hasContentDisposition = ContentDispositionHeaderValue.TryParse(
                    section.ContentDisposition, out var contentDisposition
                    );

                if (hasContentDisposition)
                {
                    if (contentDisposition.DispositionType.Equals("form-data") &&
                        (!string.IsNullOrEmpty(contentDisposition.FileName.Value) ||
                         !string.IsNullOrEmpty(contentDisposition.FileNameStar.Value)))
                    {
                        string fileStoragePath = $"{_webHostEnvironment.WebRootPath}/images/";
                        string fileName        = Path.GetRandomFileName() + ".jpg";
                        // uploaded files form fileds
                        byte[] fileByteArray;
                        using (var memoryStream = new MemoryStream())
                        {
                            await section.Body.CopyToAsync(memoryStream);

                            fileByteArray = memoryStream.ToArray();
                        }
                        using (var fileStream = System.IO.File.Create(Path.Combine(fileStoragePath, fileName)))
                        {
                            await fileStream.WriteAsync(fileByteArray);
                        }
                    }
                    else
                    {
                        var key = HeaderUtilities.RemoveQuotes(contentDisposition.Name).Value;

                        using (var streamReader = new StreamReader(section.Body,
                                                                   encoding: Encoding.UTF8,
                                                                   detectEncodingFromByteOrderMarks: true,
                                                                   bufferSize: 1024,
                                                                   leaveOpen: true)){
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }
                            formAccumelator.Append(key, value);
                        }
                    }
                }
                section = await reader.ReadNextSectionAsync();
            }

            var profile            = new Profile();
            var formValueProvidere = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumelator.GetResults()),
                CultureInfo.CurrentCulture
                );

            var bindindSuccessfully = await TryUpdateModelAsync(profile, "", formValueProvidere);

            if (ModelState.IsValid)
            {
                // write log to save profile data to database
            }

            return(Content("Uploaded successfully"));
        }
示例#18
0
        /// Streamed Upload
        public async static Task <int> Upload(HttpRequest request, IFile filesys, string targetFolder,
                                              string filename, long fileSizeLimit, string[] permittedExtensions)
        {
            long _fileSizeLimit = fileSizeLimit;
            int  reason         = 0;

            if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                throw new Exception("Failed on Request.ContentType = " + request.ContentType + " (Error 1)");
            }

            MediaTypeHeaderValue contentType = MediaTypeHeaderValue.Parse(request.ContentType);
            // Use the default form options to set the default limits for request body data.
            int              lengthLimit = (new FormOptions()).MultipartBoundaryLengthLimit;
            string           boundary    = MultipartRequestHelper.GetBoundary(contentType, lengthLimit);
            MultipartReader  reader      = new MultipartReader(boundary, request.Body);
            MultipartSection section     = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader =
                    ContentDispositionHeaderValue.TryParse(
                        section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    // This check assumes that there's a file present without form data.
                    // If form data is present, this method immediately fails and returns the error.
                    if (!MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        throw new Exception("Failed on Content Disposition (Error 2)");
                    }
                    else
                    {
                        // In the  following, the file is saved without scanning the file's contents.
                        // In most production scenarios, an anti-virus/anti-malware scanner API
                        // is used on the file before making the file available for download or
                        // for use by other systems.


                        using (var stream = new MemoryStream())
                        {
                            await section.Body.CopyToAsync(stream);

                            string sourceFilename = contentDisposition.FileName.Value;

                            reason = FileHelpers.CheckStreamSize(stream, _fileSizeLimit);
                            if (reason == 0)
                            {
                                reason = FileHelpers.CheckStreamContent(stream, sourceFilename, permittedExtensions);
                            }

                            if (reason == 0)
                            {
                                byte[] bytes   = stream.ToArray();
                                Stream stream2 = new MemoryStream(bytes);

                                filesys.ChangeDirectory(targetFolder);
                                string ext = Path.GetExtension(sourceFilename).ToLowerInvariant();
                                if (filename == null)
                                {
                                    filename = WebUtility.HtmlEncode(sourceFilename);
                                }
                                filename = Path.ChangeExtension(filename, ext);
                                filesys.FileUpload(filename, stream2);

                                Log.Me.Info("Uploaded " + WebUtility.HtmlEncode(sourceFilename) + " as " + filename);
                            }
                        }
                    }
                }

                // Drain any remaining section body that hasn't been consumed and
                // read the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            return(reason);
        }
示例#19
0
        public static async Task <FormValueProvider> StreamFile(this HttpRequest request, Func <FileMultipartSection, Stream> createStream)
        {
            if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                throw new Exception($"Expected a multipart request, but got {request.ContentType}");
            }

            // 把 request 中的 Form 依照 Key 及 Value 存到此物件
            var formAccumulator = new KeyValueAccumulator();

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                // 把 Form 的欄位內容逐一取出
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        // 若此欄位是檔案,就寫入至 Stream;
                        using (var targetStream = createStream(section.AsFileSection())) {
                            await section.Body.CopyToAsync(targetStream);
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // 若此欄位不是檔案,就把 Key 及 Value 取出,存入 formAccumulator
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name).Value;
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true)) {
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key, value);

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // 取得 Form 的下一個欄位
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to a model
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);

            return(formValueProvider);
        }
        public async Task <IActionResult> UploadDatabase()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                ModelState.AddModelError("File",
                                         $"The request couldn't be processed (Error 1).");
                // Log error

                return(BadRequest(ModelState));
            }
            // Accumulate the form data key-value pairs in the request (formAccumulator).
            var formAccumulator             = new KeyValueAccumulator();
            var trustedFileNameForDisplay   = string.Empty;
            var untrustedFileNameForStorage = string.Empty;
            var streamedFileContent         = new byte[0];

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader =
                    ContentDispositionHeaderValue.TryParse(
                        section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    untrustedFileNameForStorage = contentDisposition.FileName.Value;
                    trustedFileNameForDisplay   = WebUtility.HtmlEncode(contentDisposition.FileName.Value);
                    streamedFileContent         = await FileHelpers.ProcessStreamedFile(section, contentDisposition, ModelState, _permittedExtensions, _fileSizeLimit);

                    if (!ModelState.IsValid)
                    {
                        return(BadRequest(ModelState));
                    }
                }

                else if (MultipartRequestHelper
                         .HasFormDataContentDisposition(contentDisposition))
                {
                    // Don't limit the key name length because the
                    // multipart headers length limit is already in effect.
                    var key = HeaderUtilities
                              .RemoveQuotes(contentDisposition.Name).Value;
                    var encoding = GetEncoding(section);
                    if (encoding == null)
                    {
                        ModelState.AddModelError("File",
                                                 $"The request couldn't be processed (Error 2).");
                        // Log error

                        return(BadRequest(ModelState));
                    }
                    using var streamReader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true);
                    var value = await streamReader.ReadToEndAsync();

                    if (string.Equals(value, "undefined",
                                      StringComparison.OrdinalIgnoreCase))
                    {
                        value = string.Empty;
                    }

                    formAccumulator.Append(key, value);

                    if (formAccumulator.ValueCount >
                        _defaultFormOptions.ValueCountLimit)
                    {
                        // Form key count limit of
                        // _defaultFormOptions.ValueCountLimit
                        // is exceeded.
                        ModelState.AddModelError("File",
                                                 $"The request couldn't be processed (Error 3).");
                        // Log error

                        return(BadRequest(ModelState));
                    }
                }
                // Drain any remaining section body that hasn't been consumed and
                // read the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }
            // Bind form data to the model
            var formData          = new FormData();
            var formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);
            var bindingSuccessful = await TryUpdateModelAsync(formData, prefix : "",
                                                              valueProvider : formValueProvider);

            if (!bindingSuccessful)
            {
                ModelState.AddModelError("File",
                                         "The request couldn't be processed (Error 5).");
                // Log error

                return(BadRequest(ModelState));
            }

            // **WARNING!**
            // In the following example, the file is saved without
            // scanning the file's contents. In most production
            // scenarios, an anti-virus/anti-malware scanner API
            // is used on the file before making the file available
            // for download or for use by other systems.
            // For more information, see the topic that accompanies
            // this sample.
            var file = new AppFile
            {
                Content       = streamedFileContent,
                UntrustedName = untrustedFileNameForStorage,
                Note          = formData.Note,
                UploadDT      = DateTime.UtcNow
            };

            _appDbContext.AppFiles.Add(file);
            await _appDbContext.SaveChangesAsync();

            return(Created(nameof(StreamingController), null));
        }
示例#21
0
        /// based on microsoft example https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/mvc/models/file-uploads/samples/
        /// and large file streaming example https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-5.0#upload-large-files-with-streaming
        private async Task <(GroupDto, ImageDto?)> UploadGroupImageMultipartContent(GroupData groupData, Guid userId, string slug, Stream requestBody, byte[] rowVersion, string?contentType, CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            // Check if HttpRequest (Form Data) is a Multipart Content Type
            if (!MultipartRequestHelper.IsMultipartContentType(contentType))
            {
                throw new InvalidDataException($"Expected a multipart request, but got {contentType}");
            }

            var now = _systemClock.UtcNow.UtcDateTime;

            var defaultFormOptions = new FormOptions();
            // Create a Collection of KeyValue Pairs.
            var formAccumulator = new KeyValueAccumulator();
            // Determine the Multipart Boundary.
            var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(contentType), defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader   = new MultipartReader(boundary, requestBody);
            var section  = await reader.ReadNextSectionAsync(cancellationToken);

            ImageDto?imageDto = null;
            GroupDto groupDto = new GroupDto();

            // Loop through each 'Section', starting with the current 'Section'.
            while (section != null)
            {
                // Check if the current 'Section' has a ContentDispositionHeader.
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);
                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        if (contentDisposition != null)
                        {
                            var sectionFileName = contentDisposition.FileName.Value;
                            // use an encoded filename in case there is anything weird
                            var encodedFileName = WebUtility.HtmlEncode(Path.GetFileName(sectionFileName));

                            // read the section filename to get the content type
                            var fileExtension = Path.GetExtension(sectionFileName);

                            // now make it unique
                            var uniqueFileName = $"{Guid.NewGuid()}{fileExtension}";

                            if (!_acceptedFileTypes.Contains(fileExtension.ToLower()))
                            {
                                _logger.LogError("file extension:{0} is not an accepted image file", fileExtension);
                                throw new ValidationException("Image", "The image is not in an accepted format");
                            }

                            var compressedImage = _imageService.TransformImageForGroupHeader(section.Body);

                            try
                            {
                                await _blobStorageProvider.UploadFileAsync(compressedImage.Image, uniqueFileName,
                                                                           MimeTypesMap.GetMimeType(encodedFileName), cancellationToken);
                            }
                            catch (Exception ex)
                            {
                                _logger.LogError(ex, "An error occurred uploading file to blob storage");
                                throw;
                            }

                            // trick to get the size without reading the stream in memory
                            var size = section.Body.Position;

                            // TODO MimeDetective does not work when stream has already been uploaded - figure out a solution
                            //if (fileContentTypeMatchesExtension is false)
                            //{
                            //    await _blobStorageProvider.DeleteFileAsync(uniqueFileName);
                            //    _logger.LogError("File extension:{0} does not match the file signature", fileExtension);
                            //    throw new FormatException("File extension} does not match the file signature");
                            //}

                            imageDto = new ImageDto
                            {
                                FileSizeBytes = size,
                                FileName      = uniqueFileName,
                                Height        = compressedImage.Height,
                                Width         = compressedImage.Width,
                                IsDeleted     = false,
                                MediaType     = compressedImage.MediaType,
                                CreatedBy     = userId,
                                CreatedAtUtc  = now
                            };

                            var imageValidator        = new ImageValidator(MaxFileSizeBytes);
                            var imageValidationResult = await imageValidator.ValidateAsync(imageDto, cancellationToken);

                            if (imageValidationResult.Errors.Count > 0)
                            {
                                await _blobStorageProvider.DeleteFileAsync(uniqueFileName);

                                _logger.LogError("File size:{0} is greater than the max allowed size:{1}", size, MaxFileSizeBytes);
                                throw new ValidationException(imageValidationResult);
                            }
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // if for some reason other form data is sent it would get processed here
                        var key = HeaderUtilities.RemoveQuotes(contentDisposition?.Name.ToString().ToLowerInvariant());

                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(section.Body, encoding, detectEncodingFromByteOrderMarks: true, bufferSize: 1024, leaveOpen: true))
                        {
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }
                            formAccumulator.Append(key.Value, value);
                            if (formAccumulator.ValueCount > defaultFormOptions.ValueCountLimit)
                            {
                                _logger.LogError("GroupEdit: Form key count limit {0} exceeded.", defaultFormOptions.ValueCountLimit);
                                throw new FormatException($"Form key count limit { defaultFormOptions.ValueCountLimit } exceeded.");
                            }
                        }
                    }
                }
                // Begin reading the next 'Section' inside the 'Body' of the Request.
                section = await reader.ReadNextSectionAsync(cancellationToken);
            }

            if (formAccumulator.HasValues)
            {
                var formValues = formAccumulator.GetResults();

                // Get values from multipart form
                var nameFound = formValues.TryGetValue("name", out var name);
                if (nameFound is false)
                {
                    throw new ValidationException("Name", "Name was not provided");
                }
                var straplineFound = formValues.TryGetValue("strapline", out var strapline);
                if (straplineFound is false)
                {
                    throw new ValidationException("Strapline", "Strapline was not provided");
                }

                formValues.TryGetValue("themeid", out var theme);
                if (Guid.TryParse(theme, out var themeId) is false || themeId == new Guid())
                {
                    throw new ValidationException(nameof(GroupDto.ThemeId), "Theme was not provided");
                }

                formValues.TryGetValue("imageid", out var image);
                var imageId = Guid.TryParse(image, out var imageGuid) ? (Guid?)imageGuid : null;
                if (imageId.HasValue)
                {
                    if (imageId == new Guid())
                    {
                        throw new ArgumentOutOfRangeException($"Incorrect Id provided");
                    }
                }

                formValues.TryGetValue("isPublic", out var publicGroup);
                var isPublic = bool.TryParse(publicGroup, out var isPublicBool) ? isPublicBool : false;
                if (!groupData.IsPublic)
                {
                    if (isPublic != groupData.IsPublic)
                    {
                        throw new ValidationException("isPublic", "Cannot make a private group public");
                    }
                }

                groupDto = new GroupDto
                {
                    Slug          = slug,
                    Name          = _htmlSanitizer.Sanitize(name),
                    Strapline     = _htmlSanitizer.Sanitize(strapline),
                    ThemeId       = themeId,
                    ImageId       = imageId,
                    ModifiedBy    = userId,
                    ModifiedAtUtc = now,
                    IsPublic      = isPublic,
                    RowVersion    = rowVersion
                };
            }
            return(groupDto, imageDto);
        }
        public async Task <ActionResult <ModuleDescriptor> > UploadModuleArchive()
        {
            EnsureModulesCatalogInitialized();
            ModuleDescriptor result = null;

            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
            }
            var uploadPath = Path.GetFullPath(_platformOptions.LocalUploadFolderPath);

            if (!Directory.Exists(uploadPath))
            {
                Directory.CreateDirectory(uploadPath);
            }
            string targetFilePath = null;

            var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader   = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            if (section != null)
            {
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        var fileName = contentDisposition.FileName.Value;
                        targetFilePath = Path.Combine(uploadPath, fileName);

                        using (var targetStream = System.IO.File.Create(targetFilePath))
                        {
                            await section.Body.CopyToAsync(targetStream);
                        }
                    }
                }
                using (var packageStream = System.IO.File.Open(targetFilePath, FileMode.Open))
                    using (var package = new ZipArchive(packageStream, ZipArchiveMode.Read))
                    {
                        var entry = package.GetEntry("module.manifest");
                        if (entry != null)
                        {
                            using (var manifestStream = entry.Open())
                            {
                                var manifest = ManifestReader.Read(manifestStream);
                                var module   = AbstractTypeFactory <ManifestModuleInfo> .TryCreateInstance();

                                module.LoadFromManifest(manifest);
                                var alreadyExistModule = _externalModuleCatalog.Modules.OfType <ManifestModuleInfo>().FirstOrDefault(x => x.Equals(module));
                                if (alreadyExistModule != null)
                                {
                                    module = alreadyExistModule;
                                }
                                else
                                {
                                    //Force dependency validation for new module
                                    _externalModuleCatalog.CompleteListWithDependencies(new[] { module }).ToList().Clear();
                                    _externalModuleCatalog.AddModule(module);
                                }
                                module.Ref = targetFilePath;
                                result     = new ModuleDescriptor(module);
                            }
                        }
                    }
            }
            return(Ok(result));
        }
示例#23
0
        public async Task ReplayRecording()
        {
            using (Database.DocumentsStorage.ContextPool.AllocateOperationContext(out DocumentsOperationContext context))
            {
                if (HttpContext.Request.HasFormContentType == false)
                {
                    HttpContext.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    await using (var writer = new AsyncBlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        context.Write(writer, new DynamicJsonValue
                        {
                            ["Type"]  = "Error",
                            ["Error"] = "Transactions replay requires form content type"
                        });
                        return;
                    }
                }

                var operationId = GetLongQueryString("operationId", false) ?? Database.Operations.GetNextOperationId();

                using (var operationCancelToken = CreateOperationToken())
                {
                    var result = await Database.Operations.AddOperation(
                        database : Database,
                        description : "Replay transaction commands",
                        operationType : Operations.Operations.OperationType.ReplayTransactionCommands,
                        taskFactory : progress => Task.Run(async() =>
                    {
                        var reader = new MultipartReader(MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(HttpContext.Request.ContentType),
                                                                                            MultipartRequestHelper.MultipartBoundaryLengthLimit), HttpContext.Request.Body);
                        while (true)
                        {
                            var section = await reader.ReadNextSectionAsync().ConfigureAwait(false);
                            if (section == null)
                            {
                                break;
                            }

                            if (ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition) == false)
                            {
                                continue;
                            }

                            if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                            {
                                if (section.Headers.ContainsKey("Content-Encoding") && section.Headers["Content-Encoding"] == "gzip")
                                {
                                    await using (var gzipStream = new GZipStream(section.Body, CompressionMode.Decompress))
                                    {
                                        return(await DoReplayAsync(progress, gzipStream, operationCancelToken.Token));
                                    }
                                }
                                return(await DoReplayAsync(progress, section.Body, operationCancelToken.Token));
                            }
                        }

                        throw new BadRequestException("Please upload source file using FormData");
                    }),
                        id : operationId,
                        token : operationCancelToken
                        );

                    await using (var writer = new AsyncBlittableJsonTextWriter(context, ResponseBodyStream()))
                    {
                        context.Write(writer, result.ToJson());
                    }
                }
            }
        }
示例#24
0
        public async Task <ActionResult <ContentItem[]> > UploadContent(string contentType, string storeId, [FromQuery] string folderUrl, [FromQuery] string url = null)
        {
            if (url == null && !MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
            }

            var retVal          = new List <ContentFile>();
            var storageProvider = _blobContentStorageProviderFactory.CreateProvider(GetContentBasePath(contentType, storeId));

            if (url != null)
            {
                var fileName = HttpUtility.UrlDecode(Path.GetFileName(url));
                var fileUrl  = folderUrl + "/" + fileName;

                using (var client = new WebClient())
                    using (var blobStream = storageProvider.OpenWrite(fileUrl))
                        using (var remoteStream = client.OpenRead(url))
                        {
                            remoteStream.CopyTo(blobStream);

                            var сontentFile = AbstractTypeFactory <ContentFile> .TryCreateInstance();

                            сontentFile.Name = fileName;
                            сontentFile.Url  = storageProvider.GetAbsoluteUrl(fileUrl);
                            retVal.Add(сontentFile);
                        }
            }

            else
            {
                var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(Request.ContentType), _defaultFormOptions.MultipartBoundaryLengthLimit);
                var reader   = new MultipartReader(boundary, HttpContext.Request.Body);

                var section = await reader.ReadNextSectionAsync();

                if (section != null)
                {
                    var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out var contentDisposition);

                    if (hasContentDispositionHeader)
                    {
                        var fileName = contentDisposition.FileName.Value ?? contentDisposition.Name.Value.Replace("\"", string.Empty);

                        var targetFilePath = folderUrl + "/" + fileName;

                        using (var targetStream = storageProvider.OpenWrite(targetFilePath))
                        {
                            await section.Body.CopyToAsync(targetStream);
                        }

                        var contentFile = AbstractTypeFactory <ContentFile> .TryCreateInstance();

                        contentFile.Name = fileName;
                        contentFile.Url  = storageProvider.GetAbsoluteUrl(targetFilePath);
                        retVal.Add(contentFile);
                    }
                }
            }

            ContentCacheRegion.ExpireContent(($"content-{storeId}"));

            return(Ok(retVal.ToArray()));
        }
        public static async Task <FormValueProvider> StreamFileAsync(this HttpRequest request, Stream targetStream, CancellationToken cancellationToken = default(CancellationToken))
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                throw new Exception($"Expected a multipart request, but got {request.ContentType}");
            }

            // Used to accumulate all the form url encoded key value pairs in the request.
            var formAccumulator = new KeyValueAccumulator();

            var boundary = MultipartRequestHelper.GetBoundary(MediaTypeHeaderValue.Parse(request.ContentType),
                                                              _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, request.Body);

            var section = await reader.ReadNextSectionAsync(cancellationToken);

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);
                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        formAccumulator.Append("fileName", contentDisposition.FileName.Value);
                        await section.Body.CopyToAsync(targetStream, 81920, cancellationToken);
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }
                            formAccumulator.Append(key.Value, value);

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync(cancellationToken);
            }

            // Bind form data to a model
            var formValueProvider = new FormValueProvider(BindingSource.Form, new FormCollection(formAccumulator.GetResults()), CultureInfo.CurrentCulture);

            return(formValueProvider);
        }
示例#26
0
        public static async Task <string> Start(HttpRequest request, FormOptions options)
        {
            if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                return(null);
            }

            // Used to accumulate all the form url encoded key value pairs in the
            // request.
            var    formAccumulator = new KeyValueAccumulator();
            string targetFilePath  = null;

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(request.ContentType),
                options.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        //targetFilePath = Path.GetTempFileName();
                        targetFilePath = System.IO.Path.Combine(Utils.Constants.TEMP_PATH, contentDisposition.FileName.Value.Replace("\"", ""));
                        using (var targetStream = System.IO.File.Create(targetFilePath))
                        {
                            await section.Body.CopyToAsync(targetStream);
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"
                        //
                        // value

                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key.Value, value);

                            if (formAccumulator.ValueCount > options.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {options.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            return(targetFilePath);
        }
示例#27
0
        public async Task <Unit> Handle(ImportExcelFileCommand request, CancellationToken cancellationToken)
        {
            string      fullPath = null;
            List <City> cities   = new List <City> ();
            List <Sale> sales    = new List <Sale> ();

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(request.context.Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader = new MultipartReader(boundary, request.context.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        string folderName  = "TempExcels";
                        string webRootPath = hostingEnvironment.ContentRootPath;
                        string newPath     = Path.Combine(webRootPath, folderName);
                        if (!Directory.Exists(newPath))
                        {
                            Directory.CreateDirectory(newPath);
                        }
                        fullPath = Path.Combine(newPath, "testdata.xlsx");
                        var targetStream = System.IO.File.Create(fullPath);
                        await section.Body.CopyToAsync(targetStream);

                        ISheet citySheet, saleSheet;
                        await targetStream.FlushAsync();

                        targetStream.Seek(0, SeekOrigin.Begin);
                        XSSFWorkbook hssfwb = new XSSFWorkbook(targetStream);                     //This will read 2007 Excel format
                        citySheet = hssfwb.GetSheet("Cities");
                        saleSheet = hssfwb.GetSheet("Sales");                                     //get first sheet from workbook
                        for (int i = (citySheet.FirstRowNum + 1); i <= citySheet.LastRowNum; i++) //Read Excel File
                        {
                            IRow row = citySheet.GetRow(i);
                            if (row == null)
                            {
                                continue;
                            }
                            cities.Add(new City()
                            {
                                Name = row.GetCell(0).StringCellValue
                            });
                        }
                        cities = await repository.AddCities(cities);

                        for (int i = (saleSheet.FirstRowNum + 1); i <= saleSheet.LastRowNum; i++) //Read Excel File
                        {
                            IRow row = saleSheet.GetRow(i);
                            if (row == null)
                            {
                                continue;
                            }
                            sales.Add(new Sale()
                            {
                                CityId      = cities.First(c => c.Name == row.GetCell(0).StringCellValue).Id,
                                UserName    = row.GetCell(1).StringCellValue,
                                ProductName = row.GetCell(2).StringCellValue,
                                ProductId   = row.GetCell(3).StringCellValue,
                                Price       = (long)row.GetCell(4).NumericCellValue,
                            });
                        }
                        if (sales.Count > 0)
                        {
                            await repository.AddSales(sales);
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            return(Unit.Value);
        }
示例#28
0
        public async Task <IActionResult> uploads()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                return(BadRequest($"Expected a multipart request, but got {Request.ContentType}"));
            }

            StringValues UserName;

            SiteConfig.HttpContextAccessor.HttpContext.Request.Headers.TryGetValue("UName", out UserName);

            // Used to accumulate all the form url encoded key value pairs in the
            // request.
            var formAccumulator = new KeyValueAccumulator();
            // string targetFilePath = null;

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);


            var reader = new MultipartReader(boundary, HttpContext.Request.Body);

            var section = await reader.ReadNextSectionAsync();

            var uploadPath = SiteConfig.Environment.ContentRootPath + DirectoryPaths.BlogsPhotoDirectoryPath;

            if (!Directory.Exists(uploadPath))
            {
                Directory.CreateDirectory(uploadPath);
                Directory.CreateDirectory(uploadPath + "thumbs/");
            }


            var fileName = "";

            while (section != null)
            {
                ContentDispositionHeaderValue contentDisposition;
                var hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition,
                                                                                         out contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        var output = formAccumulator.GetResults();
                        var chunk  = "0";
                        foreach (var item in output)
                        {
                            if (item.Key == "name")
                            {
                                fileName = UtilityBLL.ReplaceSpaceWithHyphin(Path.GetFileNameWithoutExtension(item.Value))
                                           + "-" + Guid.NewGuid().ToString().Substring(0, 10) + Path.GetExtension(item.Value);
                            }
                            else if (item.Key == "chunk")
                            {
                                chunk = item.Value;
                            }
                        }

                        var strPath = uploadPath + "" + fileName;
                        using (var fs = new FileStream(strPath, chunk == "0" ? FileMode.Create : FileMode.Append))
                        {
                            await section.Body.CopyToAsync(fs);

                            fs.Flush();
                        }
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        var key      = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        var encoding = GetEncoding(section);
                        using (var streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: 1024,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            var value = await streamReader.ReadToEndAsync();

                            if (String.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = String.Empty;
                            }
                            formAccumulator.Append(key.ToString(), value);

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                var result = formAccumulator.GetResults();

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            string orignalfilename = uploadPath + "" + fileName;
            string thumbfilename   = uploadPath + "thumbs/" + fileName;

            try
            {
                Jugnoon.Utility.Image.Generate_Thumbs(orignalfilename, thumbfilename, "",
                                                      Jugnoon.Blogs.Configs.BlogSettings.thumbnail_width,
                                                      Jugnoon.Blogs.Configs.BlogSettings.thumbnail_height,
                                                      0, 0, Jugnoon.Settings.Configs.MediaSettings.quality);


                string url       = Config.GetUrl("contents/blogs/thumbs/" + fileName);
                string fileType  = System.IO.Path.GetExtension(fileName);
                string fileIndex = fileName.Replace(fileType, "");

                return(Ok(new { jsonrpc = "2.0", result = "OK", fname = fileName, url = url, filetype = fileType, filename = fileName, fileIndex = fileIndex }));
            }
            catch (Exception ex)
            {
                return(Ok(new {
                    jsonrpc = "2.0",
                    result = "OK",
                    message = ex.Message,
                    attempt = 2
                }));
            }
        }
示例#29
0
        public async Task <IActionResult> UploadPhysical()
        {
            if (!MultipartRequestHelper.IsMultipartContentType(Request.ContentType))
            {
                ModelState.AddModelError("File",
                                         $"The request couldn't be processed (Error 1).");
                // Log error

                return(BadRequest(ModelState));
            }

            var boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(Request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            var reader  = new MultipartReader(boundary, HttpContext.Request.Body);
            var section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                var hasContentDispositionHeader =
                    ContentDispositionHeaderValue.TryParse(
                        section.ContentDisposition, out var contentDisposition);

                if (hasContentDispositionHeader)
                {
                    // This check assumes that there's a file
                    // present without form data. If form data
                    // is present, this method immediately fails
                    // and returns the model error.
                    if (!MultipartRequestHelper
                        .HasFileContentDisposition(contentDisposition))
                    {
                        ModelState.AddModelError("File",
                                                 $"The request couldn't be processed (Error 2).");
                        // Log error

                        return(BadRequest(ModelState));
                    }
                    else
                    {
                        // Don't trust the file name sent by the client. To display
                        // the file name, HTML-encode the value.
                        var trustedFileNameForDisplay = WebUtility.HtmlEncode(
                            contentDisposition.FileName.Value);
                        var trustedFileNameForFileStorage = Path.GetRandomFileName();

                        // **WARNING!**
                        // In the following example, the file is saved without
                        // scanning the file's contents. In most production
                        // scenarios, an anti-virus/anti-malware scanner API
                        // is used on the file before making the file available
                        // for download or for use by other systems.
                        // For more information, see the topic that accompanies
                        // this sample.

                        var streamedFileContent = await FileHelpers.ProcessStreamedFile(
                            section, contentDisposition, ModelState,
                            _permittedExtensions, _fileSizeLimit);

                        if (!ModelState.IsValid)
                        {
                            return(BadRequest(ModelState));
                        }

                        using (var targetStream = System.IO.File.Create(
                                   Path.Combine(_targetFilePath, trustedFileNameForFileStorage)))
                        {
                            await targetStream.WriteAsync(streamedFileContent);

                            _logger.LogInformation(
                                $"Uploaded file '{trustedFileNameForDisplay}' saved to " +
                                $"'{_targetFilePath}' as {trustedFileNameForFileStorage}");
                        }
                    }
                }

                // Drain any remaining section body that hasn't been consumed and
                // read the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            return(Created(nameof(StreamingController), null));
        }
示例#30
0
        public static async Task <FormValueProvider> StreamFile(this HttpRequest request, Stream targetStream, int bufferSize)
        {
            if (!MultipartRequestHelper.IsMultipartContentType(request.ContentType))
            {
                throw new Exception($"Expected a multipart request, but got {request.ContentType}");
            }

            // Used to accumulate all the form url encoded key value pairs in the
            // request.
            KeyValueAccumulator formAccumulator = new KeyValueAccumulator();
            // string targetFilePath = null;

            string boundary = MultipartRequestHelper.GetBoundary(
                MediaTypeHeaderValue.Parse(request.ContentType),
                _defaultFormOptions.MultipartBoundaryLengthLimit);
            MultipartReader reader = new MultipartReader(boundary, request.Body);

            MultipartSection section = await reader.ReadNextSectionAsync();

            while (section != null)
            {
                bool hasContentDispositionHeader = ContentDispositionHeaderValue.TryParse(section.ContentDisposition, out ContentDispositionHeaderValue contentDisposition);

                if (hasContentDispositionHeader)
                {
                    if (MultipartRequestHelper.HasFileContentDisposition(contentDisposition))
                    {
                        await section.Body.CopyToAsync(targetStream);
                    }
                    else if (MultipartRequestHelper.HasFormDataContentDisposition(contentDisposition))
                    {
                        // Content-Disposition: form-data; name="key"
                        //
                        // value

                        // Do not limit the key name length here because the
                        // multipart headers length limit is already in effect.
                        Microsoft.Extensions.Primitives.StringSegment key = HeaderUtilities.RemoveQuotes(contentDisposition.Name);
                        Encoding encoding = GetEncoding(section);
                        using (StreamReader streamReader = new StreamReader(
                                   section.Body,
                                   encoding,
                                   detectEncodingFromByteOrderMarks: true,
                                   bufferSize: bufferSize,
                                   leaveOpen: true))
                        {
                            // The value length limit is enforced by MultipartBodyLengthLimit
                            string value = await streamReader.ReadToEndAsync();

                            if (string.Equals(value, "undefined", StringComparison.OrdinalIgnoreCase))
                            {
                                value = string.Empty;
                            }
                            formAccumulator.Append(key.Value, value); // For .NET Core <2.0 remove ".Value" from key

                            if (formAccumulator.ValueCount > _defaultFormOptions.ValueCountLimit)
                            {
                                throw new InvalidDataException($"Form key count limit {_defaultFormOptions.ValueCountLimit} exceeded.");
                            }
                        }
                    }
                }

                // Drains any remaining section body that has not been consumed and
                // reads the headers for the next section.
                section = await reader.ReadNextSectionAsync();
            }

            // Bind form data to a model
            FormValueProvider formValueProvider = new FormValueProvider(
                BindingSource.Form,
                new FormCollection(formAccumulator.GetResults()),
                CultureInfo.CurrentCulture);

            return(formValueProvider);
        }