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); } } }
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); }
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); }
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); }