private bool ValidateRequest(HttpContext context, out string fileKey, out ClientDependencyType type, out int version)
        {
            if (string.IsNullOrEmpty(context.Request.PathInfo))
            {
                var decodedUrl = HttpUtility.HtmlDecode(context.Request.Url.OriginalString);
                var query      = decodedUrl.Split(new char[] { '?' });
                if (query.Length < 2)
                {
                    throw new ArgumentException("No query string found in request");
                }
                var queryStrings = HttpUtility.ParseQueryString(query[1]);

                // querystring format
                fileKey = queryStrings["s"];
                var clientDepdendencyVersion = queryStrings["cdv"].TrimEnd('/');

                if (!string.IsNullOrEmpty(clientDepdendencyVersion) && int.TryParse(clientDepdendencyVersion, out version))
                {
                    try
                    {
                        type = (ClientDependencyType)Enum.Parse(typeof(ClientDependencyType), queryStrings["t"], true);
                        return(true);
                    }
                    catch
                    {
                        type    = default(ClientDependencyType);
                        version = default(int);
                        return(false);
                    }
                }
                else
                {
                    type    = default(ClientDependencyType);
                    version = default(int);
                    return(false);
                }
            }
            else
            {
                //get path to parse
                var path       = context.Request.PathInfo.TrimStart('/');
                var pathFormat = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.PathBasedUrlFormat;
                //parse using the parser
                if (PathBasedUrlFormatter.Parse(pathFormat, path, out fileKey, out type, out version))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
        }
Beispiel #2
0
        public void PathBasedUrlFormat_Parse_3()
        {
            string fileKey;
            int    version;
            ClientDependencyType type;
            var output = PathBasedUrlFormatter.Parse("{dependencyId}|@#{version}$%^{type}", "123456789|@#1234$%^css", out fileKey, out type, out version);

            Assert.AreEqual(true, output);
            Assert.AreEqual("123456789", fileKey);
            Assert.AreEqual(1234, version);
            Assert.AreEqual(ClientDependencyType.Css, type);
        }
Beispiel #3
0
        public void PathBasedUrlFormat_Parse_1()
        {
            string fileKey;
            int    version;
            ClientDependencyType type;
            var output = PathBasedUrlFormatter.Parse("{dependencyId}.{version}.{type}", "123456789.10.js", out fileKey, out type, out version);

            Assert.AreEqual(true, output);
            Assert.AreEqual("123456789", fileKey);
            Assert.AreEqual(10, version);
            Assert.AreEqual(ClientDependencyType.Javascript, type);
        }
Beispiel #4
0
        void IHttpHandler.ProcessRequest(HttpContext context)
        {
            var contextBase = new HttpContextWrapper(context);

            ClientDependencyType type;
            string fileKey;
            int    version = 0;

            if (string.IsNullOrEmpty(context.Request.PathInfo))
            {
                var decodedUrl = HttpUtility.HtmlDecode(context.Request.Url.OriginalString);
                var query      = decodedUrl.Split(new char[] { '?' });
                if (query.Length < 2)
                {
                    throw new ArgumentException("No query string found in request");
                }
                var queryStrings = HttpUtility.ParseQueryString(query[1]);

                // querystring format
                fileKey = queryStrings["s"];
                if (!string.IsNullOrEmpty(queryStrings["cdv"]) && !Int32.TryParse(queryStrings["cdv"], out version))
                {
                    throw new ArgumentException("Could not parse the version in the request");
                }
                try
                {
                    type = (ClientDependencyType)Enum.Parse(typeof(ClientDependencyType), queryStrings["t"], true);
                }
                catch
                {
                    throw new ArgumentException("Could not parse the type set in the request");
                }
            }
            else
            {
                //get path to parse
                var path       = context.Request.PathInfo.TrimStart('/');
                var pathFormat = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.PathBasedUrlFormat;
                //parse using the parser
                if (!PathBasedUrlFormatter.Parse(pathFormat, path, out fileKey, out type, out version))
                {
                    throw new FormatException("Could not parse the URL path: " + path + " with the format specified: " + pathFormat);
                }
            }

            fileKey = context.Server.UrlDecode(fileKey);

            if (string.IsNullOrEmpty(fileKey))
            {
                throw new ArgumentException("Must specify a fileset in the request");
            }

            // don't process if the version doesn't match - this would be nice to do but people will get errors if
            // their html pages are cached and are referencing an old version
            //if (version != ClientDependencySettings.Instance.Version)
            //    throw new ArgumentException("Configured version does not match request");

            byte[] outputBytes = null;

            //create the webforms page to perform the server side output cache, ensure
            // the parameters are the same that we are going to use when setting our own custom
            // caching parameters. Unfortunately server side output cache is tied so directly to
            // webforms this seems to be the only way to to this.
            var page = new OutputCachedPage(new OutputCacheParameters
            {
                Duration              = Convert.ToInt32(TimeSpan.FromDays(10).TotalSeconds),
                Enabled               = true,
                VaryByParam           = "t;s;cdv",
                VaryByContentEncoding = "gzip;deflate",
                Location              = OutputCacheLocation.Any
            });

            //retry up to 5 times... this is only here due to a bug found in another website that was returning a blank
            //result. To date, it can't be replicated in VS, but we'll leave it here for error handling support... can't hurt
            for (int i = 0; i < 5; i++)
            {
                outputBytes = ProcessRequestInternal(contextBase, fileKey, type, version, outputBytes, page);
                if (outputBytes != null && outputBytes.Length > 0)
                {
                    break;
                }

                ClientDependencySettings.Instance.Logger.Error(string.Format("No bytes were returned, this is attempt {0}. Fileset: {1}, Type: {2}, Version: {3}", i, fileKey, type, version), null);
            }

            if (outputBytes == null || outputBytes.Length == 0)
            {
                ClientDependencySettings.Instance.Logger.Fatal(string.Format("No bytes were returned after 5 attempts. Fileset: {0}, Type: {1}, Version: {2}", fileKey, type, version), null);
                List <CompositeFileDefinition> fDefs;
                outputBytes = GetCombinedFiles(contextBase, fileKey, type, out fDefs);
            }

            context.Response.ContentType = type == ClientDependencyType.Javascript ? "application/x-javascript" : "text/css";
            context.Response.OutputStream.Write(outputBytes, 0, outputBytes.Length);

            //dispose the webforms page used to do ensure server side output cache
            page.Dispose();
        }
        void IHttpHandler.ProcessRequest(HttpContext context)
        {
            var contextBase = new HttpContextWrapper(context);

            ClientDependencyType type;
            string fileKey;
            int    version = 0;

            if (string.IsNullOrEmpty(context.Request.PathInfo))
            {
                // querystring format
                fileKey = context.Request["s"];
                if (!string.IsNullOrEmpty(context.Request["cdv"]) && !Int32.TryParse(context.Request["cdv"], out version))
                {
                    throw new ArgumentException("Could not parse the version in the request");
                }
                try
                {
                    type = (ClientDependencyType)Enum.Parse(typeof(ClientDependencyType), context.Request["t"], true);
                }
                catch
                {
                    throw new ArgumentException("Could not parse the type set in the request");
                }
            }
            else
            {
                //get path to parse
                var path       = context.Request.PathInfo.TrimStart('/');
                var pathFormat = ClientDependencySettings.Instance.DefaultCompositeFileProcessingProvider.PathBasedUrlFormat;
                //parse using the parser
                if (!PathBasedUrlFormatter.Parse(pathFormat, path, out fileKey, out type, out version))
                {
                    throw new FormatException("Could not parse the URL path: " + path + " with the format specified: " + pathFormat);
                }
            }

            fileKey = context.Server.UrlDecode(fileKey);

            if (string.IsNullOrEmpty(fileKey))
            {
                throw new ArgumentException("Must specify a fileset in the request");
            }

            byte[] outputBytes = null;

            //retry up to 5 times... this is only here due to a bug found in another website that was returning a blank
            //result. To date, it can't be replicated in VS, but we'll leave it here for error handling support... can't hurt
            for (int i = 0; i < 5; i++)
            {
                outputBytes = ProcessRequestInternal(contextBase, fileKey, type, version, outputBytes);
                if (outputBytes != null && outputBytes.Length > 0)
                {
                    break;
                }

                ClientDependencySettings.Instance.Logger.Error(string.Format("No bytes were returned, this is attempt {0}. Fileset: {1}, Type: {2}, Version: {3}", i, fileKey, type, version), null);
            }

            if (outputBytes == null || outputBytes.Length == 0)
            {
                ClientDependencySettings.Instance.Logger.Fatal(string.Format("No bytes were returned after 5 attempts. Fileset: {0}, Type: {1}, Version: {2}", fileKey, type, version), null);
                List <CompositeFileDefinition> fDefs;
                outputBytes = GetCombinedFiles(contextBase, fileKey, type, out fDefs);
            }

            context.Response.ContentType = type == ClientDependencyType.Javascript ? "application/x-javascript" : "text/css";
            context.Response.OutputStream.Write(outputBytes, 0, outputBytes.Length);
        }