示例#1
0
 public async Task <DataResult <UploadResultData> > UploadAsync(FileOwnerTypeId foti, IFormFile file, string fileName, string hash, int periodMinute)
 {
     using (var stream = file?.OpenReadStream())
     {
         return(await UploadAsync(foti, stream, fileName, hash, periodMinute));
     }
 }
 /// <summary>
 /// 为指定用户创建文件
 /// </summary>
 public async Task <FileStorageInfo> CreateFileAsync(FileOwnerTypeId ownerTypeId, string hash, IFormFile file, string fileName, int periodMinute = 0)
 {
     using (var stream = file?.OpenReadStream())
     {
         return(await CreateFileAsync(ownerTypeId, hash, stream, fileName, periodMinute));
     }
 }
示例#3
0
        public async Task <DataResult <UploadResultData> > UploadBlockAsync(FileOwnerTypeId foti, Stream file, string fileName, string hash, int periodMinute, int curBlock, int blockTotal)
        {
            try
            {
                var fileInfo = await _storageSvce.CreateFileBlockAsync(foti, hash, file, fileName, periodMinute, curBlock, blockTotal);

                var etAddMinute = periodMinute > 0 ? periodMinute : 52560000; //最大100年
                var fToken      = new FileToken
                {
                    PseudoId       = fileInfo.PseudoId,
                    FileId         = fileInfo.File.Id,
                    FileOwnerId    = fileInfo.Owner.Id,
                    MimeId         = (uint)fileInfo.File.MimeId,
                    FileCreateTime = fileInfo.File.CreateTime,
                    ExpireTime     = DateTime.Now.AddMinutes(etAddMinute)
                };
                var fTokenStr = _fileTokenCodec.Encode(fToken);

                var urDat = new UploadResultData
                {
                    FileToken = fTokenStr,
                    Url       = $"{GetCurrentScheme()}://{fileInfo.Server.Host}/files/{fTokenStr}",
                    Name      = fileInfo.Owner.Name,
                    Length    = fileInfo.File.Length
                };
                var signLst = new[]
                {
                    new KeyValuePair <string, object>(nameof(UploadResultData.FileToken), urDat.FileToken),
                    new KeyValuePair <string, object>(nameof(UploadResultData.Url), urDat.Url),
                    new KeyValuePair <string, object>(nameof(UploadResultData.Name), urDat.Name),
                    new KeyValuePair <string, object>(nameof(UploadResultData.Length), urDat.Length)
                };
                urDat.Sign = _appSecretSigner.Sign(signLst);

                return(new DataResult <UploadResultData>(ResultErrorCodes.Success)
                {
                    Data = urDat
                });
            }
            catch (FileNotFoundException)
            {
                return(new DataResult <UploadResultData>(100, "文件不存在,请直接上传"));
            }
            catch (Exception ex)
            {
                _logger.LogError(ex.ToString());
                return(new DataResult <UploadResultData>(ResultErrorCodes.SystemError, ex.Message));
            }
        }
