Ejemplo n.º 1
0
            /// <summary>
            /// Cache version of GetResponseStream
            /// </summary>
            /// <returns></returns>
            internal Stream GetResponseStream()
            {
                // prevent concurrent access to GetPart() which is not thread-safe
                lock (_cacheEntry)
                {
#if DEBUG
                    if (PackWebRequestFactory._traceSwitch.Enabled)
                    {
                        System.Diagnostics.Trace.TraceInformation(
                            DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
                            System.Threading.Thread.CurrentThread.ManagedThreadId + ": " +
                            "CachedResponse - Getting response stream");
                    }
#endif
                    // only one copy
                    if (_parent._responseStream == null)
                    {
                        // full container request?
                        if (_parent._partName == null)
                        {
                            Debug.Assert(false, "Cannot return full-container stream from cached container object");
                        }
                        else
                        {
#if DEBUG
                            if (PackWebRequestFactory._traceSwitch.Enabled)
                            {
                                System.Diagnostics.Trace.TraceInformation(
                                    DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
                                    System.Threading.Thread.CurrentThread.ManagedThreadId + ": " +
                                    "CachedResponse - Getting part " + _parent._partName);
                            }
#endif
                            // open the requested stream
                            PackagePart p = _cacheEntry.GetPart(_parent._partName);
#if DEBUG
                            if (PackWebRequestFactory._traceSwitch.Enabled)
                            {
                                System.Diagnostics.Trace.TraceInformation(
                                    DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
                                    System.Threading.Thread.CurrentThread.ManagedThreadId + ": " +
                                    "CachedResponse - Getting part stream ");
                            }
#endif
                            Stream s = p.GetSeekableStream(FileMode.Open, FileAccess.Read);

                            // Unless package is thread-safe, wrap the returned stream so that
                            // package access is serialized
                            if (!_cachedPackageIsThreadSafe)
                            {
                                // Return a stream that provides thread-safe access
                                // to the cached package by locking on the cached Package
                                s = new SynchronizingStream(s, _cacheEntry);
                            }

#if DEBUG
                            if (PackWebRequestFactory._traceSwitch.Enabled)
                            {
                                System.Diagnostics.Trace.TraceInformation(
                                    DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
                                    System.Threading.Thread.CurrentThread.ManagedThreadId + ": " +
                                    "CachedResponse - Getting part contenttype");
                            }
#endif
                            _parent._mimeType = new MS.Internal.ContentType(p.ContentType);

                            // cache this in case they ask for it after the stream has been closed
                            _parent._lengthAvailable = s.CanSeek;
                            if (s.CanSeek)
                            {
#if DEBUG
                                if (PackWebRequestFactory._traceSwitch.Enabled)
                                {
                                    System.Diagnostics.Trace.TraceInformation(
                                        DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
                                        System.Threading.Thread.CurrentThread.ManagedThreadId + ": " +
                                        "CachedResponse - Length is available from stream");
                                }
#endif
                                _parent._fullStreamLength = s.Length;
                            }
#if DEBUG
                            else
                            {
                                if (PackWebRequestFactory._traceSwitch.Enabled)
                                {
                                    System.Diagnostics.Trace.TraceInformation(
                                        DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
                                        System.Threading.Thread.CurrentThread.ManagedThreadId + ": " +
                                        "CachedResponse - Length is not available from stream" + _parent._partName);
                                }
                            }
#endif
                            // re-use existing member variable
                            _parent._responseStream = s;
                        }
                    }
                }

                return(_parent._responseStream);
            }
Ejemplo n.º 2
0
        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

        #region WebResponse Overloads
        /// <summary>
        /// Retrieves a stream for reading bytes from the requested resource
        /// </summary>
        /// <returns>stream</returns>
        public override Stream GetResponseStream()
        {
            CheckDisposed();

            // redirect
            if (FromPackageCache)
            {
                return(_cachedResponse.GetResponseStream());
            }

            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXPS, EventTrace.Event.WClientDRXGetStreamBegin);

#if DEBUG
            if (PackWebRequestFactory._traceSwitch.Enabled)
            {
                System.Diagnostics.Trace.TraceInformation(
                    DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
                    System.Threading.Thread.CurrentThread.ManagedThreadId + ": " +
                    "PackWebResponse - GetResponseStream()");
            }
#endif
            // create and return only a single stream for multiple calls
            if (_responseStream == null)
            {
                // can't do this until the response is available
                WaitForResponse();  // after this call, we have a viable _fullResponse object because WaitForResponse would have thrown otherwise

                // determine content length
                long streamLength = _fullResponse.ContentLength;

#if DEBUG
                if (_forceWebResponseLengthFailureSwitch.Enabled)
                {
                    streamLength = -1;
                }

                // special handling for servers that won't or can't give us the length of the resource - byte-range downloading is impossible
                if (streamLength <= 0)
                {
                    if (PackWebRequestFactory._traceSwitch.Enabled)
                    {
                        System.Diagnostics.Trace.TraceInformation(
                            DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
                            System.Threading.Thread.CurrentThread.ManagedThreadId + ": " +
                            "PackWebResponse - GetResponseStream() - stream length not available - disabling progressive download");
                    }
                }
#endif

                //  Start reading data from the response stream.
                _responseStream = _fullResponse.GetResponseStream();

                // require NetStream for progressivity and for network streams that don't
                // directly support seeking.
                if (!_responseStream.CanSeek || !_innerUri.IsFile)
                {
                    // Create a smart stream that will spawn byte-range requests as needed
                    // and support seeking. Each read has overhead of Mutex and many of the
                    // reads come through asking for 4 bytes at a time
                    _responseStream = new NetStream(
                        _responseStream, streamLength,
                        _innerUri, _webRequest, _fullResponse);

                    // wrap our stream for efficiency (short reads are expanded)
                    _responseStream = new BufferedStream(_responseStream);
                }

                // handle degenerate case where there is no part name
                if (_partName == null)
                {
                    _fullStreamLength = streamLength;    // entire container
                    _mimeType         = WpfWebRequestHelper.GetContentType(_fullResponse);

                    // pass this so that ResponseStream holds a reference to us until the stream is closed
                    _responseStream = new ResponseStream(_responseStream, this);
                }
                else
                {
                    // open container on netStream
                    Package c = Package.Open(_responseStream);
                    if (!c.PartExists(_partName))
                    {
                        throw new WebException(SR.Get(SRID.WebResponsePartNotFound));
                    }

                    PackagePart p = c.GetPart(_partName);

                    Stream s = p.GetSeekableStream(FileMode.Open, FileAccess.Read);

                    _mimeType         = new MS.Internal.ContentType(p.ContentType); // save this for use in ContentType property - may still be null
                    _fullStreamLength = s.Length;                                   // just this stream

                    // Wrap in a ResponseStream so that this container will be released
                    // when the stream is closed
                    _responseStream = new ResponseStream(s, this, _responseStream, c);
                }

                // length available? (-1 means the server chose not to report it)
                if (_fullStreamLength >= 0)
                {
                    _lengthAvailable = true;
                }
            }

            EventTrace.EasyTraceEvent(EventTrace.Keyword.KeywordXPS, EventTrace.Event.WClientDRXGetStreamEnd);

            return(_responseStream);
        }