Ejemplo n.º 1
0
        /// <summary>
        /// Fetch file for created session.
        /// </summary>
        /// <param name="sessionId">Session identifier.</param>
        /// <param name="templateCode">Element's template code.</param>
        /// <param name="fetchParameters">Fetch parameters.</param>
        /// <exception cref="InvalidTemplateException">Specified template code does not refer to binary element.</exception>
        /// <exception cref="InvalidFetchUrlException">Fetch URL is invalid.</exception>
        /// <exception cref="MissingFilenameException">Filename is not specified.</exception>
        /// <exception cref="ObjectNotFoundException">Session or template has not been found.</exception>
        /// <exception cref="SessionExpiredException">Specified session is expired.</exception>
        /// <exception cref="S3Exception">Error making request to S3.</exception>
        /// <exception cref="InvalidBinaryException">Binary does not meet template's constraints.</exception>
        /// <exception cref="FetchFailedException">Fetch request failed.</exception>
        /// <returns>Fetched file key.</returns>
        public async Task <string> FetchFile(Guid sessionId, int templateCode, FetchParameters fetchParameters)
        {
            if (!TryCreateUri(fetchParameters, out var fetchUri))
            {
                throw new InvalidFetchUrlException(
                          $"Fetch URI must be a valid absolute URI with '{Uri.UriSchemeHttp}' or '{Uri.UriSchemeHttps}' scheme");
            }

            MultipartUploadSession uploadSession = null;

            var(sessionDescriptor, _, expiresAt) = await _sessionStorageReader.GetSessionDescriptor(sessionId);  // Firstly ensure that specified session exists

            try
            {
                var(stream, mediaType) = await _fetchClient.FetchAsync(fetchUri);

                var fileMetadata = new GenericUploadedFileMetadata(fetchParameters.FileName, mediaType, stream.Length);
                uploadSession = await InitiateMultipartUploadInternal(sessionId, templateCode, fileMetadata, sessionDescriptor, expiresAt);
                await UploadFilePart(uploadSession, stream, templateCode);

                var fetchedFileKey = await CompleteMultipartUpload(uploadSession);

                return(fetchedFileKey);
            }
            catch (FetchResponseTooLargeException ex)
            {
                throw new InvalidBinaryException(templateCode, new BinaryTooLargeError(ex.ContentLength));
            }
            catch (FetchRequestException ex)
            {
                throw new FetchFailedException($"Fetch request failed with status code {ex.StatusCode} and content: {ex.Message}");
            }
            catch (HttpRequestException ex)
            {
                throw new FetchFailedException($"Fetch request failed: {ex.Message}");
            }
            catch (TimeoutRejectedException)
            {
                throw new FetchFailedException("Fetch request failed: request timeout exceeded");
            }
            catch (FetchResponseContentTypeInvalidException ex)
            {
                throw new FetchFailedException($"Fetch request failed: {ex.Message}");
            }
            finally
            {
                if (uploadSession != null)
                {
                    await AbortMultipartUpload(uploadSession);
                }
            }
        }
        private static bool TryParseUploadedFileMetadata(
            IFormFile file,
            string rawFileType,
            string rawImageSize,
            out IUploadedFileMetadata uploadedFileMetadata,
            out string error)
        {
            uploadedFileMetadata = null;
            error = null;

            if (string.IsNullOrEmpty(rawFileType))
            {
                uploadedFileMetadata = new GenericUploadedFileMetadata(file.FileName, file.ContentType, file.Length);
                return(true);
            }

            if (!Enum.TryParse <FileType>(rawFileType, true, out var fileType))
            {
                error = $"Cannot parse '{Http.HeaderNames.AmsFileType}' header value '{fileType}'";
                return(false);
            }

            switch (fileType)
            {
            case FileType.SizeSpecificBitmapImage:
                if (!ImageSize.TryParse(rawImageSize, out var imageSize))
                {
                    error = $"Cannot parse '{Http.HeaderNames.AmsImageSize}' header value '{rawImageSize}'";
                    return(false);
                }

                uploadedFileMetadata = new UploadedImageMetadata(file.FileName, file.ContentType, file.Length, imageSize);
                return(true);

            default:
                error = $"Unexpected '{Http.HeaderNames.AmsFileType}' header value '{fileType}'";
                return(false);
            }
        }