HttpHandler causing in "The remote host closed the connection" error

2

I have implemented an HttpHandler for js files. The work of this HttpHandler is to localize the contents of js files. So the handler picks the contents of js files, localize them and writes to the response object. But the problem is that the handler is resulting in "The remote host closed the connection" when it is used for long files. Following is the code for HttpHandler

   using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.IO;
    using System.Reflection;
    using System.Text.RegularExpressions;
    using System.Threading;
    using System.Web;
    using System.Web.SessionState;
    using System.Xml.Linq;

    namespace ProjectLocalization
    {
        /// <summary>
        /// HTTP Handler to handle .js file localized resources by replacing Resources tag
        /// </summary>
        public class JSFileResourceHandler : IHttpHandler, IRequiresSessionState

        {
        // Regex pattern to extract the resource place holders.
        private const string RESOURCEPATTERN = @"<\x25{1}\x24{1}\s*Resources\s*:\s*(?<declaration>\w+\s*,\s*\w+)\s*%>";

        //Regex pattern to extract resource location settings.
        private const string SETTINGSPATTERN = @"<resourcesettings>(?>.|\n)+?resourceSettings>";

        //Caches the default culture set when the handler got instantiated.
        private CultureInfo defaultCulture;

        public delegate CultureInfo OnApplyCulture();
        public static event OnApplyCulture ApplyCulture;

        // Initializes a new instance of the class.        
        public JSFileResourceHandler()
        {
            defaultCulture = Thread.CurrentThread.CurrentCulture;
        }




        // Gets a value indicating whether another request can use 
        // the True if the instance is reusable; otherwise, false.
        public bool IsReusable
        {
            get { return true; }
        }

        // Enables processing of HTTP Web requests by a custom HttpHandler
        // that implements the interface.
        // HttpContext: its object that provides references to the intrinsic server objects (for example, Request, 
        // Response, Session, and Server) used to service HTTP requests.
        public void ProcessRequest(HttpContext context)
        {
            context.Response.Buffer = false;

            // Retrieve culture information from session
            if (ApplyCulture != null)
            {
                //Call ApplyCulture(delegate), is ApplyCutlture Return NULL then default culture will be set.
                CultureInfo culture = ApplyCulture() ?? defaultCulture;
                if (culture != null)
                {
                    // Set culture to current thread
                    Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(culture.Name);
                    Thread.CurrentThread.CurrentUICulture = culture;
                }
            }
            string physicalFilePath = context.Request.PhysicalPath;
            string fileContent = string.Empty;
            string convertedFile = string.Empty;

            // Determine whether file exists
            if (File.Exists(physicalFilePath))
            {
                // Read content from file
                using (StreamReader streamReader = File.OpenText(physicalFilePath))
                {
                    fileContent = streamReader.ReadToEnd();
                    if (!string.IsNullOrEmpty(fileContent))
                    {
                        // Load resource location types
                        //Dictionary<string, System.Type> locationTypes = GetResourceLocationTypes(fileContent);
                        Boolean IsLocalized = IsLocalizationImplemented(fileContent);
                        // Find and replace resource place holders
                        convertedFile = IsLocalized ? ReplaceResourcePlaceholders(fileContent) : fileContent;//, locationTypes);
                    }
                }
            }
            context.Response.ContentType = "application/javascript";
            context.Response.Output.Write(convertedFile);
            context.Response.Flush();
        }


        private static bool IsLocalizationImplemented(string strFileContent)
        {
            try
            {
                bool IsLocalize = false;
                Match settingsMatch = Regex.Match(strFileContent, SETTINGSPATTERN, RegexOptions.IgnoreCase);
                while (settingsMatch.Success)
                {
                    string Value = settingsMatch.Groups[0].Value.Replace("///", String.Empty).Replace("//", String.Empty);
                    XElement Settings = XElement.Parse(Value);

                    //Load Value that it is localized or not.
                    if (Settings.Element("Resource").Attribute("IsLocalize") != null)
                    {
                        String strIsLocalized = Settings.Element("Resource").Attribute("IsLocalize").Value;
                        settingsMatch = settingsMatch.NextMatch();
                        if (strIsLocalized.ToUpper() == @"TRUE") IsLocalize = true;
                    }
                }
                return IsLocalize;
            }
            catch
            {
                return false;
            }
        }


        //Replaces the resource placeholders.        
        //fileContent:Content of the file
        //return:File content with localized strings
        private static string ReplaceResourcePlaceholders(string fileContent)
        {
            string outputString = fileContent;
            Match resourceMatch = Regex.Match(fileContent, RESOURCEPATTERN);

            while (resourceMatch.Success)
            {
                // Determine whether a valid match was found
                if (resourceMatch.Groups["declaration"] != null)
                {
                    // Extract resource arguments -> always two
                    // arguments expected: 1. resource location name, 2. resource name
                    string[] arguments =
                      resourceMatch.Groups["declaration"].Value.Split(',');

                    if (arguments.Length < 2)
                    {
                        throw new ArgumentException("Resource declaration");
                    }

                    string resourceLocationName = arguments[0].Trim();
                    string resourceName = arguments[1].Trim();

                    // Load resource string
                    string localizedValue = "";
                    try
                    {
                        localizedValue = Convert.ToString(HttpContext.GetGlobalResourceObject(resourceLocationName, resourceName));
                        localizedValue = localizedValue.Replace("\\'", "~");
                        localizedValue = localizedValue.Replace("'", "~");
                        localizedValue = localizedValue.Replace("~", "\\'");
                    }
                    catch
                    {
                        localizedValue = "ERROR WHILE LOCALIZATION!!!";
                    }
                    // Replace place holder
                    outputString = outputString.Replace(resourceMatch.Groups[0].Value, localizedValue);
                }

                // Find next regex match
                resourceMatch = resourceMatch.NextMatch();
            }



return outputString;
        }
    }
}

I think the error is caused by the following lines

context.Response.ContentType = "application/javascript";
context.Response.Output.Write(convertedFile);
context.Response.Flush();

The error comes like The remote host closed the connection. The error code is 0x80072746.

at System.Web.Hosting.ISAPIWorkerRequestInProcForIIS6.FlushCore(Byte[] status, Byte[] header, Int32 keepConnected, Int32 totalBodySize, Int32 numBodyFragments, IntPtr[] bodyFragments, Int32[] bodyFragmentLengths, Int32 doneWithSession, Int32 finalStatus, Boolean& async) at System.Web.Hosting.ISAPIWorkerRequest.FlushCachedResponse(Boolean isFinal) at System.Web.Hosting.ISAPIWorkerRequest.FlushResponse(Boolean finalFlush) at System.Web.HttpResponse.Flush(Boolean finalFlush) at System.Web.HttpResponse.Flush() at System.Web.HttpWriter.Write(String s) at ProjectLocalization.JSFileResourceHandler.ProcessRequest(HttpContext context) at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Can anyone suggest a solution.....

c#
asked on Stack Overflow Apr 13, 2010 by Mohammad Nadeem

1 Answer

0

Have you tried getting rid of the call to Flush()? That is the only part that seems suspicious to me.

answered on Stack Overflow Mar 9, 2011 by FMM

User contributions licensed under CC BY-SA 3.0