/// <summary> /// Orchestrates common block reading procedures for the <see cref="WriteBlock"/> and /// <see cref="WriteBlockStreamed"/> methods. /// </summary> protected virtual void OrchestrateBlockWriting <T>(T dataBlock, Action <TTransfer, T> writerImplFunc) where T : class, IDataBlock { Ensure.ArgumentNotNull(dataBlock, "dataBlock"); const FileSystemTask context = FileSystemTask.DataBlockUploadRequest; TTransfer transfer = GetCachedTransfer(dataBlock.TransferTokenId, true, context); lock (transfer.SyncRoot) { //make sure the transfer is active if (!transfer.Status.Is(TransferStatus.Starting, TransferStatus.Running, TransferStatus.Paused)) { string msg = String.Format("Transfer [{0}] is not active anymore - status is [{1}].", transfer.TransferId, transfer.Status); if (transfer.AbortReason.HasValue) { msg += String.Format(" Transfer abort reason: [{0}].", transfer.AbortReason); } Auditor.AuditDeniedOperation(context, AuditEvent.UploadNoLongerActive, transfer.FileItem, msg); throw new TransferStatusException(msg) { IsAudited = true, EventId = (int)AuditEvent.UploadNoLongerActive }; } if (!transfer.HasUploadStarted) { if (transfer.FileItem.Exists) { //overwrite an existing file DeleteExistingFileImpl(transfer); } InitializeFileUploadImpl(transfer); transfer.HasUploadStarted = true; } //update status transfer.Status = TransferStatus.Running; ValidateBlockSizeAndSettings(transfer, dataBlock); //write the data to the file system writerImplFunc(transfer, dataBlock); //store copy of the uploaded block that doesn't contain any data transfer.RegisterBlock(DataBlockInfo.FromDataBlock(dataBlock)); //audit uploaded block Auditor.AuditResourceOperation(context, AuditEvent.FileBlockUploaded, transfer.FileItem); //if we just read the last block, close implicitly if (dataBlock.IsLastBlock) { CompleteTransfer(transfer.TransferId); } } }
private TTransfer InitTransferImpl(string submittedResourceFilePath, bool overwrite, long resourceLength, string contentType) { const FileSystemTask context = FileSystemTask.UploadTokenRequest; //validate maximum file size var maxFileSize = GetMaxFileUploadSize(); if (maxFileSize.HasValue && maxFileSize < resourceLength) { string msg = "Upload for file [{0}] denied: Resource length of [{1}] is above the maximum upload limit of [{2}] bytes."; msg = String.Format(msg, submittedResourceFilePath, resourceLength, maxFileSize.Value); throw new ResourceAccessException(msg); } //of course, the length cannot be negative if (resourceLength < 0) { string msg = "Upload for file [{0}] denied: Resource length cannot be negative [{1}]."; msg = String.Format(msg, submittedResourceFilePath, resourceLength); throw new ResourceAccessException(msg); } TFile fileItem = CreateFileItemImpl(submittedResourceFilePath, false, context); if (fileItem.Exists && !overwrite) { Auditor.AuditDeniedOperation(context, AuditEvent.FileAlreadyExists, fileItem); string msg = String.Format("Cannot upload file [{0}] without overwriting existing data - a file already exists at this location.", submittedResourceFilePath); throw new ResourceOverwriteException(msg) { IsAudited = true }; } //get authorization TFolder parentFolder = GetParentFolder(fileItem, context); //validate file system specific restrictions VerifyCanUploadFileToFileSystemLocation(submittedResourceFilePath, parentFolder, fileItem); //get parent folder and check whether files can be added FolderClaims folderClaims = GetParentFolderClaims(fileItem, parentFolder); if (!folderClaims.AllowAddFiles) { //deny adding a file to that folder Auditor.AuditDeniedOperation(context, AuditEvent.CreateFileDenied, fileItem); string msg = "Cannot create file at [{0}] - adding files to the folder is not permitted."; msg = String.Format(msg, submittedResourceFilePath); throw new ResourceAccessException(msg) { IsAudited = true }; } //only overwrite a file if explicitly requested FileClaims claims = GetFileClaims(fileItem); if (fileItem.Exists) { if (!claims.AllowOverwrite) { Auditor.AuditDeniedOperation(context, AuditEvent.FileDataOverwriteDenied, fileItem); string msg = "Overwriting file [{0}] was denied due to missing permission."; msg = String.Format(msg, submittedResourceFilePath); throw new ResourceOverwriteException(msg) { IsAudited = true }; } } //try to get lock ResourceLockGuard writeLock = LockResourceForUpload(fileItem); if (writeLock != null && !writeLock.IsLockEnabled) { Auditor.AuditDeniedOperation(context, AuditEvent.FileReadLockDenied, fileItem); string msg = "The file [{0}] is currently locked and cannot be accessed."; msg = String.Format(msg, submittedResourceFilePath); throw new ResourceLockedException(msg) { IsAudited = true }; } //create upload token UploadToken token = CreateUploadToken(submittedResourceFilePath, fileItem, resourceLength, contentType); //create expiration job if we have an expiration time Job <UploadToken> job = null; if (token.ExpirationTime.HasValue) { job = ScheduleExpiration(token); } //create and cache transfer instance TTransfer transfer = CreateTransfer(submittedResourceFilePath, fileItem, parentFolder, token, claims, writeLock, job); TransferStore.AddTransfer(transfer); Auditor.AuditResourceOperation(context, AuditEvent.UploadTokenIssued, fileItem); return(transfer); }
private TTransfer InitTransferImpl(string submittedResourceFilePath, int?clientMaxBlockSize, bool includeFileHash) { const FileSystemTask context = FileSystemTask.DownloadTokenRequest; TFile fileItem = CreateFileItemImpl(submittedResourceFilePath, false, context); if (!fileItem.Exists) { Auditor.AuditRequestedFileNotFound(fileItem, context); string msg = String.Format("Resource [{0}] not found.", submittedResourceFilePath); throw new VirtualResourceNotFoundException(msg) { IsAudited = true }; } //get authorization FileClaims claims = GetFileClaims(fileItem); if (!claims.AllowReadData) { Auditor.AuditDeniedOperation(context, AuditEvent.FileDataDownloadDenied, fileItem); string msg = "Read request for file [{0}] was denied - you are not authorized to read the resource."; msg = String.Format(msg, submittedResourceFilePath); throw new ResourceAccessException(msg) { IsAudited = true }; } //try to get lock ResourceLockGuard readLock = LockResourceForDownload(fileItem, claims); if (readLock != null && !readLock.IsLockEnabled) { Auditor.AuditDeniedOperation(context, AuditEvent.FileReadLockDenied, fileItem); string msg = "The requested file [{0}] is currently locked and thus cannot be accessed."; msg = String.Format(msg, submittedResourceFilePath); throw new ResourceLockedException(msg) { IsAudited = true }; } //create download token DownloadToken token = CreateDownloadToken(submittedResourceFilePath, fileItem, clientMaxBlockSize, includeFileHash); //create expiration job if we have an expiration time Job <DownloadToken> job = null; if (token.ExpirationTime.HasValue) { job = ScheduleExpiration(token); } //create transfer instance TTransfer transfer = CreateTransfer(submittedResourceFilePath, fileItem, token, claims, readLock, job); //cache transfer TransferStore.AddTransfer(transfer); //audit issued token Auditor.AuditResourceOperation(context, AuditEvent.DownloadTokenIssued, fileItem); return(transfer); }