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
- Debugger.cs
- ActivityDesignerHighlighter.cs
- OptionUsage.cs
- ApplicationDirectory.cs
- ScriptResourceInfo.cs
- StatusBarItemAutomationPeer.cs
- PageThemeBuildProvider.cs
- RadioButton.cs
- RemoteWebConfigurationHostStream.cs
- StringFormat.cs
- InternalResources.cs
- ResourcePool.cs
- PtsHelper.cs
- CustomAttributeFormatException.cs
- X509Certificate2.cs
- SingleResultAttribute.cs
- HttpProfileGroupBase.cs
- ParserHooks.cs
- LiteralControl.cs
- WebHeaderCollection.cs
- WebServiceResponseDesigner.cs
- AppDomainManager.cs
- CreateUserErrorEventArgs.cs
- clipboard.cs
- WindowsRichEdit.cs
- StreamWriter.cs
- CrossSiteScriptingValidation.cs
- CapabilitiesAssignment.cs
- StoreItemCollection.Loader.cs
- ViewKeyConstraint.cs
- SocketInformation.cs
- KnownColorTable.cs
- SqlError.cs
- ExtendedTransformFactory.cs
- LogManagementAsyncResult.cs
- DateTimeParse.cs
- LinearKeyFrames.cs
- Facet.cs
- TypeElementCollection.cs
- GlyphShapingProperties.cs
- XmlSchemaElement.cs
- ComplexTypeEmitter.cs
- ArithmeticException.cs
- MenuItemCollection.cs
- DataGridViewUtilities.cs
- AssemblyInfo.cs
- ByteStorage.cs
- CodeIdentifier.cs
- WindowsGraphics.cs
- ObfuscationAttribute.cs
- EastAsianLunisolarCalendar.cs
- Graph.cs
- SiteMapHierarchicalDataSourceView.cs
- DbException.cs
- XDRSchema.cs
- AdCreatedEventArgs.cs
- DataGridLength.cs
- FormsIdentity.cs
- ParameterBuilder.cs
- StringAnimationBase.cs
- ScrollPattern.cs
- EntityDataSourceContextCreatedEventArgs.cs
- CharAnimationUsingKeyFrames.cs
- ResourceReferenceExpressionConverter.cs
- TextRunTypographyProperties.cs
- PlanCompilerUtil.cs
- StylusEditingBehavior.cs
- CollectionViewGroupRoot.cs
- StreamUpgradeAcceptor.cs
- CroppedBitmap.cs
- AttributeAction.cs
- CodeTypeConstructor.cs
- KoreanLunisolarCalendar.cs
- ControlAdapter.cs
- AssemblyAttributesGoHere.cs
- GeneralTransformGroup.cs
- ReliabilityContractAttribute.cs
- ResolveMatches11.cs
- Variant.cs
- Drawing.cs
- PropertyGridView.cs
- selecteditemcollection.cs
- IISMapPath.cs
- OraclePermissionAttribute.cs
- DuplicateDetector.cs
- DataTableCollection.cs
- GeometryModel3D.cs
- FloaterBaseParagraph.cs
- CollectionDataContractAttribute.cs
- SafeEventLogWriteHandle.cs
- CollectionBase.cs
- EmptyEnumerable.cs
- ListenerElementsCollection.cs
- CompiledScopeCriteria.cs
- BaseDataListDesigner.cs
- TemplateLookupAction.cs
- FileRecordSequence.cs
- ControlPropertyNameConverter.cs
- TemplatePagerField.cs
- Registry.cs