private void CompressContent(HttpApplication httpApplication) { if (!httpApplication.Context.Items.Contains("__@fluorinehttpcompress")) { httpApplication.Context.Items.Add("__@fluorinehttpcompress", 1); HttpCompressSettings httpCompressSettings = FluorineConfiguration.Instance.HttpCompressSettings; if (((httpCompressSettings.HandleRequest != HandleRequest.None) && ((httpCompressSettings.HandleRequest != HandleRequest.Amf) || !(httpApplication.Request.ContentType != "application/x-amf"))) && (httpCompressSettings.CompressionLevel != CompressionLevels.None)) { string fileName = Path.GetFileName(httpApplication.Request.Path); if (!httpCompressSettings.IsExcludedPath(fileName) && ((httpApplication.Response.ContentType != null) && !httpCompressSettings.IsExcludedMimeType(httpApplication.Response.ContentType))) { httpApplication.Response.Cache.VaryByHeaders["Accept-Encoding"] = true; string str2 = httpApplication.Request.Headers["Accept-Encoding"]; if (str2 != null) { CompressingFilter compressStream = GetFilterForScheme(str2.Split(new char[] { ',' }), httpApplication.Response.Filter, httpCompressSettings); if (compressStream != null) { if (httpApplication.Request.ContentType == "application/x-amf") { httpApplication.Response.Filter = new ThresholdFilter(compressStream, httpApplication.Response.Filter, httpCompressSettings.Threshold); } else { httpApplication.Response.Filter = compressStream; } } } } } } }
/// <summary> /// Get ahold of a <see cref="CompressingFilter"/> for the given encoding scheme. /// If no encoding scheme can be found, it returns null. /// </summary> /// <remarks> /// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3 for details /// on how clients are supposed to construct the Accept-Encoding header. This /// implementation follows those rules, though we allow the server to override /// the preference given to different supported algorithms. I'm doing this as /// I would rather give the server control over the algorithm decision than /// the client. If the clients send up * as an accepted encoding with highest /// quality, we use the preferred algorithm as specified in the config file. /// </remarks> internal static CompressingFilter GetFilterForScheme(string[] schemes, Stream output, HttpCompressSettings prefs) { bool foundDeflate = false; bool foundGZip = false; bool foundStar = false; float deflateQuality = 0f; float gZipQuality = 0f; float starQuality = 0f; for (int i = 0; i < schemes.Length; i++) { string acceptEncodingValue = schemes[i].Trim().ToLower(); if (acceptEncodingValue.StartsWith("deflate")) { foundDeflate = true; float newDeflateQuality = GetQuality(acceptEncodingValue); if (deflateQuality < newDeflateQuality) { deflateQuality = newDeflateQuality; } } else if (acceptEncodingValue.StartsWith("gzip") || acceptEncodingValue.StartsWith("x-gzip")) { foundGZip = true; float newGZipQuality = GetQuality(acceptEncodingValue); if (gZipQuality < newGZipQuality) { gZipQuality = newGZipQuality; } } else if (acceptEncodingValue.StartsWith("*")) { foundStar = true; float newStarQuality = GetQuality(acceptEncodingValue); if (starQuality < newStarQuality) { starQuality = newStarQuality; } } } bool isAcceptableStar = foundStar && (starQuality > 0); bool isAcceptableDeflate = (foundDeflate && (deflateQuality > 0)) || (!foundDeflate && isAcceptableStar); bool isAcceptableGZip = (foundGZip && (gZipQuality > 0)) || (!foundGZip && isAcceptableStar); if (isAcceptableDeflate && !foundDeflate) { deflateQuality = starQuality; } if (isAcceptableGZip && !foundGZip) { gZipQuality = starQuality; } // Do they support any of our compression methods? if (!(isAcceptableDeflate || isAcceptableGZip || isAcceptableStar)) { return(null); } // If deflate is better according to client if (isAcceptableDeflate && (!isAcceptableGZip || (deflateQuality > gZipQuality))) { return(new DeflateFilter(output, prefs.CompressionLevel)); } // If gzip is better according to client if (isAcceptableGZip && (!isAcceptableDeflate || (deflateQuality < gZipQuality))) { return(new GZipFilter(output)); } // If we're here, the client either didn't have a preference or they don't support compression if (isAcceptableDeflate && (prefs.PreferredAlgorithm == Algorithms.Deflate || prefs.PreferredAlgorithm == Algorithms.Default)) { return(new DeflateFilter(output, prefs.CompressionLevel)); } if (isAcceptableGZip && prefs.PreferredAlgorithm == Algorithms.GZip) { return(new GZipFilter(output)); } if (isAcceptableDeflate || isAcceptableStar) { return(new DeflateFilter(output, prefs.CompressionLevel)); } if (isAcceptableGZip) { return(new GZipFilter(output)); } // return null. we couldn't find a filter. return(null); }
/// <summary> /// EventHandler that gets ahold of the current request context and attempts to compress the output. /// </summary> /// <param name="httpApplication">The <see cref="HttpApplication"/> that is firing this event.</param> public void CompressContent(HttpApplication httpApplication) { // Only do this if we haven't already attempted an install. This prevents PreSendRequestHeaders from // trying to add this item way to late. We only want the first run through to do anything. // also, we use the context to store whether or not we've attempted an add, as it's thread-safe and // scoped to the request. An instance of this module can service multiple requests at the same time, // so we cannot use a member variable. if (!httpApplication.Context.Items.Contains(FluorineHttpCompressKey)) { // Log the install attempt in the HttpContext. Must do this first as several IF statements below skip full processing of this method httpApplication.Context.Items.Add(FluorineHttpCompressKey, 1); // Get the config settings HttpCompressSettings settings = FluorineConfiguration.Instance.HttpCompressSettings; // Skip if no request can be handled if (settings.HandleRequest == HandleRequest.None) { return; } // Skip if only AMF is compressed and we do not have an AMF request if (settings.HandleRequest == HandleRequest.Amf && httpApplication.Request.ContentType != ContentType.AMF) { return; } // Skip if the CompressionLevel is set to 'None' if (settings.CompressionLevel == CompressionLevels.None) { return; } //string realPath = httpApplication.Request.Path.Remove(0, httpApplication.Request.ApplicationPath.Length+1); string realPath = Path.GetFileName(httpApplication.Request.Path); if (settings.IsExcludedPath(realPath)) { // Skip if the file path excludes compression return; } // Skip if the MimeType excludes compression if (httpApplication.Response.ContentType == null || settings.IsExcludedMimeType(httpApplication.Response.ContentType)) { return; } // Fix to handle caching appropriately, see http://www.pocketsoap.com/weblog/2003/07/1330.html // This header is added only when the request has the possibility of being compressed // i.e. it is not added when the request is excluded from compression by CompressionLevel, Path, or MimeType httpApplication.Response.Cache.VaryByHeaders["Accept-Encoding"] = true; // Grab an array of algorithm;q=x, algorith;q=x style values string acceptedTypes = httpApplication.Request.Headers["Accept-Encoding"]; // If we couldn't find the header, bail out if (acceptedTypes == null) { return; } // The actual types could be , delimited. split 'em out. string[] types = acceptedTypes.Split(','); CompressingFilter filter = GetFilterForScheme(types, httpApplication.Response.Filter, settings); // If we didn't find a filter, bail out if (filter == null) { return; } // If we get here, we found a viable filter. // Set the filter and change the Content-Encoding header to match so the client can decode the response if (httpApplication.Request.ContentType == ContentType.AMF) { httpApplication.Response.Filter = new ThresholdFilter(filter, httpApplication.Response.Filter, settings.Threshold); } else { httpApplication.Response.Filter = filter; } } }
/// <summary> /// Get ahold of a <see cref="CompressingFilter"/> for the given encoding scheme. /// If no encoding scheme can be found, it returns null. /// </summary> /// <remarks> /// See http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3 for details /// on how clients are supposed to construct the Accept-Encoding header. This /// implementation follows those rules, though we allow the server to override /// the preference given to different supported algorithms. I'm doing this as /// I would rather give the server control over the algorithm decision than /// the client. If the clients send up * as an accepted encoding with highest /// quality, we use the preferred algorithm as specified in the config file. /// </remarks> internal static CompressingFilter GetFilterForScheme(string[] schemes, Stream output, HttpCompressSettings prefs) { bool foundDeflate = false; bool foundGZip = false; bool foundStar = false; float deflateQuality = 0f; float gZipQuality = 0f; float starQuality = 0f; for (int i = 0; i<schemes.Length;i++) { string acceptEncodingValue = schemes[i].Trim().ToLower(); if (acceptEncodingValue.StartsWith("deflate")) { foundDeflate = true; float newDeflateQuality = GetQuality(acceptEncodingValue); if (deflateQuality < newDeflateQuality) deflateQuality = newDeflateQuality; } else if (acceptEncodingValue.StartsWith("gzip") || acceptEncodingValue.StartsWith("x-gzip")) { foundGZip = true; float newGZipQuality = GetQuality(acceptEncodingValue); if (gZipQuality < newGZipQuality) gZipQuality = newGZipQuality; } else if (acceptEncodingValue.StartsWith("*")) { foundStar = true; float newStarQuality = GetQuality(acceptEncodingValue); if (starQuality < newStarQuality) starQuality = newStarQuality; } } bool isAcceptableStar = foundStar && (starQuality > 0); bool isAcceptableDeflate = (foundDeflate && (deflateQuality > 0)) || (!foundDeflate && isAcceptableStar); bool isAcceptableGZip = (foundGZip && (gZipQuality > 0)) || (!foundGZip && isAcceptableStar); if (isAcceptableDeflate && !foundDeflate) deflateQuality = starQuality; if (isAcceptableGZip && !foundGZip) gZipQuality = starQuality; // Do they support any of our compression methods? if(!(isAcceptableDeflate || isAcceptableGZip || isAcceptableStar)) return null; // If deflate is better according to client if (isAcceptableDeflate && (!isAcceptableGZip || (deflateQuality > gZipQuality))) return new DeflateFilter(output, prefs.CompressionLevel); // If gzip is better according to client if (isAcceptableGZip && (!isAcceptableDeflate || (deflateQuality < gZipQuality))) return new GZipFilter(output); // If we're here, the client either didn't have a preference or they don't support compression if(isAcceptableDeflate && (prefs.PreferredAlgorithm == Algorithms.Deflate || prefs.PreferredAlgorithm == Algorithms.Default)) return new DeflateFilter(output, prefs.CompressionLevel); if(isAcceptableGZip && prefs.PreferredAlgorithm == Algorithms.GZip) return new GZipFilter(output); if(isAcceptableDeflate || isAcceptableStar) return new DeflateFilter(output, prefs.CompressionLevel); if(isAcceptableGZip) return new GZipFilter(output); // return null. we couldn't find a filter. return null; }
internal static CompressingFilter GetFilterForScheme(string[] schemes, Stream output, HttpCompressSettings prefs) { bool flag = false; bool flag2 = false; bool flag3 = false; float num = 0f; float num2 = 0f; float num3 = 0f; for (int i = 0; i < schemes.Length; i++) { string acceptEncodingValue = schemes[i].Trim().ToLower(); if (acceptEncodingValue.StartsWith("deflate")) { flag = true; float quality = GetQuality(acceptEncodingValue); if (num < quality) { num = quality; } } else if (acceptEncodingValue.StartsWith("gzip") || acceptEncodingValue.StartsWith("x-gzip")) { flag2 = true; float num6 = GetQuality(acceptEncodingValue); if (num2 < num6) { num2 = num6; } } else if (acceptEncodingValue.StartsWith("*")) { flag3 = true; float num7 = GetQuality(acceptEncodingValue); if (num3 < num7) { num3 = num7; } } } bool flag6 = flag3 && (num3 > 0f); bool flag4 = (flag && (num > 0f)) || (!flag && flag6); bool flag5 = (flag2 && (num2 > 0f)) || (!flag2 && flag6); if (!(!flag4 || flag)) { num = num3; } if (!(!flag5 || flag2)) { num2 = num3; } if ((flag4 || flag5) || flag6) { if (flag4 && (!flag5 || (num > num2))) { return(new DeflateFilter(output, prefs.CompressionLevel)); } if (flag5 && (!flag4 || (num < num2))) { return(new GZipFilter(output)); } if (flag4 && ((prefs.PreferredAlgorithm == Algorithms.Deflate) || (prefs.PreferredAlgorithm == Algorithms.Default))) { return(new DeflateFilter(output, prefs.CompressionLevel)); } if (flag5 && (prefs.PreferredAlgorithm == Algorithms.GZip)) { return(new GZipFilter(output)); } if (flag4 || flag6) { return(new DeflateFilter(output, prefs.CompressionLevel)); } if (flag5) { return(new GZipFilter(output)); } } return(null); }