Пример #1
0
        /// <summary>
        /// Orchestrates common block reading procedures for the <see cref="ReadBlock"/> and
        /// <see cref="ReadBlockStreamed"/> methods.
        /// </summary>
        protected virtual T OrchestrateBlockReading <T>(TTransfer transfer, long blockNumber,
                                                        Func <TTransfer, long, DataBlockInfo, T> readerImplFunc) where T : IDataBlock
        {
            const FileSystemTask context = FileSystemTask.DataBlockDownloadRequest;

            if (blockNumber < 0)
            {
                string msg = "Invalid block number [{0}] requested - block numbers cannot be negative.";
                msg = String.Format(msg, blockNumber);
                throw new DataBlockException(msg);
            }

            if (blockNumber >= transfer.Token.TotalBlockCount)
            {
                string msg = "Invalid block number [{0}] requested - the total number of blocks is [{1}].";
                msg = String.Format(msg, blockNumber, transfer.Token.TotalBlockCount);
                throw new DataBlockException(msg);
            }

            //make sure the file still exists
            if (!transfer.FileItem.Exists)
            {
                Auditor.AuditRequestedFileNotFound(transfer.FileItem, context);

                string msg = "Resource [{0}] of transfer [{1}] was not found.";
                msg = String.Format(msg, transfer.Token.ResourceName, transfer.TransferId);
                throw new VirtualResourceNotFoundException(msg)
                      {
                          IsAudited = true
                      };
            }

            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.DownloadNoLongerActive, transfer.FileItem, msg);
                    throw new TransferStatusException(msg)
                          {
                              IsAudited = true, EventId = (int)AuditEvent.DownloadNoLongerActive
                          };
                }

                //check whether we already transferred this block once
                DataBlockInfo transferredBlock = transfer.TryGetTransferredBlock(blockNumber);

                T dataBlock = readerImplFunc(transfer, blockNumber, transferredBlock);

                //update status
                transfer.Status = TransferStatus.Running;

                //store copy of the downloaded block that doesn't contain any data
                transfer.RegisterBlock(DataBlockInfo.FromDataBlock(dataBlock));

                //audit download
                Auditor.AuditTransferOperation(context, AuditEvent.FileBlockDownloaded, transfer.TransferId, transfer.FileItem);

                return(dataBlock);
            }
        }
Пример #2
0
        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);
        }