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);
        }
예제 #3
0
        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();
                }
            }
        }