Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / IO / Packaging / PackWebRequest.cs / 2 / PackWebRequest.cs
//------------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// Description:
// WebRequest class to handle pack-specific URI's
//
// History:
// 10/09/2003: [....]: Created.
// 11/25/2003: [....]: Removed IDisposable and create a new WebResponse for
// each call to GetResponse().
// 01/08/2004: [....]: Disable serialization
// 05/10/2004: [....]: Convert to pack scheme
// 04/26/2005: [....]: Hold and return whatever credentials are provided by caller in cache case
// 09/21/2005: [....]: Delay inner-webrequest creation until a WebRequest property is set/get so
// that requests that hit a cached package don't require WebPermission.
//
//-----------------------------------------------------------------------------
#if DEBUG
#define TRACE
#endif
using System;
using System.IO;
using System.Net;
using System.Net.Cache; // for RequestCachePolicy
using System.Runtime.Serialization;
using System.Diagnostics; // For Assert
using MS.Utility; // for EventTrace
using MS.Internal.IO.Packaging; // for PackageCacheEntry
using MS.Internal.PresentationCore; // for SRID exception strings
using System.Security; // for SecurityCritical
using MS.Internal;
namespace System.IO.Packaging
{
///
/// pack-specific WebRequest handler
///
///
/// This WebRequest overload exists to handle pack-specific URI's based on the "pack" custom schema.
/// Note that this schema may or may not be "registered" with the .NET WebRequest factory so callers
/// should be sure to use the PackUriHelper static class to prepare their Uri's. PackUriHelper use has the
/// side effect of registering the "pack" scheme and associating the PackWebRequest class as its default handler.
///
public sealed class PackWebRequest : WebRequest
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
///
/// Constructor
///
/// uri to resolve
/// uri of the package
/// uri of the part - may be null
/// This should only be called by PackWebRequestFactory
/// Will throw an ArgumentException if the given URI is not of the correct scheme
internal PackWebRequest(Uri uri, Uri packageUri, Uri partUri)
: this(uri, packageUri, partUri, null, false, false)
{
}
///
/// Cached instance constructor
///
/// cache entry to base this response on
/// uri to resolve
/// uri of the package
/// uri of the part - may be null
/// should we throw if cache policy conflicts?
/// is the cacheEntry thread-safe?
/// This should only be called by PackWebRequestFactory
/// Will throw an ArgumentException if the given URI is not of the correct scheme
internal PackWebRequest(Uri uri, Uri packageUri, Uri partUri, Package cacheEntry,
bool respectCachePolicy, bool cachedPackageIsThreadSafe)
{
Debug.Assert(uri != null, "PackWebRequest uri cannot be null");
Debug.Assert(packageUri != null, "packageUri cannot be null");
// keep these
_uri = uri;
_innerUri = packageUri;
_partName = partUri;
_cacheEntry = cacheEntry;
_respectCachePolicy = respectCachePolicy;
_cachedPackageIsThreadSafe = cachedPackageIsThreadSafe;
_cachePolicy = _defaultCachePolicy; // always use default and then let them change it
#if DEBUG
if (PackWebRequestFactory._traceSwitch.Enabled && (cacheEntry != null))
System.Diagnostics.Trace.TraceInformation(
DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
System.Threading.Thread.CurrentThread.ManagedThreadId + ": " +
"PackWebRequest - working from Package Cache");
#endif
}
//------------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
#region WebRequest - Sync
///
/// GetRequestStream
///
/// stream
/// writing not supported
public override Stream GetRequestStream()
{
throw new NotSupportedException();
}
///
/// Returns a WebResponse object
///
/// PackWebResponse
/// Caller must eventually call Close() to avoid leaking resources.
///
/// Critical
/// 1) accesses Critical _webRequest
/// 2) calling Critical PackWebResponse constructor
/// Safe
/// 1) PublicOK
/// 2) PublicOK
///
[SecurityCritical]
public override WebResponse GetResponse()
{
bool cachedPackageAvailable = IsCachedPackage;
// if there is no cached package or it is from the public PackageStore, we must respect CachePolicy
if (!cachedPackageAvailable || (cachedPackageAvailable && _respectCachePolicy))
{
// inspect and act on CachePolicy
RequestCacheLevel policy = _cachePolicy.Level;
if (policy == RequestCacheLevel.Default)
policy = _defaultCachePolicy.Level;
switch (policy)
{
case RequestCacheLevel.BypassCache:
{
// ignore cache entry
cachedPackageAvailable = false;
} break;
case RequestCacheLevel.CacheOnly:
{
// only use cached value
if (!cachedPackageAvailable)
throw new WebException(SR.Get(SRID.ResourceNotFoundUnderCacheOnlyPolicy));
} break;
case RequestCacheLevel.CacheIfAvailable:
{
// use cached value if possible - we need take no explicit action here
} break;
default:
{
throw new WebException(SR.Get(SRID.PackWebRequestCachePolicyIllegal));
}
}
}
if (cachedPackageAvailable)
{
#if DEBUG
if (PackWebRequestFactory._traceSwitch.Enabled)
System.Diagnostics.Trace.TraceInformation(
DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
System.Threading.Thread.CurrentThread.ManagedThreadId + ": " +
"PackWebRequest - Getting response from Package Cache");
#endif
return new PackWebResponse(_uri, _innerUri, _partName, _cacheEntry, _cachedPackageIsThreadSafe);
}
else
{
// only return a real WebRequest instance - throw on a PseudoWebRequest
WebRequest request = GetRequest(false);
if (_webRequest == null || _webRequest is PseudoWebRequest)
throw new InvalidOperationException(SR.Get(SRID.SchemaInvalidForTransport));
#if DEBUG
if (PackWebRequestFactory._traceSwitch.Enabled)
System.Diagnostics.Trace.TraceInformation(
DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
System.Threading.Thread.CurrentThread.ManagedThreadId + ": " +
"PackWebRequest - Getting new response");
#endif
// Create a new response for every call
return new PackWebResponse(_uri, _innerUri, _partName, request);
}
}
#endregion
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
#region Properties
///
/// CachePolicy for the PackWebRequest
///
/// This value is distinct from the CachePolicy of the InnerRequest.
///
public override RequestCachePolicy CachePolicy
{
get
{
return _cachePolicy;
}
set
{
if (value == null)
_cachePolicy = _defaultCachePolicy;
else
{
switch (value.Level)
{
case RequestCacheLevel.BypassCache: break;
case RequestCacheLevel.CacheOnly: break;
case RequestCacheLevel.CacheIfAvailable: break;
default:
throw new WebException(SR.Get(SRID.PackWebRequestCachePolicyIllegal));
}
_cachePolicy = value;
}
}
}
///
/// ConnectionGroupName
///
/// This value is shared with the InnerRequest.
/// name of current connection group
public override string ConnectionGroupName
{
get
{
return GetRequest().ConnectionGroupName;
}
set
{
GetRequest().ConnectionGroupName = value;
}
}
///
/// ContentLength
///
/// length of RequestStream
/// This value is shared with the InnerRequest.
/// Set is not supported as PackWebRequest is read-only.
public override long ContentLength
{
get
{
return GetRequest().ContentLength;
}
set
{
// we don't upload so no reason to support this
throw new NotSupportedException();
}
}
///
/// ContentType
///
/// Content type of the request data being sent or data being requested. Null is explicitly allowed.
/// This value is shared with the InnerRequest.
public override string ContentType
{
get
{
string contentType = GetRequest().ContentType;
if (contentType == null)
return contentType;
else
//We call the ContentType constructor to validate the grammar for
//content type string.
return new MS.Internal.ContentType(contentType).ToString();
}
set
{
// this property can indicate to the server what content type we prefer
GetRequest().ContentType = value;
}
}
///
/// Credentials
///
/// Credentials to use when authenticating against the resource
/// This value is shared with the InnerRequest.
public override ICredentials Credentials
{
get
{
return GetRequest().Credentials;
}
set
{
GetRequest().Credentials = value;
}
}
///
/// Headers
///
/// collection of header name/value pairs associated with the request
/// This value is shared with the InnerRequest.
public override WebHeaderCollection Headers
{
get
{
return GetRequest().Headers;
}
set
{
GetRequest().Headers = value;
}
}
///
/// Method
///
/// protocol method to use in this request
/// This value is shared with the InnerRequest.
public override string Method
{
get
{
return GetRequest().Method;
}
set
{
GetRequest().Method = value;
}
}
///
/// PreAuthenticate
///
/// indicates whether to preauthenticate the request
/// This value is shared with the InnerRequest.
public override bool PreAuthenticate
{
get
{
return GetRequest().PreAuthenticate;
}
set
{
GetRequest().PreAuthenticate = value;
}
}
///
/// Proxy
///
/// network proxy to use to access this Internet resource
/// This value is shared with the InnerRequest.
///
/// Critical
/// 1) gets/sets Critical member _webRequest.Proxy()
/// Safe
/// 2) PublicOK
///
public override IWebProxy Proxy
{
[SecurityCritical]
get
{
return GetRequest().Proxy;
}
[SecurityCritical]
set
{
GetRequest().Proxy = value;
}
}
///
/// RequestUri
///
/// URI of the Internet resource associated with the request
public override Uri RequestUri
{
get
{
return _uri;
}
}
///
/// Timeout
///
/// length of time before the request times out
/// This value is shared with the InnerRequest.
/// Value must be >= -1
public override int Timeout
{
get
{
return GetRequest().Timeout;
}
set
{
// negative time that is not -1 (infinite) is an error case
if (value < 0 && value != System.Threading.Timeout.Infinite)
throw new ArgumentOutOfRangeException("value");
GetRequest().Timeout = value;
}
}
///
/// UseDefaultCredentials
///
public override bool UseDefaultCredentials
{
get
{
return GetRequest().UseDefaultCredentials;
}
set
{
GetRequest().UseDefaultCredentials = value;
}
}
#endregion
#region New Properties
///
/// GetInnerRequest
///
/// Inner WebRequest object.
/// Inner uri is not resolvable to a valid transport protocol (such as
/// ftp or http) and the request cannot be satisfied from the PackageStore.
/// The inner WebRequest is provided for advanced scenarios only and
/// need not be accessed in most cases.
/// A WebRequest created using the inner-uri or null if the inner uri is not resolvable and we
/// have a valid PackageStore entry that can be used to provide data.
public WebRequest GetInnerRequest()
{
WebRequest request = GetRequest(false);
if (request == null || request is PseudoWebRequest)
return null;
return request;
}
#endregion
//-----------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
//-----------------------------------------------------
//
// Internal Properties
//
//-----------------------------------------------------
//-----------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
///
/// Returns a WebRequest - should be called from properties
///
/// Actual WebRequest or PseudoWebRequest
/// protocol does not have a registered handler
private WebRequest GetRequest()
{
return GetRequest(true);
}
///
/// Returns a WebRequest - can be called from properties and from GetInnerRequest()
///
/// if this is false, caller will not accept a PseudoWebRequest
/// Actual WebRequest or PseudoWebRequest
/// protocol does not have a registered handler
///
/// Critical
/// 1) accesses Critical _webRequest
/// Safe
/// 1) Not modifying Proxy member which is what is really Critical
///
[SecurityCritical, SecurityTreatAsSafe]
private WebRequest GetRequest(bool allowPseudoRequest)
{
if (_webRequest == null)
{
// Don't even attempt to create if we know it will fail. This does not eliminate all failure cases
// but most and is very common so let's save an expensive exception.
// We still create a webRequest if possible even if we have a potential cacheEntry
// because the caller may still specify BypassCache policy before calling GetResponse() that will force us to hit the server.
if (!IsPreloadedPackage)
{
// Need inner request so we can get/set properties or create a real WebResponse.
// Note: WebRequest.Create throws NotSupportedException for schemes that it does not recognize.
// We need to be open-ended in our support of schemes, so we need to always try to create.
// If WebRequest throws NotSupportedException then we catch and ignore if the WebRequest can be
// satisfied from the cache. If the cache entry is missing then we simply re-throw because the request
// cannot possibly succeed.
try
{
_webRequest = WpfWebRequestHelper.CreateRequest(_innerUri);
// special optimization for ftp - Passive mode won't return lengths on ISA servers
FtpWebRequest ftpWebRequest = _webRequest as FtpWebRequest;
if (ftpWebRequest != null)
{
ftpWebRequest.UsePassive = false; // default but allow override
}
}
catch (NotSupportedException)
{
// If the inner Uri does not match any cache entry then we throw.
if (!IsCachedPackage)
throw;
}
}
// Just return null if caller cannot accept a PseudoWebRequest
if (_webRequest == null && allowPseudoRequest)
{
// We get here if the caller can accept a PseudoWebRequest (based on argument to the function)
// and one of these two cases is true:
// 1. We have a package from the PreloadedPackages collection
// 2. If WebRequest.Create() failed and we have a cached package
// In either case, we create a pseudo request to house property values.
// In case 1, we know there will never be a cache bypass (we ignore cache policy for PreloadedPackages)
// In case 2, the caller is using a schema that we cannot use for transport (not on of ftp, http, file, etc)
// and we will silently accept and ignore their property modifications/queries.
// Note that if they change the cache policy to BypassCache they will get an exception when they call
// GetResponse(). If they leave cache policy intact, and call GetResponse()
// they will get data from the cached package.
_webRequest = new PseudoWebRequest(_uri, _innerUri, _partName, _cacheEntry);
}
}
return _webRequest;
}
//-----------------------------------------------------
//
// Private Properties
//
//------------------------------------------------------
///
/// True if we have a package from either that PreloadedPackages or PackageStore
///
private bool IsCachedPackage
{
get
{
return (_cacheEntry != null);
}
}
///
/// True only if we have a package from PreloadedPackages
///
private bool IsPreloadedPackage
{
get
{
// _respectCachePolicy is only false for packages retrieved from PreloadedPackages
return ((_cacheEntry != null) && (!_respectCachePolicy));
}
}
//------------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
private Uri _uri; // pack uri
private Uri _innerUri; // inner uri extracted from the pack uri
private Uri _partName; // name of PackagePart (if any) - null for full-container references
[SecurityCritical] // only WebRequest.Proxy member is Critical
private WebRequest _webRequest; // our "real" webrequest counterpart - may be a PseudoWebRequest
private Package _cacheEntry; // non-null if we found this in a cache
private bool _respectCachePolicy; // do we throw if cache policy conflicts?
private bool _cachedPackageIsThreadSafe; // pass to WebResponse so it can safely return streams
private RequestCachePolicy _cachePolicy; // outer cache-policy
// statics
static private RequestCachePolicy _defaultCachePolicy = new RequestCachePolicy(RequestCacheLevel.CacheIfAvailable);
// These are "cached" inner Uri's taken from the available application: and SiteOfOrigin: Uri's.
// They are kept in statics to eliminate overhead of reparsing them on every request.
// We are essentially extracting the "application://" out of "pack://application:,,"
static private Uri _siteOfOriginUri = PackUriHelper.GetPackageUri(System.Windows.Navigation.BaseUriHelper.SiteOfOriginBaseUri);
static private Uri _appBaseUri = PackUriHelper.GetPackageUri(System.Windows.Navigation.BaseUriHelper.PackAppBaseUri);
}
}
// 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
- XmlHierarchyData.cs
- UriExt.cs
- SamlSerializer.cs
- DesignerActionVerbItem.cs
- QueryCacheKey.cs
- ExceptionUtility.cs
- Visual3DCollection.cs
- SoapTypeAttribute.cs
- StateMachineWorkflowDesigner.cs
- HttpResponseHeader.cs
- PageAsyncTask.cs
- OledbConnectionStringbuilder.cs
- DiscardableAttribute.cs
- ParserOptions.cs
- Attributes.cs
- DispatchWrapper.cs
- Hex.cs
- MetaData.cs
- PolicyManager.cs
- TypeElement.cs
- TraceFilter.cs
- HitTestWithGeometryDrawingContextWalker.cs
- WebHttpBehavior.cs
- RowParagraph.cs
- WindowsGraphics.cs
- FormViewModeEventArgs.cs
- OLEDB_Util.cs
- DefaultPropertyAttribute.cs
- StylusPlugin.cs
- HttpServerVarsCollection.cs
- PointF.cs
- NoClickablePointException.cs
- ListBoxItem.cs
- TaiwanLunisolarCalendar.cs
- WebControl.cs
- SequenceFullException.cs
- ItemAutomationPeer.cs
- HighlightVisual.cs
- QilIterator.cs
- EventLevel.cs
- WebRequestModuleElementCollection.cs
- AsymmetricKeyExchangeFormatter.cs
- ReachSerializableProperties.cs
- Grant.cs
- Label.cs
- BamlMapTable.cs
- ErrorHandlerFaultInfo.cs
- HtmlTableRow.cs
- ObjectIDGenerator.cs
- AssertSection.cs
- X509CertificateCollection.cs
- AsymmetricAlgorithm.cs
- GridViewEditEventArgs.cs
- XmlSchemaElement.cs
- DebugTrace.cs
- WeakEventTable.cs
- _SafeNetHandles.cs
- HwndHost.cs
- ConsumerConnectionPoint.cs
- MutableAssemblyCacheEntry.cs
- SoapConverter.cs
- RegisteredArrayDeclaration.cs
- InvalidPropValue.cs
- ErrorProvider.cs
- XmlWriterDelegator.cs
- FormatException.cs
- PointLight.cs
- StringToken.cs
- HitTestParameters3D.cs
- MSAAEventDispatcher.cs
- UnicodeEncoding.cs
- GraphicsPathIterator.cs
- Table.cs
- PriorityBinding.cs
- METAHEADER.cs
- ExternalFile.cs
- NullExtension.cs
- XPathParser.cs
- CacheOutputQuery.cs
- RegistrationServices.cs
- Label.cs
- TracePayload.cs
- InputDevice.cs
- WhiteSpaceTrimStringConverter.cs
- ByteRangeDownloader.cs
- LazyTextWriterCreator.cs
- HttpRequestCacheValidator.cs
- GAC.cs
- ExpressionBuilderContext.cs
- documentsequencetextcontainer.cs
- SubstitutionDesigner.cs
- ObfuscateAssemblyAttribute.cs
- CalendarModeChangedEventArgs.cs
- SecurityKeyIdentifierClause.cs
- Function.cs
- CurrencyManager.cs
- ForceCopyBuildProvider.cs
- SocketManager.cs
- DictionarySectionHandler.cs
- EntityConnection.cs