Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / IO / Packaging / PackWebResponse.cs / 3 / PackWebResponse.cs
//------------------------------------------------------------------------------ // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // Description: // WebResponse class to handle pack-specific URI's // // History: // 10/09/2003: [....]: Created. // 01/05/2004: [....]: Rearchitect to return a new stream for each GetResponseStream call. // 01/08/2004: [....]: Disable serialization // 05/10/2004: [....]: Port to pack scheme // //----------------------------------------------------------------------------- #if DEBUG #define TRACE #endif using System; using System.IO; using System.Net; using System.Runtime.Serialization; using System.Diagnostics; // For Assert using System.Threading; // for ManualResetEvent using System.Globalization; // for CultureInfo using MS.Internal.PresentationCore; // for ExceptionStringTable using MS.Internal.IO.Packaging; // for ResponseStream using System.Security; using System.Security.Permissions; using System.Windows.Navigation; using MS.Utility; using MS.Internal; #pragma warning disable 1634, 1691 // disable warning about unknown Presharp warnings namespace System.IO.Packaging { ////// Pack-specific WebRequest handler /// ////// This WebRequest overload exists to handle Pack-specific URI's based on our custom schema /// public sealed class PackWebResponse: WebResponse { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- ////// Critical as the BooleanSwitch has a LinkDemand /// TreatAsSafe as this is just a diag switch, Debug-only and internal-only, no input data /// is passed to BooleanSwitch, and the overall operation is considered safe. /// [SecurityCritical, SecurityTreatAsSafe] static PackWebResponse() { #if DEBUG _forceWebResponseLengthFailureSwitch = new BooleanSwitch("PackWebResponseBadServerLength", "Simulate PackWebResponse handling of server that returns bogus content length"); #endif } ////// Constructor /// /// real web request /// full uri /// inner uri /// part name in the container - null if uri is to entire container only ///intended for use only by PackWebRequest ////// Critical /// 1) assigns Critical member _webRequest and calls BeginGetResponse() on it. /// [SecurityCritical] internal PackWebResponse(Uri uri, Uri innerUri, Uri partName, WebRequest innerRequest) { if (uri == null) throw new ArgumentNullException("uri"); if (innerUri == null) throw new ArgumentNullException("innerUri"); if (innerRequest == null) throw new ArgumentNullException("innerRequest"); _lockObject = new Object(); // required for synchronization _uri = uri; #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse - Creating response "); #endif _innerUri = innerUri; _partName = partName; // may be null _webRequest = innerRequest; _mimeType = null; // until we find out the real value // only create these in non-cache case // Create before any Timeout timer to prevent a race condition with the Timer callback // (that expects _responseAvailable to exist) _responseAvailable = new ManualResetEvent(false); // do we need a timer? // if the TimeOut has been set on the innerRequest, we need to simulate this behavior for // our synchronous clients if (innerRequest.Timeout != Timeout.Infinite) { #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse() starting timeout timer " + innerRequest.Timeout + " ms"); #endif _timeoutTimer = new Timer(new TimerCallback(TimeoutCallback), null, innerRequest.Timeout, Timeout.Infinite); } #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse() BeginGetResponse()"); #endif // Issue the async request to get our "real" WebResponse // don't access this value until we set the ManualResetEvent _webRequest.BeginGetResponse(new AsyncCallback(ResponseCallback), this); } ////// Constructor: Cache-entry overload /// /// /// /// /// entry from cache /// is entry thread safe? internal PackWebResponse(Uri uri, Uri innerUri, Uri partName, Package cacheEntry, bool cachedPackageIsThreadSafe) { _lockObject = new Object(); // required for synchronization if (uri == null) throw new ArgumentNullException("uri"); if (innerUri == null) throw new ArgumentNullException("innerUri"); if (partName == null) throw new ArgumentNullException("partName"); if (cacheEntry == null) throw new ArgumentNullException("cacheEntry"); #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse - Creating response from Package Cache"); #endif _uri = uri; _innerUri = innerUri; _partName = partName; // may not be null _mimeType = null; // until we find out the real value // delegate work to private class _cachedResponse = new CachedResponse(this, cacheEntry, cachedPackageIsThreadSafe); } //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- #region WebResponse Overloads ////// Retrieves a stream for reading bytes from the requested resource /// ///stream ////// Critical /// 1) Passes Critical member _webRequest to NetStream constructor /// Safe /// 1) Providing _webRequest to NetStream is safe because NetStream treats _webRequest as Critical /// [SecurityCritical, SecurityTreatAsSafe] public override Stream GetResponseStream() { CheckDisposed(); // redirect if (FromPackageCache) return _cachedResponse.GetResponseStream(); if (EventTrace.IsEnabled(EventTrace.Flags.performance, EventTrace.Level.normal)) { EventTrace.EventProvider.TraceEvent(EventTrace.GuidFromId(EventTraceGuidId.DRXGETSTREAMGUID), EventType.StartEvent); } #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.GetStream(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.NormalTraceEvent(EventTraceGuidId.DRXGETSTREAMGUID, EventType.EndEvent); return _responseStream; } ////// Close stream /// public override void Close() { Dispose(true); } #endregion //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ ////// InnerResponse /// ///inner WebResponse public WebResponse InnerResponse { get { CheckDisposed(); // no inner response if (FromPackageCache) return null; // can't do this until the response is available WaitForResponse(); return _fullResponse; } } ////// Headers /// ///web headers public override WebHeaderCollection Headers { get { CheckDisposed(); // redirect if (FromPackageCache) return _cachedResponse.Headers; // can't do this until the response is available WaitForResponse(); return _fullResponse.Headers; } } ////// ResponseUri /// ///Fully-qualified pack uri reflecting any server redirection. ///For the inner ResponseUri access the InnerResponse like this: /// Uri innerResponseUri = packResponse.InnerResponse.ResponseUri public override Uri ResponseUri { get { CheckDisposed(); // If data is served from a cached package, we simply return the original, fully-qualified // pack uri. if (FromPackageCache) return _uri; else { // If data is served from an actual webResponse, we need to re-compose the original pack uri // with the responseUri provided by the real webResponse to account for server redirects. // We can't do this until the response is available so we wait. WaitForResponse(); // create new pack uri with webResponse and original part name uri return PackUriHelper.Create(_fullResponse.ResponseUri, _partName); } } } ////// IsFromCache /// ///true if result is from the cache public override bool IsFromCache { get { CheckDisposed(); // quick answer if (FromPackageCache) return true; // can't do this until the response is available WaitForResponse(); return _fullResponse.IsFromCache; } } ////// ContentType /// ///string ///There are four separate results possible from this property. If the PartName is /// empty, then the container MIME type is returned. If it is not, we return the MIME type of the /// stream in the following order or preference: /// 1. If the PackagePart offers a MIME type, we return that /// 2. If the stream name has an extension, we determine the MIME type from that using a lookup table /// 3. We return String.Empty if no extension is found. public override string ContentType { get { CheckDisposed(); // No need to wait if working from cache // But we can share the logic as none of it hits the _webResponse if (!FromPackageCache) { // can't do this until the response is available WaitForResponse(); } // cache the value - if it's empty that means we already tried (and failed) to find a real type if (_mimeType == null) { // Get the response stream which has the side effect of setting the _mimeType member. GetResponseStream(); } return _mimeType.ToString(); } } ////// ContentLength /// ///length of response stream public override long ContentLength { get { CheckDisposed(); // redirect if (FromPackageCache) return _cachedResponse.ContentLength; // can't do this until the response is available WaitForResponse(); // is the length available? if (!_lengthAvailable) { _fullStreamLength = GetResponseStream().Length; _lengthAvailable = true; } // use the stored value return _fullStreamLength; } } //----------------------------------------------------- // // Internal Properties // //------------------------------------------------------ //----------------------------------------------------- // // Private Methods // //----------------------------------------------------- ////// AbortResponse - called only from Close() /// ///assumes caller has locked the syncObject and that we are not disposed ////// Critical /// 1) accesses Critical _webRequest /// Safe /// 1) Not modifying WebRequest.Proxy member which is what is really Critical /// [SecurityCritical, SecurityTreatAsSafe] private void AbortResponse() { // Disable the PreSharp warning about empty catch blocks - we need this one because sub-classes of WebResponse may or may // not implement Abort() and we want to silently ignore this if they don't. #pragma warning disable 56502 // Close was called - abort the response if necessary try { // Only abort if the response is still "outstanding". // Non-blocking "peek" at the event to see if it is set or not. if (!_responseAvailable.WaitOne(0, false)) { _webRequest.Abort(); // response not back yet so abort it } } catch (NotImplementedException) { // Ignore - innerRequest class chose to implement BeginGetResponse but not Abort. This is allowed. } #pragma warning restore 56502 } ////// This is private instead of protected because this class is sealed - if it is ever unsealed, this method should /// be made protected and GC.SuppressFinalize() should be enabled at the end of Dispose call. /// /// private void Dispose(bool disposing) { if (!_disposed) { if (disposing) { // ignore multiple calls to Close() // no lock required here because the only place where _disposed is changed is later in this same function and this // function is never entered by more than one thread if (_disposed) return; // redirect for cache case // NOTE: FromPackageCache need not be synchronized because it is only set once in the constructor and never // changes. if (FromPackageCache) { _cachedResponse.Close(); // indirectly sets _disposed on this class _cachedResponse = null; // release return; } #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse.Close()"); #endif // prevent async callback from accessing these resources while we are disposing them lock (_lockObject) { try { // abort any outstanding response AbortResponse(); // prevent recursion in our call to _responseStream.Close() _disposed = true; if (_responseStream != null) { #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse.Close() - close stream"); #endif _responseStream.Close(); } // FullResponse if (_fullResponse != null) { #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse.Close() - close response"); #endif // always call Dispose to satisfy FxCop ((IDisposable)_fullResponse).Dispose(); } // must free this regardless of whether GetResponseStream was invoked _responseAvailable.Close(); // this call can not throw an exception // timer if (_timeoutTimer != null) { _timeoutTimer.Dispose(); } } finally { _timeoutTimer = null; _responseStream = null; _fullResponse = null; _responseAvailable = null; #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse.Close() - exiting"); #endif } } // lock } } } //----------------------------------------------------- // // Private Properties // //------------------------------------------------------ private bool FromPackageCache { get { return (_cachedResponse != null); } } //----------------------------------------------------- // // Private Classes // //------------------------------------------------------ ////// CachedResponse class /// ///Isolate cache-specific functionality to reduce complexity private class CachedResponse { //------------------------------------------------------ // // Internal Methods // //----------------------------------------------------- internal CachedResponse(PackWebResponse parent, Package cacheEntry, bool cachedPackageIsThreadSafe) { _parent = parent; _cacheEntry = cacheEntry; _cachedPackageIsThreadSafe = cachedPackageIsThreadSafe; } ////// Cache version of GetResponseStream /// ///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.GetStream(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; } /// /// Release some resources /// internal void Close() { try { // Prevent recursion - this sync-protected member is safe to set in a CachedResponse // mode because we have no other thread in operation. _parent._disposed = true; if (_parent._responseStream != null) _parent._responseStream.Close(); } finally { _cacheEntry = null; _parent._uri = null; _parent._mimeType = null; _parent._innerUri = null; _parent._partName = null; _parent._responseStream = null; _parent = null; } } //------------------------------------------------------ // // Internal Properties // //----------------------------------------------------- internal WebHeaderCollection Headers { get { // empty - bogus collection - prevents exceptions for callers return new WebHeaderCollection(); } } public long ContentLength { get { // if fullStreamLength not already set, get the stream which has // the side effect of updating the length if (!_parent._lengthAvailable) GetResponseStream(); return _parent._fullStreamLength; } } // fields private PackWebResponse _parent; private Package _cacheEntry; private bool _cachedPackageIsThreadSafe; } ////// Throw exception if we are already closed /// private void CheckDisposed() { // no need to lock here because only Close() sets this variable and we are not ThreadSafe if (_disposed) throw new ObjectDisposedException("PackWebResponse"); } ////// ResponseCallBack /// /// async result ///static method not necessary ////// Critical /// 1) calls EndGetResponse() on Critical member _webRequest /// [SecurityCritical] private void ResponseCallback(IAsyncResult ar) { lock (_lockObject) // prevent race condition accessing _timeoutTimer, _disposed, _responseAvailable { try { // If disposed, the message is too late // Exit early and don't access members as they have been disposed if (!_disposed) { // dispose the timer - it is no longer needed if (_timeoutTimer != null) _timeoutTimer.Dispose(); #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse.ResponseCallBack()"); #endif // Dispose/Close waits on _responseAvailable so we know that these are available // No need to lock. // Call EndGetResponse, which produces the WebResponse object // that came from the request issued above. _fullResponse = MS.Internal.WpfWebRequestHelper.EndGetResponse(_webRequest, ar); } } catch (WebException e) { // web exceptions are meaningful to our client code - keep these to re-throw on the other thread _responseException = e; _responseError = true; } catch // catch (and re-throw) all kinds of exceptions so we can inform the other thread { #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceError( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse.ResponseCallBack() exception"); #endif // inform other thread of error condition _responseError = true; throw; } finally { _timeoutTimer = null; // harmless if already null, and removes need for extra try/finally block above #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse.ResponseCallBack() - signal response available"); #endif // We need the original webRequest to get HttpStack information so that they can be used to make // additional byte range request; So we cannot null it out anymore // _webRequest = null; // don't need this anymore so release // this must be set even when there is an exception so that our client // can be unblocked // make sure this wasn't already free'd when the Timercallback thread released // the blocked Close() thread if (!_disposed) _responseAvailable.Set(); } } } ////// All methods that need to access variables only available after the response callback has been /// handled should call this to block. Doing it in one place simplifies our need to respond to any /// exceptions encountered in the other thread and rethrow these. /// private void WaitForResponse() { #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse.WaitForResponse()"); #endif // wait for the response callback _responseAvailable.WaitOne(); // We get here only when the other thread signals. // Need to inspect for errors and throw if there was trouble on the other thread. if (_responseError) { if (_responseException == null) throw new WebException(SR.Get(SRID.WebResponseFailure)); else throw _responseException; // throw literal exception if there is one } } ////// Timeout callback /// /// private void TimeoutCallback(Object stateInfo) { lock (_lockObject) // prevent race condition accessing _timeoutTimer, _disposed, _responseAvailable { // If disposed, the message is too late // Exit early and don't access members as they have been disposed // Let Close() method clean up our Timer object if (_disposed) return; try { // If we get called, need to check if response is available before escalating // just in case it arrived "just now". If the event is already signalled, we can ignore // the callback as no "timeout" occurred. if (!_responseAvailable.WaitOne(0, false)) { #if DEBUG if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceError( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse.TimerCallback() timeout - throwing exception"); #endif // caller is still blocked so need to throw to indicate timeout // create exception to be thrown on client thread, then unblock the caller // thread will be discovered and re-thrown in WaitForResponse() method _responseError = true; _responseException = new WebException(SR.Get(SRID.WebRequestTimeout, null), WebExceptionStatus.Timeout); } #if DEBUG else { if (PackWebRequestFactory._traceSwitch.Enabled) System.Diagnostics.Trace.TraceInformation( DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " + System.Threading.Thread.CurrentThread.ManagedThreadId + ": " + "PackWebResponse.TimerCallback() no timeout - ignoring callback"); } #endif // clean up if (_timeoutTimer != null) { _timeoutTimer.Dispose(); } } finally { _timeoutTimer = null; if (!_disposed) { // this must be set so that our client can be unblocked and then discover the exception _responseAvailable.Set(); } } } // lock } //----------------------------------------------------- // // Private Fields // //----------------------------------------------------- private MS.Internal.ContentType _mimeType; // type of the returned stream - cached because it never changes private const int _bufferSize = 0x1000; // 4k private Uri _uri; // full uri private Uri _innerUri; // inner uri private Uri _partName; // path to stream private bool _disposed; // closed? ////// Critical /// 1) Proxy member is Critical because we use it under Unrestricted assert /// [SecurityCritical] // only WebRequest.Proxy member is Critical private WebRequest _webRequest; // the real web request private WebResponse _fullResponse; // the real web response private long _fullStreamLength; // need to return this in call to get_Length private Stream _responseStream; // mimic existing Response behavior by creating and returning // one and only one stream private bool _responseError; // will be true if exception occurs calling EndGetResponse() private Exception _responseException; // actual exception to throw (if any) private Timer _timeoutTimer; // used if Timeout specified // OS event used to signal that the response is available private ManualResetEvent _responseAvailable; // protects access to _fullResponse object // flag to signal that _fullStreamLength is valid - needed because some servers don't return // the length (usually FTP servers) so calls to Stream.Length must block until we know the actual length. private bool _lengthAvailable; // PackageCache response? private CachedResponse _cachedResponse; // null if cache not used // private object to prevent deadlock (should not lock(_lockObject) based on PreSharp rule 6517) private Object _lockObject; // Serialize access to _disposed, _timoutTimer and _responseAvailable because even though the main client // thread blocks on WaitForResponse (_responseAvailable event) the optional Timer thread and the // Response callback thread may arrive independently at any time. #if DEBUG // toggle this switch to force execution of code that handles servers that return bogus content length internal static System.Diagnostics.BooleanSwitch _forceWebResponseLengthFailureSwitch; #endif } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ChineseLunisolarCalendar.cs
- DataGridComboBoxColumn.cs
- RegionData.cs
- ListenerUnsafeNativeMethods.cs
- AttributeCollection.cs
- WinInet.cs
- CurrencyManager.cs
- DataKeyCollection.cs
- FixedSOMLineRanges.cs
- UpdateTranslator.cs
- LayoutDump.cs
- AppliesToBehaviorDecisionTable.cs
- UnsafeNativeMethods.cs
- MaterialCollection.cs
- ResourceDisplayNameAttribute.cs
- IsolatedStorageFile.cs
- TransformerInfo.cs
- BindingMAnagerBase.cs
- SerialErrors.cs
- Set.cs
- Win32Native.cs
- LockCookie.cs
- SystemColorTracker.cs
- AsymmetricKeyExchangeFormatter.cs
- DatatypeImplementation.cs
- EventMap.cs
- QueryOutputWriter.cs
- DeflateStream.cs
- BinaryConverter.cs
- HttpProfileBase.cs
- DbXmlEnabledProviderManifest.cs
- RegexInterpreter.cs
- EncoderBestFitFallback.cs
- ProfileProvider.cs
- ToolStripSplitStackLayout.cs
- IndexingContentUnit.cs
- EntityProviderServices.cs
- EntityCommandDefinition.cs
- ReachPrintTicketSerializer.cs
- ZipFileInfoCollection.cs
- EqualityComparer.cs
- XmlSchemaAnnotation.cs
- OledbConnectionStringbuilder.cs
- ParserOptions.cs
- BindingMAnagerBase.cs
- BamlCollectionHolder.cs
- DocumentCollection.cs
- StylusCaptureWithinProperty.cs
- WindowsAuthenticationEventArgs.cs
- MenuItem.cs
- DataServiceConfiguration.cs
- QuaternionAnimationUsingKeyFrames.cs
- EnterpriseServicesHelper.cs
- X509Chain.cs
- XmlAtomicValue.cs
- Part.cs
- RolePrincipal.cs
- ChainOfDependencies.cs
- SoapObjectWriter.cs
- BaseTreeIterator.cs
- Help.cs
- ListControl.cs
- SiteMapSection.cs
- EntityParameter.cs
- SchemaComplexType.cs
- RectangleConverter.cs
- SimpleWebHandlerParser.cs
- LinearQuaternionKeyFrame.cs
- ColorBuilder.cs
- Panel.cs
- WebPartConnectionsCancelEventArgs.cs
- HasCopySemanticsAttribute.cs
- BinHexDecoder.cs
- ObjectKeyFrameCollection.cs
- InstanceContext.cs
- DbDataReader.cs
- Instrumentation.cs
- HuffmanTree.cs
- SmiConnection.cs
- DynamicVirtualDiscoSearcher.cs
- WebRequestModuleElementCollection.cs
- SignatureHelper.cs
- DynamicRendererThreadManager.cs
- Light.cs
- DatatypeImplementation.cs
- SiteMapNodeItemEventArgs.cs
- ChangeBlockUndoRecord.cs
- SafeSecurityHelper.cs
- AttachInfo.cs
- PanelDesigner.cs
- NavigationWindow.cs
- WindowsUserNameSecurityTokenAuthenticator.cs
- ContainerUIElement3D.cs
- SqlProcedureAttribute.cs
- _UriSyntax.cs
- _HeaderInfo.cs
- BaseTemplateParser.cs
- ImageDrawing.cs
- HMACMD5.cs
- ProgramNode.cs