Exemplo n.º 1
0
        /// <summary>
        /// Sends headers required to send an entity.
        /// </summary>
        /// <param name="response">An HTTP response.</param>
        /// <param name="compressionType">The compression type that request wants it sent back in.</param>
        /// <param name="entity"></param>
        public void SendHeaders(HttpResponseBase response, ResponseCompressionType compressionType, IEntity entity)
        {
            if (!(entity.CompressionType == ResponseCompressionType.None || entity.CompressionType == compressionType))
            {
                throw new NotImplementedException("Need to decode in memory, and then stream it");
            }

            HttpResponseHeaderHelper.SetContentEncoding(response, compressionType);

            //How should data be compressed
            if (entity.CompressionType == compressionType)
            {
                //We have the entity stored in the correct compression format so just stream it
                HttpResponseHeaderHelper.AppendHeader(response, HttpHeaderContentLength, entity.ContentLength.ToString());
            }
            else if (entity.CompressionType == ResponseCompressionType.None)
            {
                switch (compressionType)
                {
                    case ResponseCompressionType.GZip:
                        response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
                        //This means that the output stream will be chunked, so we don't have to worry about content length
                        break;
                    case ResponseCompressionType.Deflate:
                        response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
                        //This means that the output stream will be chunked, so we don't have to worry about content length
                        break;
                }
            }

            response.ContentType = entity.ContentType;
        }
