Beispiel #1
0
 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;
		}
Beispiel #5
0
        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);
        }