示例#4
0
        public Task <DataResult <UploadResultData> > UploadBlockAsync(string ownerToken, Stream file, string fileName,
                                                                      string hash, int periodMinute, int curBlock, int blockTotal)
        {
            if (!DecodeAndCheckOwnerToken(ownerToken, out var oToken, out DataResult <UploadResultData> result))
            {
                return(Task.FromResult(result));
            }

            var foti = new FileOwnerTypeId
            {
                OwnerType = oToken.OwnerType,
                OwnerId   = oToken.OwnerId
            };

            return(UploadBlockAsync(foti, file, fileName, hash, periodMinute, curBlock, blockTotal));
        }
        /// <summary>
        /// 为指定用户创建文件
        /// </summary>
        public async Task <FileStorageInfo> CreateFileAsync(FileOwnerTypeId ownerTypeId, string hash, Stream file, string fileName, int periodMinute = 0)
        {
            if (!_clusterSvce.CurrentServer.AllowUpload)
            {
                throw new FriendlyException("请从上传服务器上传");
            }

            string tmpFilePath = null;

            try
            {
                var extName = Path.GetExtension(fileName);
                if (string.IsNullOrEmpty(extName))
                {
                    throw new FriendlyException("文件名缺少扩展名");
                }
                extName = extName.Substring(1).ToLower();
                var mime = _mimeProvider.GetMimeByExtensionName(extName);

                //获取hash
                if (file != null)
                {
                    tmpFilePath = await ReceiveToTempFileAsync(file);

                    //优先使用文件的hash
                    //hash = FileUtil.GetSha1(tmpFilePath);
                }
                if (string.IsNullOrWhiteSpace(hash))
                {
                    throw new FriendlyException("hash 必需指定");
                }
                //throw new FriendlyException("file 与 hash 必需至少指定一个");

                Task tSync    = null;
                var  pseudoId = GeneratePseudoId(hash);
                var  fileInfo = await FileRepo.GetFileByHashAsync(pseudoId, hash);

                //文件不存在,并且没有传file流
                if (fileInfo == null && tmpFilePath == null)
                {
                    throw new FileNotFoundException("File does not exist");
                }

                //检查所有者剩余配额
                var fileSize    = fileInfo?.Length ?? new System.IO.FileInfo(tmpFilePath).Length;
                var remainQuota = await OwnerRepo.GetOwnerRemainQuotaAsync(ownerTypeId.OwnerType, ownerTypeId.OwnerId);

                if (remainQuota < fileSize)
                {
                    throw new FriendlyException("您已经没有足够的空间上传该文件");
                }

                Service.Options.Server recServer = null;
                //检查存在否
                if (fileInfo == null)
                {
                    //插入新文件记录
                    recServer = _clusterSvce.ElectServer();
                    fileInfo  = new File
                    {
                        ServerId   = recServer.Id,
                        Length     = new System.IO.FileInfo(tmpFilePath).Length,
                        MimeId     = (int)mime.Id,
                        SHA1       = hash,
                        ExtInfo    = string.Empty,
                        CreateTime = DateTime.Now
                    };
                    await FileRepo.AddFileAsync(fileInfo, pseudoId);

                    tSync = _clusterSvce.SyncFileToServerAsync(this, tmpFilePath, fileInfo, pseudoId, recServer);
                }
                else
                {
                    recServer = _clusterSvce.GetServerById(fileInfo.ServerId);
                    var fileExists = await _clusterSvce.RawFileExistsAsync(this, recServer, pseudoId, fileInfo.CreateTime, fileInfo.Id);

                    if (!fileExists)
                    {
                        //通过hash进来的,并且文件不存在
                        if (string.IsNullOrEmpty(tmpFilePath))
                        {
                            await FileRepo.DeleteFileAsync(ownerTypeId.OwnerId, fileInfo.Id, pseudoId);

                            throw new FriendlyException("File does not exist(CFA-FE)");
                        }


                        //文件被删或意外丢失重传
                        tSync = _clusterSvce.SyncFileToServerAsync(this, tmpFilePath, fileInfo, pseudoId, recServer);
                    }
                }

                var fileOwner = await FileRepo.GetFileOwnerByOwnerAsync(pseudoId, fileInfo.Id, ownerTypeId.OwnerType, ownerTypeId.OwnerId);

                if (fileOwner == null)
                {
                    fileOwner = new FileOwner
                    {
                        FileId     = fileInfo.Id,
                        Name       = fileName,
                        OwnerType  = ownerTypeId.OwnerType,
                        OwnerId    = ownerTypeId.OwnerId,
                        CreateTime = DateTime.Now
                    };
                    await FileRepo.AddFileOwnerAsync(fileOwner, pseudoId);
                }
                if (tSync != null)
                {
                    await tSync;
                }

                //添加配额使用量
                await OwnerRepo.AddOwnerUsedQuotaAsync(ownerTypeId.OwnerType, ownerTypeId.OwnerId, fileSize);

                return(new FileStorageInfo
                {
                    File = fileInfo,
                    Owner = fileOwner,
                    Server = recServer,
                    PseudoId = pseudoId
                });
            }
            finally
            {
                if (tmpFilePath != null)
                {
                    FileUtil.TryDelete(tmpFilePath);
                }
            }
        }