Inheritance: System.IO.MemoryStream
Esempio n. 1
0
        //
        // Never throws
        //
        private Stream MakeMemoryStream(Stream stream) {
           // GlobalLog.ThreadContract(ThreadKinds.[....], "HttpWebRequest#" + ValidationHelper.HashString(this) + "::MakeMemoryStream");

            if (stream == null || stream is SyncMemoryStream)
                return stream;

            SyncMemoryStream memoryStream = new SyncMemoryStream(0);      // buffered Stream to save off data
            try {
                //
                // Now drain the Stream
                //
                if (stream.CanRead) {
                    byte [] buffer = new byte[1024];
                    int bytesTransferred = 0;

                    // 



                    int maxBytesToBuffer = (HttpWebRequest.DefaultMaximumErrorResponseLength == -1)?buffer.Length:HttpWebRequest.DefaultMaximumErrorResponseLength*1024;
                    while ((bytesTransferred = stream.Read(buffer, 0, Math.Min(buffer.Length, maxBytesToBuffer))) > 0)
                    {
                        memoryStream.Write(buffer, 0, bytesTransferred);
                        if(HttpWebRequest.DefaultMaximumErrorResponseLength != -1)
                            maxBytesToBuffer -= bytesTransferred;
                    }
                }
                memoryStream.Position = 0;
            }
            catch {
            }
            finally
            {
                try {
                    ICloseEx icloseEx = stream as ICloseEx;
                    if (icloseEx != null) {
                        icloseEx.CloseEx(CloseExState.Silent);
                    }
                    else {
                        stream.Close();
                    }
                }
                catch {
                }
            }
            return memoryStream;
        }
        /// <remarks>  This method may add headers under the "Warning" header name </remarks>
        protected internal override CacheValidationStatus ValidateCache() {

            if (this.Policy.Level != HttpRequestCacheLevel.Revalidate && base.Policy.Level >= RequestCacheLevel.Reload)
            {
                // For those policies cache is never returned
                GlobalLog.Assert("OnValidateCache()", "This validator should not be called for policy = " + Policy.ToString());
                if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_validator_invalid_for_policy, Policy.ToString()));
                return CacheValidationStatus.DoNotTakeFromCache;
            }

            // First check is do we have a cached entry at all?
            // Also we include some very special case where cache got a 304 (NotModified) response somehow
            if (CacheStream == Stream.Null || (int)CacheStatusCode == 0 || CacheStatusCode == HttpStatusCode.NotModified)
            {
                if (this.Policy.Level == HttpRequestCacheLevel.CacheOnly)
                {
                    // Throw because entry was not found and it's cache-only policy
                    FailRequest(WebExceptionStatus.CacheEntryNotFound);
                }
                return CacheValidationStatus.DoNotTakeFromCache;
            }

            if (RequestMethod == HttpMethod.Head)
            {
                // For a HEAD request we release the cache entry stream asap since we will have to suppress it anyway
                CacheStream.Close();
                CacheStream = new SyncMemoryStream(new byte[] {});
            }

            // Apply our best knowledge of HTTP caching and return the result
            // that can be hooked up and revised by the upper level

            CacheValidationStatus result = CacheValidationStatus.DoNotTakeFromCache;

            //
            // Before request submission validation
            //

            // If we return from cache we should remove existing 1xx warnings
            RemoveWarnings_1xx();

            // default values for a response from cache.
            CacheStreamOffset       = 0;
            CacheStreamLength       = CacheEntry.StreamSize;

            result = Rfc2616.OnValidateCache(this);
            if (result != CacheValidationStatus.ReturnCachedResponse && this.Policy.Level == HttpRequestCacheLevel.CacheOnly) {
                // Throw because entry was not found and it's cache-only policy
                FailRequest(WebExceptionStatus.CacheEntryNotFound);
            }

            if (result == CacheValidationStatus.ReturnCachedResponse)
            {
                if (CacheFreshnessStatus == CacheFreshnessStatus.Stale) {
                    CacheHeaders.Add(HttpKnownHeaderNames.Warning, HttpRequestCacheValidator.Warning_110);
                }
                if (base.Policy.Level == RequestCacheLevel.CacheOnly) {
                    CacheHeaders.Add(HttpKnownHeaderNames.Warning, HttpRequestCacheValidator.Warning_112);
                }
                if (HeuristicExpiration && (int)CacheAge.TotalSeconds >= 24*3600) {
                    CacheHeaders.Add(HttpKnownHeaderNames.Warning, HttpRequestCacheValidator.Warning_113);
                }
            }

            if (result == CacheValidationStatus.DoNotTakeFromCache) {
                // We signal that current cache entry can be only replaced and not updated
                CacheStatusCode = (HttpStatusCode) 0;
            }
            else if (result == CacheValidationStatus.ReturnCachedResponse) {
                CacheHeaders[HttpKnownHeaderNames.Age] = ((int)(CacheAge.TotalSeconds)).ToString(NumberFormatInfo.InvariantInfo);
            }
            return result;
        }