/// <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); } }