public void ScriptInjectionFilterStream_BecomesPassthroughOnTimeout()
        {
            // Arrange
            MockSocketAdapter serverSocket = new MockSocketAdapter();
            MockScriptInjectionFilterContext filterContext = new MockScriptInjectionFilterContext();

            ScriptInjectionFilterStream filterStream = CreateFilterStream(serverSocket, filterContext);

            byte[] bytesToSend = Encoding.UTF8.GetBytes("<html><head></head><body></body></html>");

            // Act I - Send some bytes
            Task writeTask = filterStream.WriteAsync(bytesToSend, 0, 20);

            // Assert
            TaskAssert.NotCompleted(writeTask, "Should be waiting for server to respond");

            // Act II - Wait for the request to time out
            System.Threading.Thread.Sleep(1100);

            // Assert
            TaskAssert.Completed(writeTask, "Write should complete when server fails to respond");
            Assert.True(serverSocket.IsClosed, "Should become passthrough");
            Assert.Equal("<html><head></head><", filterContext.GetResponseBody(Encoding.UTF8));
            AssertWithMessage.Equal(true, filterStream.ScriptInjectionTimedOut, "ScriptInjectionTimedOut");
        }
        internal Task HandlerMethod(byte[] buffer, int index, int count)
        {
            AssertWithMessage.Null(_handlerTcs, "More than one call to HandlerMethod is happening at the same time");

            TaskCompletionSource <object> handlerTcs = new TaskCompletionSource <object>();

            try
            {
                _response.Append(_encoding.GetString(buffer, index, count));

                if (Block)
                {
                    _handlerTcs = handlerTcs;
                }
                else
                {
                    handlerTcs.SetResult(null);
                }
            }
            catch (Exception ex)
            {
                handlerTcs.SetException(ex);
            }

            return(handlerTcs.Task);
        }
        public void RevolvingBuffers_Multithreaded()
        {
            // Arrange
            char[]        data       = "Hello, world!".ToArray();
            int           iterations = 10000;
            StringBuilder result     = new StringBuilder();

            string expected = String.Concat(Enumerable.Repeat("Hello, world!", iterations));

            RevolvingBuffers <char> buffers = new RevolvingBuffers <char>(2);

            Exception writingThreadException = null;
            Thread    writingThread          = new Thread(delegate()
            {
                try
                {
                    for (int i = 0; i < iterations; i++)
                    {
                        for (int i2 = 0; i2 < data.Length; i2++)
                        {
                            buffers.CopyDataToBuffer(data, i2, 1);
                        }
                    }
                }
                catch (Exception ex)
                {
                    writingThreadException = ex;
                }
            });

            Exception readingThreadException = null;
            Thread    readingThread          = new Thread(delegate()
            {
                try
                {
                    while (result.Length < data.Length * iterations)
                    {
                        result.Append(GetString(buffers.GetBufferedData()));
                    }
                }
                catch (Exception ex)
                {
                    readingThreadException = ex;
                }
            });

            // Act
            writingThread.Start();
            readingThread.Start();

            // Assert
            bool completed = readingThread.Join(millisecondsTimeout: 1000);

            AssertWithMessage.Null(writingThreadException, "Exception in writingThread: {0}", writingThreadException);
            AssertWithMessage.Null(readingThreadException, "Exception in readingThread: {0}", readingThreadException);
            Assert.True(completed, "Process did not complete.");

            AssertWithMessage.Equal(expected.Length, result.Length, "result.Length");
            Assert.Equal(expected, result.ToString());
        }
        public void ScriptInjectionFilterStream_ExceptionOnSubsequentWrite()
        {
            // Arrange
            MockSocketAdapter serverSocket = new MockSocketAdapter();

            serverSocket.SendString("HTTP/1.1 200 OK\r\n", Encoding.ASCII);

            MockScriptInjectionFilterContext filterContext = new MockScriptInjectionFilterContext();

            ScriptInjectionFilterStream filterStream = CreateFilterStream(serverSocket, filterContext);

            byte[] bytesToSend = Encoding.UTF8.GetBytes("<html><head></head><body></body></html>");

            // Act I - Write some bytes
            filterStream.Write(bytesToSend, 0, 20);

            // Assert
            Assert.Contains("<html><head></head><", serverSocket.SentContent);
            AssertWithMessage.Equal(0, filterContext.GetResponseBody(Encoding.UTF8).Length, "No content should be sent to the response yet.");
            Assert.False(serverSocket.IsClosed, "Server connection should not have been closed.");

            // Act II - Attempt to write more bytes
            serverSocket.ThrowExceptionOnNextSendAsync();


            Task result = filterStream.WriteAsync(bytesToSend, 20, bytesToSend.Length - 20);

            // Assert
            TaskAssert.Faulted(result, "Exception should have been re-thrown");
            Assert.Equal("SendAsync after ThrowExceptionOnNextSendAsync was called.", result.Exception.InnerException.Message);
        }
        public void RevolvingBuffers_InlineAsyncDisposalInteraction()
        {
            // Arrange
            char[] data = "Hello, world!".ToArray();

            RevolvingBuffers <char> buffers = new RevolvingBuffers <char>(20);

            // Reader waits for a chunk of data
            Task read1 = buffers.GetBufferedDataAsync();

            Assert.False(read1.IsCompleted, "read1.IsCompleted");

            // Writer writes some data
            buffers.CopyDataToBuffer(data, 0, data.Length);
            Assert.True(read1.IsCompleted, "read1.IsCompleted");

            // Writer is done writing data
            Task wait = buffers.WaitForBufferEmptyAsync();

            Assert.False(wait.IsCompleted, "All data isn't finished until the reader releases the last buffer");

            // Writer will dispose as soon as reading is complete
            wait.ContinueWith(task =>
            {
                buffers.Dispose();
            }, TaskContinuationOptions.ExecuteSynchronously);

            // Reader looks for more data
            Task <ArraySegment <char> > read2 = buffers.GetBufferedDataAsync();

            Assert.True(wait.IsCompleted, "Wait should be completed now");
            Assert.True(read2.IsCompleted, "Read should also return because buffers were disposed immediately");
            AssertWithMessage.Equal("", GetString(read2.Result), "read2.Result");
        }
        void IHttpSocketAdapter.SetResponseHandler(ResponseHandler handler)
        {
            AssertWithMessage.Null(_responseHandler, "SetResponseHandler was called more than once.");
            AssertWithMessage.NotNull(handler, "SetResponseHandler was called with a null handler.");

            _responseHandler = handler;
        }
