/// <summary> 获取下载流 /// </summary> /// <param name="fileName"></param> /// <returns></returns> public Stream GetDownloadStream(HttpContext httpContext, string fileName) { string filePath = this.GetServerFilePath(fileName); PartialFileInfo partialFileInfo = this.GetPartialFileInfo(httpContext.Request, filePath); this.SetResponseHeaders(httpContext.Response, partialFileInfo); return(this.GetPartialFileStream(partialFileInfo)); }
/// <summary> 异步获取下载流 /// </summary> /// <param name="fileName"></param> /// <returns></returns> public Task <Stream> GetDownloadStreamAsync(HttpContext httpContext, string fileName) { return(Task.Run <Stream>(() => { string filePath = this.GetServerFilePath(fileName); PartialFileInfo partialFileInfo = this.GetPartialFileInfo(httpContext.Request, filePath); this.SetResponseHeaders(httpContext.Response, partialFileInfo); return this.GetPartialFileStream(partialFileInfo); })); }
public async Task ArchiveChannel(ISocketMessageChannel channel, [Remainder] string title) { var messages = await channel.GetMessagesAsync().Flatten(); using (ChannelArchive archive = new ChannelArchive(title)) { string voteEmote = _settings.Has("brackeys-emote") ? _settings.Get("brackeys-emote").Split(':').First() : string.Empty; foreach (IMessage msg in messages) { ArchiveMessage archiveMessage = new ArchiveEventSubmission(msg, voteEmote); IEnumerable <ArchiveImage> archiveImages = archiveMessage.GetMessageImages(); archive.AddMessage(archiveMessage); foreach (ArchiveImage image in archiveImages) { archive.AddImage(image); } } archive.CloseArchive(); string zippedArchive = archive.ZipArchive(); WeTransferClient wt = new WeTransferClient(BrackeysBot.Configuration["wetransfer-api-key"]); // Make sure we are authorized await wt.Authorize(); var fileInfo = new System.IO.FileInfo(zippedArchive); // Create Partial File Information so WeTransfer knows how many files // you're going to upload, the names of those files and their sizes PartialFileInfo[] partialFileInfos = new PartialFileInfo[] { new PartialFileInfo { Name = fileInfo.Name, Path = fileInfo.FullName, Size = (int)fileInfo.Length } }; // Create a File Transfer which informs WeTransfer that you're about to upload files // The second parameter is the transfer message which will show on the download page FileTransferResponse response = await wt.CreateTransfer(partialFileInfos, $"Download the archived channel #{channel.Name}!"); // Now you can upload the files! // The first parameter is the transfer's ID await wt.Upload(response.ID, response.Files); // Now you need to tell WeTransfer that your files have been uploaded FileUploadResult result = await wt.FinalizeUpload(response.ID, response.Files); // FileUploadResult contains the url to the download page and the date of the expiry StringBuilder reply = new StringBuilder() .AppendLine($"I archived the channel <#{channel.Id}> for you{(title == channel.Name ? "!" : $", under the name **{title}**!")}")
/// <summary> /// 设置响应头信息 /// </summary> /// <param name="response"></param> /// <param name="partialFileInfo"></param> /// <param name="fileLength"></param> /// <param name="fileName"></param> private void SetResponseHeaders(HttpResponse response, PartialFileInfo partialFileInfo) { response.Headers[HeaderNames.AcceptRanges] = "bytes"; response.StatusCode = partialFileInfo.IsPartial ? StatusCodes.Status206PartialContent : StatusCodes.Status200OK; var contentDisposition = new ContentDispositionHeaderValue("attachment"); contentDisposition.SetHttpFileName(partialFileInfo.Name); response.Headers[HeaderNames.ContentDisposition] = contentDisposition.ToString(); response.Headers[HeaderNames.ContentType] = "application/octet-stream"; //response.Headers[HeaderNames.ContentMD5] = partialFileInfo.MD5; response.Headers[HeaderNames.ContentLength] = partialFileInfo.Length.ToString(); if (partialFileInfo.IsPartial) { response.Headers[HeaderNames.ContentRange] = new ContentRangeHeaderValue(partialFileInfo.From, partialFileInfo.To, partialFileInfo.FileLength).ToString(); } }
/// <summary> 获取文件分块信息 /// </summary> /// <param name="request"></param> /// <param name="filePath"></param> /// <returns></returns> private PartialFileInfo GetPartialFileInfo(HttpRequest request, string filePath) { PartialFileInfo partialFileInfo = new PartialFileInfo(filePath); if (RangeHeaderValue.TryParse(request.Headers[HeaderNames.Range].ToString(), out RangeHeaderValue rangeHeaderValue)) { var range = rangeHeaderValue.Ranges.FirstOrDefault(); if (range.From.HasValue && range.From < 0 || range.To.HasValue && range.To > partialFileInfo.FileLength - 1) { return(null); } var from = range.From; var to = range.To; if (from.HasValue) { if (from.Value >= partialFileInfo.FileLength) { return(null); } if (!to.HasValue || to.Value >= partialFileInfo.FileLength) { to = partialFileInfo.FileLength - 1; } } else { if (to.Value == 0) { return(null); } var bytes = Math.Min(to.Value, partialFileInfo.FileLength); from = partialFileInfo.FileLength - bytes; to = from + bytes - 1; } partialFileInfo.IsPartial = true; partialFileInfo.Length = to.Value - from.Value + 1; } return(partialFileInfo); }
/// <summary> 获取分块文件流 /// </summary> /// <param name="partialFileInfo"></param> /// <returns></returns> private Stream GetPartialFileStream(PartialFileInfo partialFileInfo) { return(new PartialFileStream(partialFileInfo.FilePath, partialFileInfo.From, partialFileInfo.To)); }