Gallatin.Core.Service.ProxyFilter.EvaluateResponseFilters C# (CSharp) Method

EvaluateResponseFilters() public method

public EvaluateResponseFilters ( IHttpResponse args, string connectionId, bool &isBodyRequired ) : byte[]
args IHttpResponse
connectionId string
isBodyRequired bool
return byte[]
        public byte[] EvaluateResponseFilters( IHttpResponse args, string connectionId, out bool isBodyRequired )
        {
            isBodyRequired = false;

            if (!_settings.FilteringEnabled.Value || ResponseFilters == null || ResponseFilters.Count() == 0)
            {
                return null;
            }

            lock (_whiteListedConnections)
            {
                if (_whiteListedConnections.Contains(connectionId))
                {
                    _whiteListedConnections.Remove(connectionId);
                    return null;
                }
            }

            string errorMessage = null;

            _callbackList.Clear();

            foreach (IResponseFilter filter in ResponseFilters.OrderBy(s => s.FilterSpeedType))
            {
                Func<IHttpResponse, string, byte[], byte[]> callback;
                string filterText = filter.EvaluateFilter(args, connectionId, out callback);

                if (!String.IsNullOrEmpty(filterText))
                {
                    // Fail fast
                    errorMessage = filterText;

                    // Don't bother with the callbacks. The response has been filtered without the HTTP body.
                    // These types of filters are preferable over filters that require the body.
                    _callbackList.Clear();
                    break;
                }

                if (callback != null)
                {
                    _callbackList.Add(callback);
                }
            }

            if (!String.IsNullOrEmpty(errorMessage))
            {
                string body = String.Format("<html><head><title>Gallatin Proxy - Response Filtered</title></head><body>{0}</body></html>",
                                                errorMessage);

                return Encoding.UTF8.GetBytes(
                    String.Format("HTTP/{0} 200 OK\r\nConnection: close\r\nContent length: {1}\r\nContent-Type: text/html\r\n\r\n{2}",
                                    args.Version,
                                    body.Length,
                                    body) );
            }

            // Clear the filters that require the HTTP body if there will be no body. Filters should
            // check this themselves. This is a catch-all. Without this, a bad filter could hang the proxy
            // by waiting for a body that will never arrive.
            if (!args.HasBody)
            {
                _callbackList.Clear();
            }
            else
            {
                isBodyRequired = true;
            }

            return null;
        }

Usage Example

        public void VerifyResponseFilterWithCallbackWithBody([Values(true, false)] bool filterEnabled)
        {
            bool delegateHasBeenCalled = false;

            byte[] body = Encoding.UTF8.GetBytes( "this is the body" );
            byte[] compressedBody = Compress( body );
            byte[] outBody = Encoding.UTF8.GetBytes( "this is the modified body" );

            Mock<IHttpHeaders> mockHeaders = new Mock<IHttpHeaders>();
            mockHeaders.Setup( s => s["transfer-encoding"] ).Returns( "chunked" );
            mockHeaders.Setup( s => s["content-encoding"] ).Returns( "gzip" );

            Mock<ICoreSettings> settings = new Mock<ICoreSettings>();
            settings.SetupGet(m => m.FilteringEnabled).Returns(filterEnabled);

            ProxyFilter filter = new ProxyFilter(settings.Object);
            List<IResponseFilter> filters = new List<IResponseFilter>();

            Mock<IHttpResponse> response = new Mock<IHttpResponse>();
            response.SetupAllProperties();
            response.SetupGet( s => s.HasBody ).Returns( true );
            response.SetupGet( s => s.Headers ).Returns( mockHeaders.Object );

            Mock<IResponseFilter> mockFilter = new Mock<IResponseFilter>();
            mockFilter.SetupGet( s => s.FilterSpeedType ).Returns( FilterSpeedType.Remote );
            Func<IHttpResponse, string, byte[], byte[]> outParm =
                ( r, c, i ) =>
                {
                    delegateHasBeenCalled = true;
                    Assert.That( r, Is.SameAs( response.Object ) );
                    Assert.That( c, Is.EqualTo( "connectionid" ) );
                    Assert.That( i, Is.EqualTo( body ), "This should be the uncompressed body" );
                    return outBody;
                };
            mockFilter.Setup( s => s.EvaluateFilter( response.Object, "connectionid", out outParm ) ).Returns( null as string );

            filters.Add( mockFilter.Object );
            filter.ResponseFilters = filters;

            bool isBodyNeeded;
            byte[] filterResponse = filter.EvaluateResponseFilters( response.Object, "connectionid", out isBodyNeeded );

            if (filterEnabled)
            {
                Assert.That(isBodyNeeded, Is.True);
                Assert.That(filterResponse, Is.Null);

                byte[] responseMessage = filter.EvaluateResponseFiltersWithBody(response.Object, "connectionid", compressedBody);

                Assert.That(responseMessage, Is.EqualTo(outBody));

                mockHeaders.Verify(s => s.RemoveKeyValue("transfer-encoding", "chunked"), Times.Once());
                mockHeaders.Verify(s => s.UpsertKeyValue("Content-Length", "25"), Times.Once());
                mockHeaders.Verify(s => s.RemoveKeyValue("content-encoding", "gzip"), Times.Once());
                mockHeaders.Verify(s => s.UpsertKeyValue("Content-Length", "16"),
                                    Times.Once(),
                                    "The header should have been updated with the uncompressed body size");

                Assert.That(delegateHasBeenCalled, Is.True);
            }
            else
            {
                Assert.That(isBodyNeeded, Is.False);
                Assert.That(filterResponse, Is.Null);

            }
        }
All Usage Examples Of Gallatin.Core.Service.ProxyFilter::EvaluateResponseFilters