Пример #7
0
        public void HttpSocketAdapter_GetResponseHeader_SocketException()
        {
            // Arrange
            MockSocketAdapter serverSocket = new MockSocketAdapter();

            serverSocket.SendString("HTTP/1.1 200 OK\r\n", Encoding.ASCII);

            HttpSocketAdapter clientSocket = new HttpSocketAdapter("GET", new Uri("http://bing.com"), serverSocket);

            Task <int>    responseCodeTask     = clientSocket.GetResponseStatusCode();
            Task <string> responseHeaderTask   = clientSocket.GetResponseHeader("test header");
            Task          responseCompleteTask = clientSocket.WaitForResponseComplete();

            TaskAssert.Completed(responseCodeTask, "GetResponseStatusCode should have failed.");
            AssertWithMessage.Equal(200, responseCodeTask.Result, "Wrong result for GetResponseStatusCode");

            // Act
            serverSocket.ThrowExceptionFromReceiveAsync();

            // Assert
            TaskAssert.Faulted(responseHeaderTask, "GetResponseHeader should have failed.");
            TaskAssert.Faulted(responseCompleteTask, "WaitForResponseComplete should have failed.");

            AssertWithMessage.Equal("An error occurred.", responseHeaderTask.Exception.InnerException.Message, "Wrong exception for GetResponseHeader");
            AssertWithMessage.Equal("An error occurred.", responseCompleteTask.Exception.InnerException.Message, "Wrong exception for WaitForResponseComplete");
        }
        public void SendResponseBodyContent(string content, Encoding encoding)
        {
            AssertWithMessage.NotNull(_responseHandler, "No response handler was set.");

            byte[] bytes = encoding.GetBytes(content);

            _responseHandler.Invoke(bytes, 0, bytes.Length);
        }
        Task <int> ISocketAdapter.ReceiveAsync(byte[] buffer, int offset, int count)
        {
            Assert.False(_disposed, "ReceiveAsync was called on a socket that has been disposed.");

            AssertWithMessage.Null(_receiveTcs, "Multiple calls to ReceiveAsync are occuring at the same time");

            _receiveTcs     = new TaskCompletionSource <int>();
            _receiverBuffer = new ArraySegment <byte>(buffer, offset, count);

            Task <int> resultTask = _receiveTcs.Task;

            PushBytesToReceiver();

            return(resultTask);
        }
        public void ScriptInjectionFilterStream_CompleteFilterProcess()
        {
            // Arrange
            MockSocketAdapter serverSocket = new MockSocketAdapter();
            MockScriptInjectionFilterContext filterContext = new MockScriptInjectionFilterContext();

            ScriptInjectionFilterStream filterStream = CreateFilterStream(serverSocket, filterContext);

            byte[] bytesToSend = Encoding.UTF8.GetBytes("<html><head></head><body></body></html>");

            // Act I - Write some bytes
            Task writeTask = filterStream.WriteAsync(bytesToSend, 0, 20);

            // Assert
            TaskAssert.NotCompleted(writeTask, "Write task should not complete until a successful response comes from the server.");

            // Act Ia - Response from the server
            serverSocket.SendString("HTTP/1.1 200 OK\r\n", Encoding.ASCII);

            // Assert
            TaskAssert.Completed(writeTask, "The write task should complete after we receive the response line from the server.");
            Assert.Contains("<html><head></head><", serverSocket.SentContent);
            AssertWithMessage.Equal(0, filterContext.GetResponseBody(Encoding.UTF8).Length, "No content should be sent to the response yet.");
            Assert.False(serverSocket.IsClosed, "Server connection should not have been closed.");

            // Act II - Write some more bytes
            filterStream.Write(bytesToSend, 20, bytesToSend.Length - 20);

            // Assert
            Assert.Contains("body></body></html>", serverSocket.SentContent);
            AssertWithMessage.Equal(0, filterContext.GetResponseBody(Encoding.UTF8).Length, "No content should be sent to the response yet.");
            Assert.False(serverSocket.IsClosed, "Server connection should not have been closed.");

            // Act III - Wait for complete
            Task completeTask = filterStream.FlushAsync();

            // Assert
            TaskAssert.NotCompleted(completeTask, "Before response from server.");

            // Act IV - Send response from server
            serverSocket.SendString("Content-Length: 17\r\n\r\nXFiltered content", Encoding.ASCII);

            // Assert
            Assert.Equal("Filtered content", filterContext.GetResponseBody(Encoding.ASCII));
            TaskAssert.Completed(completeTask, "After response from server.");
            Assert.False(filterStream.ScriptInjectionTimedOut);
        }
        public void ScriptInjectionFilterStream_PassesCssDirectlyToOutput()
        {
            // Arrange
            MockSocketAdapter serverSocket = new MockSocketAdapter();
            MockScriptInjectionFilterContext filterContext = new MockScriptInjectionFilterContext();

            ScriptInjectionFilterStream filterStream = CreateFilterStream(serverSocket, filterContext);

            byte[] bytesToSend = Encoding.UTF8.GetBytes("body { font-weight: bold; }");

            // Act
            filterStream.Write(bytesToSend, 0, bytesToSend.Length);

            // Assert
            AssertWithMessage.Equal(0, serverSocket.SentContent.Length, "Non-HTML content shouldn't be sent to the filter.");
            Assert.True(serverSocket.IsClosed, "Connection to VS was not closed when non-HTML content was detected.");
            Assert.Equal("body { font-weight: bold; }", filterContext.GetResponseBody(Encoding.UTF8));
        }
        public void ScriptInjectionFilterStream_ChecksResponseContentType()
        {
            // Arrange
            MockSocketAdapter serverSocket = new MockSocketAdapter();

            serverSocket.SendString("HTTP/1.1 200 OK\r\n", Encoding.ASCII);

            MockScriptInjectionFilterContext filterContext = new MockScriptInjectionFilterContext(contentType: "text/javascript");

            ScriptInjectionFilterStream filterStream = CreateFilterStream(serverSocket, filterContext);

            byte[] bytesToSend = Encoding.UTF8.GetBytes("var myhtml = \"<html></html>\";");

            // Act
            filterStream.Write(bytesToSend, 0, bytesToSend.Length);

            // Assert
            AssertWithMessage.Equal(0, serverSocket.SentContent.Length, "Non-HTML content shouldn't be sent to the filter.");
            Assert.True(serverSocket.IsClosed, "Connection to VS was not closed when non-HTML content was detected.");
            Assert.Equal("var myhtml = \"<html></html>\";", filterContext.GetResponseBody(Encoding.UTF8));
        }
        public void ScriptInjectionFilterStream_PassesHtmlToFilter()
        {
            // Arrange
            MockSocketAdapter serverSocket = new MockSocketAdapter();

            serverSocket.SendString("HTTP/1.1 200 OK\r\n", Encoding.ASCII);

            MockScriptInjectionFilterContext filterContext = new MockScriptInjectionFilterContext();

            ScriptInjectionFilterStream filterStream = CreateFilterStream(serverSocket, filterContext);

            byte[] bytesToSend = Encoding.UTF8.GetBytes("<html><head></head><body></body></html>");

            // Act
            filterStream.Write(bytesToSend, 0, bytesToSend.Length);

            // Assert
            Assert.Contains("\r\nContent-Type: text/html\r\n", serverSocket.SentContent);
            Assert.Contains("<html><head></head><body></body></html>", serverSocket.SentContent);
            AssertWithMessage.Equal(0, filterContext.GetResponseBody(Encoding.UTF8).Length, "No content should be sent to the response yet.");
            Assert.False(serverSocket.IsClosed, "Server connection should not have been closed.");
        }
        public void RevolvingBuffers_ReusesAvailableBuffers()
        {
            // Arrange
            char[] data = "Hello, world!".ToArray();

            RevolvingBuffers <char> buffers = new RevolvingBuffers <char>(10);

            buffers.CopyDataToBuffer(data, 0, 6); // Write to buffer 1
            buffers.CopyDataToBuffer(data, 6, 6); // Write to buffer 2

            buffers.GetBufferedData();            // Read from buffer 1
            buffers.GetBufferedData();            // Read from buffer 2; buffer 1 is now available

            // Act
            buffers.CopyDataToBuffer(data, 7, 5); // Write to buffer 1

            // Assert
#if DEBUG
            AssertWithMessage.Equal(2, buffers.BufferCount, "BufferCount");
#endif
            Assert.Equal("world", GetString(buffers.GetBufferedData()));
        }