public async Task ElementStreamer_locates_a_base64_target() { var documentHeader = "{\"document\" : \""; var documentTail = "\"}"; var json = $"{documentHeader}{Constants.TestMessageB64}{documentTail}"; var TestStream = new MemoryStream(Encoding.ASCII.GetBytes(json)); elements.Add("$.document", new Base64StreamWriter(new MemoryStream())); testStreamer = new JsonElementStreamer(TestStream, outStream, elements); await testStreamer.Next(); Assert.AreEqual(Enums.StreamerStatus.StartOfData, testStreamer.Status); await testStreamer.Next(); Assert.AreEqual(Enums.StreamerStatus.EndOfData, testStreamer.Status); Assert.IsTrue(elements["$.document"].OutStream.Length > 0); elements["$.document"].OutStream.Position = 0; var elementStreamContent = new StreamReader(elements["$.document"].OutStream).ReadToEnd(); await testStreamer.Next(); // check that the content contains the document Assert.AreEqual(Enums.StreamerStatus.Complete, testStreamer.Status); Assert.IsTrue(outStream.Length > 0); outStream.Position = 0; var outstreamContent = new StreamReader(outStream).ReadToEnd(); // Finally check the content Assert.AreEqual($"{documentHeader}{documentTail}", outstreamContent); Assert.AreEqual(Constants.TestMessage, elementStreamContent); }
private void ConfigureJsonFileWriter() { // 1. Identify the elements, and their types. var elements = new StreamedElements(); // I want to be able to intercept a Base64 encoded element and string property elements.Add(Constants.DocumentJsonPath, new Base64ToTempFileWriter()); elements.Add(Constants.FilenameJsonPath, new StringValueStreamWriter()); // Specify when to use this Context var jsonEndpoints = new List <string>() { "/api/document/upload" }; var jsonContentTypes = new List <string>() { "application/json", "application/json;charset=utf-8" }; // Now plug in a Element Streamer. var elementStreamer = new JsonElementStreamer(elements); var jsonRequestContext = new ElementStreamingRequestContext(jsonEndpoints, jsonContentTypes, elements, elementStreamer); // Finally add what we new want to do when we receive data (use a lambda or specific funciton). jsonRequestContext.OnElementStarting = s => true; // do nothing for starting jsonRequestContext.OnElementCompleted = s => { var handled = false; var docElement = s.GetElement(Constants.DocumentJsonPath); if (docElement != null && s.Streamer.ElementPath == Constants.DocumentJsonPath && docElement.IsComplete) { //Add a new context element indicating the size of the stream. var fileSize = docElement.OutStream.Length; var tmpFileName = docElement.TypedValue.AsString(); if (fileSize > 0) // check for the null case { var sizeElement = new DynamicValueStreamWriter(docElement.OutStream.Length.ToString()); s.Elements.Add(Constants.ByteSizeJsonPath, sizeElement); // substitute the original base64 code with the filename: var newFilenameElement = new DynamicValueStreamWriter(tmpFileName); s.Elements.Add(Constants.TempFileJsonPath, newFilenameElement); //warning: this will write synchronously s.Streamer.WriteAlternateContent(tmpFileName); // and now get rid of that streamer - as we now have a file reference. s.Elements.DiscardElement(Constants.DocumentJsonPath); } else { docElement.Ignore = true; docElement.OutStream.Dispose(); } // was this a file we previously decided to discard? if (docElement.Ignore) { if (File.Exists(tmpFileName)) { File.Delete(tmpFileName); } } handled = true; } else { // Check for unwanted file types we need to delete or block. var fnameElement = s.GetElement(Constants.FilenameJsonPath); var newFilenameElement = s.GetElement(Constants.TempFileJsonPath); if (s.Streamer.ElementPath == Constants.FilenameJsonPath && fnameElement.IsComplete) { var fname = fnameElement.TypedValue.AsString(); var extn = Path.GetExtension(fname); var blockedTypes = new List <string>() { ".exe", ".svg", ".dll", ".bat", ".com", ".sh", ".ps1" }; var blockFile = blockedTypes.Any(t => t.ToLower() == extn); if (docElement != null) { // encounterd FileName first - so we can block the file from being written docElement.Ignore = blockFile; } if (newFilenameElement != null) { var tmpFileName = newFilenameElement.TypedValue.AsString(); // we have already written it, delete it now. if (File.Exists(tmpFileName)) { File.Delete(tmpFileName); } } handled = true; } } return(handled); }; this.ElementStreamingRequestContexts.Add(jsonRequestContext); }
public async Task All_Paths_are_detected_correctly() { using (var TestStream = new MemoryStream(Encoding.ASCII.GetBytes(Constants.TestJSON))) { elements.Add("$.dummy", new Base64StreamWriter(new MemoryStream())); try { testStreamer = new JsonElementStreamer(TestStream, outStream, elements); testStreamer.AlwaysStopOnNextData = true; foreach (var p in Constants.JsonPaths) { await testStreamer.Next(); Assert.AreEqual(p, testStreamer.JsonPath, $"Faulted at {p} with {testStreamer.JsonPath}"); Console.WriteLine(p); } } finally { elements["$.dummy"].OutStream.Dispose(); } } }