public static async Task Test_CopyStream() { //Prepare MemoryStream msSource = new MemoryStream(); StreamWriter swSource = new StreamWriter(msSource); swSource.Write(dummyPath); swSource.Flush(); msSource.Seek(0, SeekOrigin.Begin); MemoryStream msDest = new MemoryStream(); StreamReader reader = new StreamReader(msDest); CopyStream copyStream = new CopyStream(); ParameterDic pd = new ParameterDic() { { copyStream.SourceKey, msSource }, { copyStream.DestinationKey, msDest } }; //Action IScriptCommand retCmd = await copyStream.ExecuteAsync(pd); msDest.Seek(0, SeekOrigin.Begin); string read = reader.ReadToEnd(); //Assert Assert.AreEqual(dummyPath, read); }
/// <summary> /// This is called when the request is PUT/POST/PATCH to read the body /// </summary> /// <returns></returns> internal async Task CopyRequestBodyAsync(HttpWriter writer, TransformationMode transformation, CancellationToken cancellationToken) { var request = WebSession.Request; long contentLength = request.ContentLength; // send the request body bytes to server if (contentLength > 0 && hasMulipartEventSubscribers && request.IsMultipartFormData) { var reader = getStreamReader(true); string boundary = HttpHelper.GetBoundaryFromContentType(request.ContentType); using (var copyStream = new CopyStream(reader, writer, bufferPool, bufferSize)) { while (contentLength > copyStream.ReadBytes) { long read = await readUntilBoundaryAsync(copyStream, contentLength, boundary, cancellationToken); if (read == 0) { break; } if (contentLength > copyStream.ReadBytes) { var headers = new HeaderCollection(); await HeaderParser.ReadHeaders(copyStream, headers, cancellationToken); OnMultipartRequestPartSent(boundary, headers); } } await copyStream.FlushAsync(cancellationToken); } } else { await copyBodyAsync(true, false, writer, transformation, OnDataSent, cancellationToken); } }
protected FileInfo CopyFolder(string parentId, FileInfo fileInfo) { try { FileInfo folder = CreateFolder(parentId, fileInfo); FilesProcessed++; foreach (FileInfo childInfo in fileInfo.Files) { if (IsCancellationRequested) { throw new Exception("Process cancelled by user."); } if (childInfo.IsFolder) { CopyFolder(folder.Id, childInfo); } else { var copyStream = new CopyStream(); copyStream.Init(folder.Id, childInfo); copyStream.Visible = false; _DriveService.CopyFile(copyStream); while (!copyStream.Processed) { if (IsCancellationRequested) { copyStream.Cancel(); } System.Threading.Thread.Sleep(250); } if (IsCancellationRequested) { throw new Exception("Process cancelled by user."); } if (!copyStream.Completed) { throw new Exception("Could not create new folder"); } FilesProcessed++; } } return folder; } catch (Exception exception) { Log.Error(exception); return null; } }
protected FileInfo CopyFolder(string parentId, FileInfo fileInfo) { try { FileInfo folder = CreateFolder(parentId, fileInfo); FilesProcessed++; foreach (FileInfo childInfo in fileInfo.Files) { if (IsCancellationRequested) { throw new Exception("Process cancelled by user."); } if (childInfo.IsFolder) { CopyFolder(folder.Id, childInfo); } else { var copyStream = new CopyStream(); copyStream.Init(folder.Id, childInfo); copyStream.Visible = false; _DriveService.CopyFile(copyStream); while (!copyStream.Processed) { if (IsCancellationRequested) { copyStream.Cancel(); } System.Threading.Thread.Sleep(250); } if (IsCancellationRequested) { throw new Exception("Process cancelled by user."); } if (!copyStream.Completed) { throw new Exception("Could not create new folder"); } FilesProcessed++; } } return(folder); } catch (Exception exception) { Log.Error(exception); return(null); } }
public static async ValueTask ProcessClient(HttpClientHolder holder, HttpInitialRequest request) { var handler = HttpHandleStore.Check(request.Path); if (handler == null) { request.Path = Path.Combine(Directory.GetCurrentDirectory(), HttpConstant.RootDirectory, request.Path); if (!File.Exists(request.Path)) { await holder.SafeWriteAsync(HttpErrorResponses.Instance.NotFoundResponse); return; } } else { handler.Invoked?.Invoke(holder); return; } var mime = MimeProcessor.Interpret(request.Path); if (mime == null) { await holder.SafeWriteAsync(HttpErrorResponses.Instance.NotImplementedResponse); return; } var fileInfo = new FileInfo(request.Path); holder.Client.SendBufferSize = HttpConstant.FileBufferSize; var asyncFs = fileInfo.Length > 1024 * 1024; Stream fs; if (Cfg.EnableHttpCache && !Cfg.HttpCacheExclude.Contains(request.Path)) { var(stat, array, length) = HttpServerFileCache.TryGet(request.Path); if (stat) { Trace.Assert(array != null, "Http cache null L58/Client.Processor!"); fs = new MemoryStream(array, 0, length.Value); asyncFs = false; } else { var(success, bytes, stream) = await HttpServerFileCache.TryCache(request.Path, asyncFs); if (success) { fs = new MemoryStream(bytes, 0, (int)fileInfo.Length); asyncFs = false; } else { fs = stream; } } } else { fs = new FileStream(request.Path, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, useAsync: asyncFs); } await using (fs) { if (request.Ranges == null || request.Ranges.Count == 0) { using var header = new HttpResponseHeaders(fileInfo.Length, ResponseStatusCode.Ok200, new IResponseField[] { new FieldServer(HttpConstant.ServerName), new FieldContentType(mime), new FieldAcceptRanges(HttpConstant.AcceptRanges), }, request.HttpVersion); var headerData = header.Compile(); if (!await holder.SafeWriteAsync(headerData.Item1, headerData.Item2)) { return; } if (request.Method == HttpInitialRequestMethod.HEAD) { return; } await CopyStream(fileInfo, fs, holder, fileInfo.Length, asyncFs); return; } foreach (var range in request.Ranges) { switch (range.Method) { case HttpRangeRequestMethod.SliceFromToEnd: { // implemented, tested if (fs.Length < range.Range.From) { return; } using var header = new HttpResponseHeaders(fileInfo.Length, ResponseStatusCode.PartialContent206, new IResponseField[] { new FieldContentRange(true, range.Range.From, fileInfo.Length - 1, fileInfo.Length), new FieldServer(HttpConstant.ServerName), new FieldContentType(mime), new FieldAcceptRanges(HttpConstant.AcceptRanges), }, request.HttpVersion); var headerData = header.Compile(); if (!await holder.SafeWriteAsync(headerData.Item1, headerData.Item2)) { return; } if (request.Method == HttpInitialRequestMethod.HEAD) { return; } fs.Seek((long)range.Range.From !, SeekOrigin.Begin); await CopyStream(fileInfo, fs, holder, (int)(fs.Length - range.Range.From), asyncFs); return; } case HttpRangeRequestMethod.SendAll: { // implemented, tested using var header = new HttpResponseHeaders(fileInfo.Length, ResponseStatusCode.PartialContent206, new IResponseField[] { new FieldContentRange(true, 0, fileInfo.Length - 1, fileInfo.Length), new FieldServer(HttpConstant.ServerName), new FieldContentType(mime), new FieldAcceptRanges(HttpConstant.AcceptRanges), }, request.HttpVersion); var headerData = header.Compile(); if (!await holder.SafeWriteAsync(headerData.Item1, headerData.Item2)) { return; } if (request.Method == HttpInitialRequestMethod.HEAD) { return; } await CopyStream(fileInfo, fs, holder, (int)fs.Length, asyncFs); return; } case HttpRangeRequestMethod.SliceFromTo: { if (fs.Length < range.Range.From || fs.Length < range.Range.To) { // attacker. return; } using var header = new HttpResponseHeaders(fileInfo.Length, ResponseStatusCode.PartialContent206, new IResponseField[] { new FieldContentRange(true, range.Range.From, range.Range.To, fileInfo.Length), new FieldServer(HttpConstant.ServerName), new FieldContentType(mime), new FieldAcceptRanges(HttpConstant.AcceptRanges), }, request.HttpVersion); var headerData = header.Compile(); if (!await holder.SafeWriteAsync(headerData.Item1, headerData.Item2)) { return; } if (request.Method == HttpInitialRequestMethod.HEAD) { return; } fs.Seek((int)range.Range.From, SeekOrigin.Begin); await CopyStream(fileInfo, fs, holder, (long)(range.Range.To - range.Range.From) !, asyncFs); return; } case HttpRangeRequestMethod.SliceFromStartTo: { if (fs.Length < range.Range.To) { // attacker. return; } using var header = new HttpResponseHeaders(fileInfo.Length, ResponseStatusCode.PartialContent206, new IResponseField[] { new FieldContentRange(true, 0, range.Range.To, fileInfo.Length), new FieldServer(HttpConstant.ServerName), new FieldContentType(mime), new FieldAcceptRanges(HttpConstant.AcceptRanges), }, request.HttpVersion); var headerData = header.Compile(); if (!await holder.SafeWriteAsync(headerData.Item1, headerData.Item2) || range.Range.To == null) { return; } if (request.Method == HttpInitialRequestMethod.HEAD) { return; } await CopyStream(fileInfo, fs, holder, (long)range.Range.To, asyncFs); return; } default: return; // ?? } } } }