Exemplo n.º 2
0
        public void SendHeaders(HttpResponseBase response, ResponseCompressionType compressionType, IEntity entity)
        {
            //Data must be in uncompressed format when responding partially
            if (entity.CompressionType != ResponseCompressionType.None)
            {
                //TODO: perhaps we could uncompress object, but for now we don't worry about it
                throw new Exception("Cannot do a partial response on compressed data");
            }

            HttpResponseHeaderHelper.SetContentEncoding(response, compressionType);

            switch (compressionType)
            {
            case ResponseCompressionType.None:
                var contentLength = Range.EndRange - Range.StartRange + 1;
                HttpResponseHeaderHelper.AppendHeader(response, HTTP_HEADER_CONTENT_LENGTH, contentLength.ToString());
                break;

            case ResponseCompressionType.GZip:
                response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
                //This means that the output stream will be chunked, so we don't have to worry about content length
                break;

            case ResponseCompressionType.Deflate:
                response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
                //This means that the output stream will be chunked, so we don't have to worry about content length
                break;
            }

            response.ContentType = entity.ContentType;
            HttpResponseHeaderHelper.AppendHeader(response, HTTP_HEADER_CONTENT_RANGE, BYTES + " " + Range.StartRange + "-" + Range.EndRange + "/" + entity.ContentLength);
        }
        public void SendHeaders(HttpResponseBase response, ResponseCompressionType compressionType, IEntity entity)
        {
            //Data must be in uncompressed format when responding partially
            if (entity.CompressionType != ResponseCompressionType.None)
            {
                //TODO: perhaps we could uncompress object, but for now we don't worry about it
                throw new Exception("Cannot do a partial response on compressed data");
            }

            HttpResponseHeaderHelper.SetContentEncoding(response, compressionType);

            switch (compressionType)
            {
                case ResponseCompressionType.None:
                    var contentLength = Range.EndRange - Range.StartRange + 1;
                    HttpResponseHeaderHelper.AppendHeader(response, HttpHeaderContentLength, contentLength.ToString());
                    break;
                case ResponseCompressionType.GZip:
                    response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
                    //This means that the output stream will be chunked, so we don't have to worry about content length
                    break;
                case ResponseCompressionType.Deflate:
                    response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
                    //This means that the output stream will be chunked, so we don't have to worry about content length
                    break;
            }

            response.ContentType = entity.ContentType;
            HttpResponseHeaderHelper.AppendHeader(response, HttpHeaderContentRange, Bytes + " " + Range.StartRange + "-" + Range.EndRange + "/" + entity.ContentLength);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Setups the headers required to send a partial response.
        /// </summary>
        /// <param name="response">An HTTP response.</param>
        /// <param name="compressionType">The compression type that request wants it sent back in.</param>
        /// <param name="entity"></param>
        public void SendHeaders(HttpResponseBase response, ResponseCompressionType compressionType, IEntity entity)
        {
            //Data must be in uncompressed format when responding partially
            if (entity.CompressionType != ResponseCompressionType.None)
            {
                //TODO: perhaps we could uncompress object, but for now we don't worry about it
                throw new Exception("Cannot do a partial response on compressed data");
            }

            HttpResponseHeaderHelper.SetContentEncoding(response, compressionType);

            switch (compressionType)
            {
            case ResponseCompressionType.None:
                ByteRangeResponse.SetContentLength(response, entity);
                break;

            case ResponseCompressionType.GZip:
                response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
                //This means that the output stream will be chunked, so we don't have to worry about content length
                break;

            case ResponseCompressionType.Deflate:
                response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
                //This means that the output stream will be chunked, so we don't have to worry about content length
                break;
            }

            ByteRangeResponse.SetOtherHeaders(response, entity);
        }
Exemplo n.º 5
0
        protected override void When()
        {
            Entity.Stub(x => x.ContentLength).Return(EntityContentLength);
            Entity.Stub(x => x.CompressionType).Return(EntityCompressionType);
            Entity.Stub(x => x.ContentType).Return(EntityContentType);

            HttpResponseHeaderHelper
            .Stub(x => x.SetContentEncoding(HttpResponse, ResponseCompressionType))
            .Callback((HttpResponseBase httpResponse, ResponseCompressionType responseCompressionType) =>
            {
                ResponseCompressionTypeSet = responseCompressionType;
                return(true);
            });

            HttpResponseHeaderHelper
            .Stub(x => x.AppendHeader(HttpResponse, EntityResponseFull.HttpHeaderContentLength, EntityContentLength.ToString()))
            .Callback((HttpResponseBase httpResponse, string httpResponseHeader, string headerValue) =>
            {
                ContentLengthSet = headerValue;
                return(true);
            });

            HttpResponse.Stub(x => x.ContentType).PropertyBehavior();
            HttpResponse.Stub(x => x.Filter).PropertyBehavior();
            HttpResponse.Filter = new MemoryStream();

            SystemUnderTest.SendHeaders(HttpResponse, ResponseCompressionType, Entity);
        }
 /// <summary>
 /// Set the compression type used in the response.
 /// </summary>
 /// <param name="response">An HTTP response.</param>
 /// <param name="responseCompressionType">The compression type to use in the response.</param>
 public void SetContentEncoding(HttpResponseBase response, ResponseCompressionType responseCompressionType)
 {
     if (responseCompressionType != ResponseCompressionType.None)
     {
         AppendHeader(response, HttpResponseHeader.ContentEncoding, responseCompressionType.ToString().ToLower());
     }
 }
Exemplo n.º 7
0
        private static void ReadFileData(ResponseCompressionType compressionType,
                                         FileInfo file, MemoryStream memoryStream)
        {
            using (Stream outputStream =
                       (compressionType == ResponseCompressionType.None ? memoryStream :
                        (compressionType == ResponseCompressionType.GZip ?
                         (Stream) new GZipStream(memoryStream, CompressionMode.Compress, true) :
                         (Stream) new DeflateStream(memoryStream, CompressionMode.Compress))))
            {
                // We can compress and cache this file
                using (FileStream fs = file.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    int    bufSize = Convert.ToInt32(Math.Min(file.Length, 8 * 1024));
                    byte[] buffer  = new byte[bufSize];

                    int bytesRead;
                    while ((bytesRead = fs.Read(buffer, 0, bufSize)) > 0)
                    {
                        outputStream.Write(buffer, 0, bytesRead);
                    }
                }

                outputStream.Flush();
            }
        }
Exemplo n.º 8
0
 /// <summary>
 /// Set the compression type used in the response.
 /// </summary>
 /// <param name="response">An HTTP response.</param>
 /// <param name="responseCompressionType">The compression type to use in the response.</param>
 public void SetContentEncoding(HttpResponseBase response, ResponseCompressionType responseCompressionType)
 {
     if (responseCompressionType != ResponseCompressionType.None)
     {
         AppendHeader(response, HttpResponseHeader.ContentEncoding, responseCompressionType.ToString().ToLower());
     }
 }
        public void SendHeaders(HttpResponseBase response, ResponseCompressionType compressionType, IEntity entity)
        {
            //Data must be in uncompressed format when responding partially
            if (entity.CompressionType != ResponseCompressionType.None)
            {
                //TODO: perhaps we could uncompress object, but for now we don't worry about it
                throw new Exception("Cannot do a partial response on compressed data");
            }

            HttpResponseHeaderHelper.SetContentEncoding(response, compressionType);

            switch (compressionType)
            {
            case ResponseCompressionType.None:
                var partialContentLength = GetMultipartPartialRequestLength(Ranges, entity.ContentType, entity.ContentLength);
                HttpResponseHeaderHelper.AppendHeader(response, HttpHeaderContentLength, partialContentLength.ToString());
                break;

            case ResponseCompressionType.GZip:
                response.BufferOutput = true;
                response.Filter       = new GZipStream(response.Filter, CompressionMode.Compress);
                //This means that the output stream will be chunked, so we don't have to worry about content length
                break;

            case ResponseCompressionType.Deflate:
                response.BufferOutput = true;
                response.Filter       = new DeflateStream(response.Filter, CompressionMode.Compress);
                //This means that the output stream will be chunked, so we don't have to worry about content length
                break;
            }

            response.ContentType = MultipartContenttype;
        }
Exemplo n.º 10
0
        /// <summary>
        /// Sends headers required to send an entity.
        /// </summary>
        /// <param name="response">An HTTP response.</param>
        /// <param name="compressionType">The compression type that request wants it sent back in.</param>
        /// <param name="entity"></param>
        public void SendHeaders(HttpResponseBase response, ResponseCompressionType compressionType, IEntity entity)
        {
            if (!(entity.CompressionType == ResponseCompressionType.None || entity.CompressionType == compressionType))
            {
                throw new NotImplementedException("Need to decode in memory, and then stream it");
            }

            HttpResponseHeaderHelper.SetContentEncoding(response, compressionType);

            //How should data be compressed
            if (entity.CompressionType == compressionType)
            {
                //We have the entity stored in the correct compression format so just stream it
                HttpResponseHeaderHelper.AppendHeader(response, HttpHeaderContentLength, entity.ContentLength.ToString());
            }
            else if (entity.CompressionType == ResponseCompressionType.None)
            {
                switch (compressionType)
                {
                case ResponseCompressionType.GZip:
                    response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
                    //This means that the output stream will be chunked, so we don't have to worry about content length
                    break;

                case ResponseCompressionType.Deflate:
                    response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
                    //This means that the output stream will be chunked, so we don't have to worry about content length
                    break;
                }
            }

            response.ContentType = entity.ContentType;
        }
Exemplo n.º 11
0
        private void CacheAndDeliver(HttpContext context,
                                     HttpRequest request, HttpResponse response,
                                     string physicalFilePath, ResponseCompressionType compressionType,
                                     string cacheKey, MemoryStream memoryStream, FileInfo file)
        {
            // Cache the content in ASP.NET Cache
            byte[] responseBytes = memoryStream.ToArray();
            context.Cache.Insert(cacheKey, new CachedContent(responseBytes, file.LastWriteTimeUtc),
                                 new CacheDependency(physicalFilePath),
                                 DateTime.Now.Add(DEFAULT_CACHE_DURATION), Cache.NoSlidingExpiration);

            this.ProduceResponseHeader(response, responseBytes.Length, compressionType,
                                       physicalFilePath, file.LastWriteTimeUtc);
            this.WriteResponse(response, responseBytes, compressionType, physicalFilePath);

            Debug.WriteLine("StaticFileHandler: NonCached: " + request.FilePath);
        }
Exemplo n.º 12
0
        private void TransmitFileUsingHttpResponse(HttpRequest request, HttpResponse response,
                                                   string physicalFilePath, ResponseCompressionType compressionType, FileInfo file)
        {
            if (file.Exists)
            {
                // We don't cache/compress such file types. Must be some binary file that's better
                // to let IIS handle
                this.ProduceResponseHeader(response, Convert.ToInt32(file.Length), compressionType,
                                           physicalFilePath, file.LastWriteTimeUtc);
                response.TransmitFile(physicalFilePath);

                Debug.WriteLine("TransmitFile: " + request.FilePath);
            }
            else
            {
                throw new HttpException((int)HttpStatusCode.NotFound, request.FilePath + " Not Found");
            }
        }
Exemplo n.º 13
0
        private static void ProduceResponseHeader(HttpResponse response, int count, ResponseCompressionType mode, string physicalFilePath, DateTime lastModified)
        {
            response.Buffer       = false;
            response.BufferOutput = false;

            response.ContentType = MimeMapping.GetMimeMapping(physicalFilePath);
            if (mode != ResponseCompressionType.None)
            {
                response.AppendHeader("Content-Encoding", mode.ToString().ToLower());
            }
            response.AppendHeader("Content-Length", count.ToString(CultureInfo.InvariantCulture));

            response.Cache.SetCacheability(HttpCacheability.Public);
            response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
            response.Cache.SetMaxAge(_defaultCacheDuration);
            response.Cache.SetExpires(DateTime.Now.Add(_defaultCacheDuration));
            response.Cache.SetLastModified(lastModified);
        }
Exemplo n.º 14
0
        //方法执行前
        public override void OnActionExecuted(ActionExecutedContext filterContext)
        {
            //压缩
            string EncodingString = filterContext.HttpContext.Request.Headers["Accept-Encoding"].ToString();;

            if (string.IsNullOrWhiteSpace(EncodingString))
            {
                return;
            }
            else
            {
                //if (EncodingString.ToLower().Contains("gzip"))
                //{
                //    var responses = filterContext.HttpContext.Response;
                //    responses.AddHeader("context-encoding", "gzip");
                //    responses.Filter = new GZipStream(responses.Filter, CompressionMode.Compress);
                //}


                #region  压缩有关(百度方式,页面压缩)
                var context  = HttpContext.Current;
                var request  = context.Request;
                var response = context.Response;
                ResponseCompressionType compressionType = this.GetCompressionMode(request);

                if (compressionType != ResponseCompressionType.None)
                {
                    response.AppendHeader("Content-Encoding", compressionType.ToString().ToLower());
                    if (compressionType == ResponseCompressionType.GZip)
                    {
                        response.Filter = new GZipStream(response.Filter, CompressionMode.Compress);
                    }
                    else
                    {
                        response.Filter = new DeflateStream(response.Filter, CompressionMode.Compress);
                    }
                }
                #endregion
            }


            base.OnActionExecuted(filterContext);
        }
Exemplo n.º 15
0
        /// <summary>
        /// Read a files contents into a stream
        /// </summary>
        /// <param name="compressionType">The compression type to use.</param>
        /// <param name="stream">The stream to write to.</param>
        private void GetEntityData(ResponseCompressionType compressionType, Stream stream)
        {
            using (var outputStream = (compressionType == ResponseCompressionType.None ? stream : (compressionType == ResponseCompressionType.GZip ? (Stream) new GZipStream(stream, CompressionMode.Compress, true) : (Stream) new DeflateStream(stream, CompressionMode.Compress))))
            {
                // We can compress and cache this file
                using (var resourceStream = _assembly.GetManifestResourceStream(ResourcePath))
                {
                    var bufferSize = Convert.ToInt32(Math.Min(ResourceSize, BufferSize));
                    var buffer     = new byte[bufferSize];

                    int bytesRead;
                    while ((bytesRead = resourceStream.Read(buffer, 0, bufferSize)) > 0)
                    {
                        outputStream.Write(buffer, 0, bytesRead);
                    }
                }

                outputStream.Flush();
            }
        }
Exemplo n.º 16
0
        /// <summary>
        /// Read a files contents into a stream
        /// </summary>
        /// <param name="compressionType">The compression type to use.</param>
        /// <param name="stream">The stream to write to.</param>
        private void GetEntityData(ResponseCompressionType compressionType, Stream stream)
        {
            using (var outputStream = (compressionType == ResponseCompressionType.None ? stream : (compressionType == ResponseCompressionType.GZip ? (Stream) new GZipStream(stream, CompressionMode.Compress, true) : (Stream) new DeflateStream(stream, CompressionMode.Compress))))
            {
                // We can compress and cache this file
                using (var fileStream = RetryableFileOpener.OpenFileStream(FileInfo, 5, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var bufferSize = Convert.ToInt32(Math.Min(FileInfo.Length, BufferSize));
                    var buffer     = new byte[bufferSize];

                    int bytesRead;
                    while ((bytesRead = fileStream.Read(buffer, 0, bufferSize)) > 0)
                    {
                        outputStream.Write(buffer, 0, bytesRead);
                    }
                }

                outputStream.Flush();
            }
        }
Exemplo n.º 17
0
        private bool DeliverFromCache(HttpContext context,
                                      HttpRequest request, HttpResponse response,
                                      string cacheKey,
                                      string physicalFilePath, ResponseCompressionType compressionType)
        {
            CachedContent cachedContent = context.Cache[cacheKey] as CachedContent;

            if (null != cachedContent)
            {
                byte[] cachedBytes = cachedContent.ResponseBytes;

                // We have it cached
                this.ProduceResponseHeader(response, cachedBytes.Length, compressionType,
                                           physicalFilePath, cachedContent.LastModified);
                this.WriteResponse(response, cachedBytes, compressionType, physicalFilePath);

                Debug.WriteLine("StaticFileHandler: Cached: " + request.FilePath);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemplo n.º 18
0
        private void ProduceResponseHeader(HttpResponse response, int count,
                                           ResponseCompressionType mode, string physicalFilePath,
                                           DateTime lastModified)
        {
            response.Buffer       = false;
            response.BufferOutput = false;

            // Emit content type and encoding based on the file extension and
            // whether the response is compressed
            response.ContentType = MimeMapping.GetMimeMapping(physicalFilePath);
            if (mode != ResponseCompressionType.None)
            {
                response.AppendHeader("Content-Encoding", mode.ToString().ToLower());
            }
            response.AppendHeader("Content-Length", count.ToString());

            // Emit proper cache headers that will cache the response in browser's
            // cache for the default cache duration
            response.Cache.SetCacheability(HttpCacheability.Public);
            response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
            response.Cache.SetMaxAge(DEFAULT_CACHE_DURATION);
            response.Cache.SetExpires(DateTime.Now.Add(DEFAULT_CACHE_DURATION));
            response.Cache.SetLastModified(lastModified);
        }
        /// <summary>
        /// Get a fileHanderCacheItem for the requested file.
        /// </summary>
        /// <param name="entityStoredWithCompressionType">The compression type to use for the file.</param>
        /// <param name="entityCacheItem">The fileHandlerCacheItem </param>
        /// <returns>Returns true if a fileHandlerCacheItem can be created; otherwise false.</returns>
        public bool TryGetFileHandlerCacheItem(ResponseCompressionType entityStoredWithCompressionType, out EntityCacheItem entityCacheItem)
        {
            entityCacheItem = null;

            // If the response bytes are already cached, then deliver the bytes directly from cache
            var cacheKey = EmbeddedResourceEntityResponderType + ":" + entityStoredWithCompressionType + ":" + ResourcePath;

            var cachedValue = CacheManager.Get<EntityCacheItem>(cacheKey);
            if (cachedValue != null)
            {
                entityCacheItem = cachedValue;
            }
            else
            {
                //File does not exist
                if (!DoesEntityExists)
                {
                    return false;
                }

                //File too large to send
                if (ResourceSize > MaxFileSizeToServe)
                {
                    return false;
                }

                var etag = string.Empty;
                var lastModifiedFileTime = ResourceLastModified;
                //When a browser sets the If-Modified-Since field to 13-1-2010 10:30:58, another DateTime instance is created, but this one has a Ticks value of 633989754580000000
                //But the time from the file system is accurate to a tick. So it might be 633989754586086250.
                var lastModified = new DateTime(lastModifiedFileTime.Year, lastModifiedFileTime.Month,
                                                lastModifiedFileTime.Day, lastModifiedFileTime.Hour,
                                                lastModifiedFileTime.Minute, lastModifiedFileTime.Second);
                var contentType = MimeTyper.GetMimeType(ResourceExtension);
                var contentLength = ResourceSize;

                //ETAG is always calculated from uncompressed entity data
                switch (MimeSetting.EtagMethod)
                {
                    case EtagMethodType.MD5:
                        using (var resourceStream = _assembly.GetManifestResourceStream(ResourcePath))
                        {
                            etag = Hasher.Hash(resourceStream);
                        }
                        break;
                    case EtagMethodType.LastModified:
                        etag = lastModified.ToString("r");
                        break;
                    default:
                        throw new Exception("Unknown etag method generation");
                }

                entityCacheItem = new EntityCacheItem
                {
                    Etag = etag,
                    LastModified = lastModified,
                    ContentLength = contentLength,
                    ContentType = contentType,
                    CompressionType = ResponseCompressionType.None
                };

                if (MimeSetting.ServeFromMemory
                    && (contentLength <= MimeSetting.MaxMemorySize))
                {
                    // When not compressed, buffer is the size of the file but when compressed,
                    // initial buffer size is one third of the file size. Assuming, compression
                    // will give us less than 1/3rd of the size
                    using (var memoryStream = new MemoryStream(
                        entityStoredWithCompressionType == ResponseCompressionType.None
                            ?
                                Convert.ToInt32(ResourceSize)
                            :
                                Convert.ToInt32((double)ResourceSize / 3)))
                    {
                        GetEntityData(entityStoredWithCompressionType, memoryStream);
                        var entityData = memoryStream.ToArray();
                        var entityDataLength = entityData.LongLength;

                        entityCacheItem.EntityData = entityData;
                        entityCacheItem.ContentLength = entityDataLength;
                        entityCacheItem.CompressionType = entityStoredWithCompressionType;
                    }
                }

                //Put fileHandlerCacheItem into cache with 30 min sliding expiration, also if file changes then remove fileHandlerCacheItem from cache
                CacheManager.Insert(
                    cacheKey,
                    entityCacheItem,
                    null,
                    Cache.NoAbsoluteExpiration,
                    MimeSetting.MemorySlidingExpiration,
                    CacheItemPriority.BelowNormal,
                    null);
            }

            return true;
        }
        /// <summary>
        /// Read a files contents into a stream
        /// </summary>
        /// <param name="compressionType">The compression type to use.</param>
        /// <param name="stream">The stream to write to.</param>
        private void GetEntityData(ResponseCompressionType compressionType, Stream stream)
        {
            using (var outputStream = (compressionType == ResponseCompressionType.None ? stream : (compressionType == ResponseCompressionType.GZip ? (Stream)new GZipStream(stream, CompressionMode.Compress, true) : (Stream)new DeflateStream(stream, CompressionMode.Compress))))
            {
                // We can compress and cache this file
                using (var resourceStream = _assembly.GetManifestResourceStream(ResourcePath))
                {
                    var bufferSize = Convert.ToInt32(Math.Min(ResourceSize, BufferSize));
                    var buffer = new byte[bufferSize];

                    int bytesRead;
                    while ((bytesRead = resourceStream.Read(buffer, 0, bufferSize)) > 0)
                    {
                        outputStream.Write(buffer, 0, bytesRead);
                    }
                }

                outputStream.Flush();
            }
        }
Exemplo n.º 21
0
        /// <summary>
        /// Get a fileHanderCacheItem for the requested file.
        /// </summary>
        /// <param name="entityStoredWithCompressionType">The compression type to use for the file.</param>
        /// <param name="entityCacheItem">The fileHandlerCacheItem </param>
        /// <returns>Returns true if a fileHandlerCacheItem can be created; otherwise false.</returns>
        public bool TryGetFileHandlerCacheItem(ResponseCompressionType entityStoredWithCompressionType, out EntityCacheItem entityCacheItem)
        {
            entityCacheItem = null;

            // If the response bytes are already cached, then deliver the bytes directly from cache
            var cacheKey = EmbeddedResourceEntityResponderType + ":" + entityStoredWithCompressionType + ":" + ResourcePath;

            var cachedValue = CacheManager.Get <EntityCacheItem>(cacheKey);

            if (cachedValue != null)
            {
                entityCacheItem = cachedValue;
            }
            else
            {
                //File does not exist
                if (!DoesEntityExists)
                {
                    return(false);
                }

                //File too large to send
                if (ResourceSize > MaxFileSizeToServe)
                {
                    return(false);
                }

                var etag = string.Empty;
                var lastModifiedFileTime = ResourceLastModified;
                //When a browser sets the If-Modified-Since field to 13-1-2010 10:30:58, another DateTime instance is created, but this one has a Ticks value of 633989754580000000
                //But the time from the file system is accurate to a tick. So it might be 633989754586086250.
                var lastModified = new DateTime(lastModifiedFileTime.Year, lastModifiedFileTime.Month,
                                                lastModifiedFileTime.Day, lastModifiedFileTime.Hour,
                                                lastModifiedFileTime.Minute, lastModifiedFileTime.Second);
                var contentType   = MimeTyper.GetMimeType(ResourceExtension);
                var contentLength = ResourceSize;

                //ETAG is always calculated from uncompressed entity data
                switch (MimeSetting.EtagMethod)
                {
                case EtagMethodType.MD5:
                    using (var resourceStream = _assembly.GetManifestResourceStream(ResourcePath))
                    {
                        etag = Hasher.CalculateMd5Etag(resourceStream);
                    }
                    break;

                case EtagMethodType.LastModified:
                    etag = lastModified.ToString("r");
                    break;

                default:
                    throw new Exception("Unknown etag method generation");
                }

                entityCacheItem = new EntityCacheItem
                {
                    Etag            = etag,
                    LastModified    = lastModified,
                    ContentLength   = contentLength,
                    ContentType     = contentType,
                    CompressionType = ResponseCompressionType.None
                };

                if (MimeSetting.ServeFromMemory &&
                    (contentLength <= MimeSetting.MaxMemorySize))
                {
                    // When not compressed, buffer is the size of the file but when compressed,
                    // initial buffer size is one third of the file size. Assuming, compression
                    // will give us less than 1/3rd of the size
                    using (var memoryStream = new MemoryStream(
                               entityStoredWithCompressionType == ResponseCompressionType.None
                            ?
                               Convert.ToInt32(ResourceSize)
                            :
                               Convert.ToInt32((double)ResourceSize / 3)))
                    {
                        GetEntityData(entityStoredWithCompressionType, memoryStream);
                        var entityData       = memoryStream.ToArray();
                        var entityDataLength = entityData.LongLength;

                        entityCacheItem.EntityData      = entityData;
                        entityCacheItem.ContentLength   = entityDataLength;
                        entityCacheItem.CompressionType = entityStoredWithCompressionType;
                    }
                }

                //Put fileHandlerCacheItem into cache with 30 min sliding expiration, also if file changes then remove fileHandlerCacheItem from cache
                CacheManager.Insert(
                    cacheKey,
                    entityCacheItem,
                    null,
                    Cache.NoAbsoluteExpiration,
                    MimeSetting.MemorySlidingExpiration,
                    CacheItemPriority.BelowNormal,
                    null);
            }

            return(true);
        }
Exemplo n.º 22
0
 private void WriteResponse(HttpResponse response, byte[] bytes,
     ResponseCompressionType mode, string physicalFilePath)
 {
     response.OutputStream.Write(bytes, 0, bytes.Length);
     response.OutputStream.Flush();
 }
Exemplo n.º 23
0
        private void TransmitFileUsingHttpResponse(HttpRequest request, HttpResponse response,
            string physicalFilePath, ResponseCompressionType compressionType, FileInfo file)
        {
            if (file.Exists)
            {
                // We don't cache/compress such file types. Must be some binary file that's better
                // to let IIS handle
                this.ProduceResponseHeader(response, Convert.ToInt32(file.Length), compressionType,
                    physicalFilePath, file.LastWriteTimeUtc);
                response.TransmitFile(physicalFilePath);

                Debug.WriteLine("TransmitFile: " + request.FilePath);
            }
            else
            {
                throw new HttpException((int)HttpStatusCode.NotFound, request.FilePath + " Not Found");
            }
        }
Exemplo n.º 24
0
        private void ProduceResponseHeader(HttpResponse response, int count,
            ResponseCompressionType mode, string physicalFilePath,
            DateTime lastModified)
        {
            response.Buffer = false;
            response.BufferOutput = false;

            // Emit content type and encoding based on the file extension and
            // whether the response is compressed
            response.ContentType = MimeMapping.GetMimeMapping(physicalFilePath);
            if (mode != ResponseCompressionType.None)
                response.AppendHeader("Content-Encoding", mode.ToString().ToLower());
            response.AppendHeader("Content-Length", count.ToString());

            // Emit proper cache headers that will cache the response in browser's
            // cache for the default cache duration
            response.Cache.SetCacheability(HttpCacheability.Public);
            response.Cache.AppendCacheExtension("must-revalidate, proxy-revalidate");
            response.Cache.SetMaxAge(DEFAULT_CACHE_DURATION);
            response.Cache.SetExpires(DateTime.Now.Add(DEFAULT_CACHE_DURATION));
            response.Cache.SetLastModified(lastModified);
        }
Exemplo n.º 25
0
        private bool DeliverFromCache(HttpContext context,
            HttpRequest request, HttpResponse response,
            string cacheKey,
            string physicalFilePath, ResponseCompressionType compressionType)
        {
            CachedContent cachedContent = context.Cache[cacheKey] as CachedContent;
            if (null != cachedContent)
            {
                byte[] cachedBytes = cachedContent.ResponseBytes;

                // We have it cached
                this.ProduceResponseHeader(response, cachedBytes.Length, compressionType,
                    physicalFilePath, cachedContent.LastModified);
                this.WriteResponse(response, cachedBytes, compressionType, physicalFilePath);

                Debug.WriteLine("StaticFileHandler: Cached: " + request.FilePath);
                return true;
            }
            else
            {
                return false;
            }
        }
Exemplo n.º 26
0
        private void CacheAndDeliver(HttpContext context,
            HttpRequest request, HttpResponse response,
            string physicalFilePath, ResponseCompressionType compressionType,
            string cacheKey, MemoryStream memoryStream, FileInfo file)
        {
            // Cache the content in ASP.NET Cache
            byte[] responseBytes = memoryStream.ToArray();
            context.Cache.Insert(cacheKey, new CachedContent(responseBytes, file.LastWriteTimeUtc),
                new CacheDependency(physicalFilePath),
                DateTime.Now.Add(DEFAULT_CACHE_DURATION), Cache.NoSlidingExpiration);

            this.ProduceResponseHeader(response, responseBytes.Length, compressionType,
                physicalFilePath, file.LastWriteTimeUtc);
            this.WriteResponse(response, responseBytes, compressionType, physicalFilePath);

            Debug.WriteLine("StaticFileHandler: NonCached: " + request.FilePath);
        }
Exemplo n.º 27
0
        private static void ReadFileData(ResponseCompressionType compressionType,
            FileInfo file, MemoryStream memoryStream)
        {
            using (Stream outputStream =
                (compressionType == ResponseCompressionType.None ? memoryStream :
                (compressionType == ResponseCompressionType.GZip ?
                    (Stream)new GZipStream(memoryStream, CompressionMode.Compress, true) :
                    (Stream)new DeflateStream(memoryStream, CompressionMode.Compress))))
            {
                // We can compress and cache this file
                using (FileStream fs = file.Open(FileMode.Open, FileAccess.Read, FileShare.Read))
                {

                    int bufSize = Convert.ToInt32(Math.Min(file.Length, 8 * 1024));
                    byte[] buffer = new byte[bufSize];

                    int bytesRead;
                    while ((bytesRead = fs.Read(buffer, 0, bufSize)) > 0)
                    {
                        outputStream.Write(buffer, 0, bytesRead);
                    }
                }

                outputStream.Flush();
            }
        }
Exemplo n.º 28
0
 private void WriteResponse(HttpResponse response, byte[] bytes,
                            ResponseCompressionType mode, string physicalFilePath)
 {
     response.OutputStream.Write(bytes, 0, bytes.Length);
     response.OutputStream.Flush();
 }
Exemplo n.º 29
0
        /// <summary>
        /// Read a files contents into a stream
        /// </summary>
        /// <param name="compressionType">The compression type to use.</param>
        /// <param name="stream">The stream to write to.</param>
        private void GetEntityData(ResponseCompressionType compressionType, Stream stream)
        {
            using (var outputStream = (compressionType == ResponseCompressionType.None ? stream : (compressionType == ResponseCompressionType.GZip ? (Stream)new GZipStream(stream, CompressionMode.Compress, true) : (Stream)new DeflateStream(stream, CompressionMode.Compress))))
            {
                // We can compress and cache this file
                using (var fileStream = RetryableFileOpener.OpenFileStream(FileInfo, 5, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var bufferSize = Convert.ToInt32(Math.Min(FileInfo.Length, BufferSize));
                    var buffer = new byte[bufferSize];

                    int bytesRead;
                    while ((bytesRead = fileStream.Read(buffer, 0, bufferSize)) > 0)
                    {
                        outputStream.Write(buffer, 0, bytesRead);
                    }
                }

                outputStream.Flush();
            }
        }
Exemplo n.º 30
0
        /// <summary>
        /// Get a fileHanderCacheItem for the requested file.
        /// </summary>
        /// <param name="entityStoredWithCompressionType">The compression type to use for the file.</param>
        /// <param name="fileEntityCacheItem">The fileHandlerCacheItem </param>
        /// <returns>Returns true if a fileHandlerCacheItem can be created; otherwise false.</returns>
        public bool TryGetFileHandlerCacheItem(ResponseCompressionType entityStoredWithCompressionType, out FileEntityCacheItem fileEntityCacheItem)
        {
            fileEntityCacheItem = null;

            // If the response bytes are already cached, then deliver the bytes directly from cache
            var cacheKey = FileInfoEntityType + ":" + entityStoredWithCompressionType + ":" + FileInfo.FullName;

            var cachedValue = HttpRuntime.Cache.Get(cacheKey);
            if (cachedValue != null)
            {
                fileEntityCacheItem = (FileEntityCacheItem)cachedValue;
            }
            else
            {
                //File does not exist
                if (!FileInfo.Exists)
                {
                    return false;
                }

                //File too large to send
                if (FileInfo.Length > MaxFileSizeToServe)
                {
                    return false;
                }

                var etag = string.Empty;
                var lastModifiedFileTime = FileInfo.LastWriteTime.ToUniversalTime();
                //When a browser sets the If-Modified-Since field to 13-1-2010 10:30:58, another DateTime instance is created, but this one has a Ticks value of 633989754580000000
                //But the time from the file system is accurate to a tick. So it might be 633989754586086250.
                var lastModified = new DateTime(lastModifiedFileTime.Year, lastModifiedFileTime.Month,
                                                lastModifiedFileTime.Day, lastModifiedFileTime.Hour,
                                                lastModifiedFileTime.Minute, lastModifiedFileTime.Second);
                var contentType = MimeTyper.GetMimeType(FileInfo.Extension);
                var contentLength = FileInfo.Length;

                //ETAG is always calculated from uncompressed entity data
                switch (FileEntitySetting.EtagMethod)
                {
                    case EtagMethodType.MD5:
                        etag = Hasher.CalculateMd5Etag(FileInfo);
                        break;
                    case EtagMethodType.LastModified:
                        etag = lastModified.ToString();
                        break;
                    default:
                        throw new Exception("Unknown etag method generation");
                }

                fileEntityCacheItem = new FileEntityCacheItem
                {
                    Etag = etag,
                    LastModified = lastModified,
                    ContentLength = contentLength,
                    ContentType = contentType,
                    CompressionType = entityStoredWithCompressionType
                };

                if (FileEntitySetting.ServeFromMemory
                    && (contentLength <= FileEntitySetting.MaxMemorySize))
                {
                    // When not compressed, buffer is the size of the file but when compressed,
                    // initial buffer size is one third of the file size. Assuming, compression
                    // will give us less than 1/3rd of the size
                    using (var memoryStream = new MemoryStream(
                        entityStoredWithCompressionType == ResponseCompressionType.None
                            ?
                                Convert.ToInt32(FileInfo.Length)
                            :
                                Convert.ToInt32((double)FileInfo.Length / 3)))
                    {
                        GetEntityData(entityStoredWithCompressionType, memoryStream);
                        var entityData = memoryStream.ToArray();
                        var entityDataLength = entityData.LongLength;

                        fileEntityCacheItem.EntityData = entityData;
                        fileEntityCacheItem.ContentLength = entityDataLength;
                    }
                }

                //Put fileHandlerCacheItem into cache with 30 min sliding expiration, also if file changes then remove fileHandlerCacheItem from cache
                HttpRuntime.Cache.Insert(
                    cacheKey,
                    fileEntityCacheItem,
                    new CacheDependency(FileInfo.FullName),
                    Cache.NoAbsoluteExpiration,
                    FileEntitySetting.MemorySlidingExpiration,
                    CacheItemPriority.BelowNormal,
                    null);
            }

            return true;
        }
Exemplo n.º 31
0
        private static void CacheAndDeliver(HttpContext context, HttpRequest request, HttpResponse response, string physicalFilePath, ResponseCompressionType compressionType, string cacheKey, MemoryStream memoryStream, FileSystemInfo file)
        {
            var responseBytes = memoryStream.ToArray();

            context.Cache.Insert(cacheKey, new CachedContent(responseBytes, file.LastWriteTimeUtc), new CacheDependency(physicalFilePath), DateTime.Now.Add(_defaultCacheDuration), Cache.NoSlidingExpiration);

            ProduceResponseHeader(response, responseBytes.Length, compressionType, physicalFilePath, file.LastWriteTimeUtc);
            WriteResponse(response, responseBytes);

            Debug.WriteLine("StaticFileHandler: NonCached: " + request.FilePath);
        }
Exemplo n.º 32
0
        public virtual IAsyncResult BeginProcessRequest(HttpContext context,
                                                        AsyncCallback callback, object state)
        {
            this._context = context;
            HttpResponse response = context.Response;
            HttpRequest  request  = context.Request;

            try
            {
                EnsureProperRequest(request);

                string physicalFilePath = request.PhysicalPath;

                ResponseCompressionType compressionType = this.GetCompressionMode(request);

                FileInfo file          = new FileInfo(physicalFilePath);
                string   fileExtension = file.Extension.ToLower();

                // Do we handle such file types?
                if (Array.BinarySearch <string>(FILE_TYPES, fileExtension) >= 0)
                {
                    // Yes we do.

                    // If this is a binary file like image, then we won't compress it.
                    if (Array.BinarySearch <string>(COMPRESS_FILE_TYPES, fileExtension) < 0)
                    {
                        compressionType = ResponseCompressionType.None;
                    }

                    // If the response bytes are already cached, then deliver the bytes directly from cache
                    string cacheKey = typeof(StaticFileHandler).ToString() + ":"
                                      + compressionType.ToString()
                                      + ":" + physicalFilePath;

                    if (DeliverFromCache(context, request, response,
                                         cacheKey, physicalFilePath, compressionType))
                    {
                        // Delivered from cache
                    }
                    else
                    {
                        if (file.Exists)
                        {
                            // When not compressed, buffer is the size of the file but when compressed,
                            // initial buffer size is one third of the file size. Assuming, compression
                            // will give us less than 1/3rd of the size
                            using (MemoryStream memoryStream = new MemoryStream(
                                       compressionType == ResponseCompressionType.None ?
                                       Convert.ToInt32(file.Length) :
                                       Convert.ToInt32((double)file.Length / 3)))
                            {
                                ReadFileData(compressionType, file, memoryStream);

                                this.CacheAndDeliver(context, request, response, physicalFilePath,
                                                     compressionType, cacheKey, memoryStream, file);
                            }
                        }
                        else
                        {
                            throw new HttpException((int)HttpStatusCode.NotFound, request.FilePath + " Not Found");
                        }
                    }
                }
                else
                {
                    this.TransmitFileUsingHttpResponse(request, response, physicalFilePath, compressionType, file);
                }

                return(new HttpAsyncResult(callback, state, true, null, null));
            }
            catch (Exception x)
            {
                if (x is HttpException)
                {
                    HttpException h = x as HttpException;
                    response.StatusCode = h.GetHttpCode();
                    Debug.WriteLine(h.Message);
                }
                return(new HttpAsyncResult(callback, state, true, null, x));
            }
        }
Exemplo n.º 33
0
        private static void TransmitFileUsingHttpResponse(HttpRequest request, HttpResponse response, string physicalFilePath, ResponseCompressionType compressionType, FileInfo file)
        {
            if (!file.Exists)
            {
                throw new HttpException((int)HttpStatusCode.NotFound, request.FilePath + " Not Found");
            }

            ProduceResponseHeader(response, Convert.ToInt32(file.Length), compressionType, physicalFilePath, file.LastWriteTimeUtc);
            response.TransmitFile(physicalFilePath);

            Debug.WriteLine("TransmitFile: " + request.FilePath);
        }