2025-04-27 07:49:33 -04:00

166 lines
5.5 KiB
Plaintext

/*++
Copyright (c) 1999 Microsoft Corporation
Module Name :
ulcachemodule.cool
Abstract:
Module which drives UL caching responses
Author:
Bilal Alam (BAlam) 13-Oct-99
Environment:
COM+ - User Mode Managed Run Time
Project:
Web Server
--*/
using System;
using System.Collections;
using System.ASP;
using System.IIS.Hosting;
namespace System.IIS
{
public class UlCacheModule : HttpModuleSync
{
public override void Leave( HttpContext context )
{
HttpCachePolicySettings cacheSettings;
ULWorkerRequest workerRequest;
string strFlushUrl;
OnCacheItemFlush flushDelegate;
bool fAnonymousAccessAllowed = false;
Dictionary contentOptions;
string strCacheDisable;
//
// Cache the response in UL if both:
// a) The cache-control policy is public
// b) DontCacheOnServer is false
// c) The response was 200 AND the user was anonymous
// This implies that an anonymous user could get the
// content and thus it is cacheable in UL.
//
// BUGBUG: Eventually we'll need to tie config to this
// so that XSP flushed the UL entry when config
// has changed
//
if ( !( context.User is System.ASP.Security.AnonymousUser ) )
{
context.Response.Cache.SetCacheability( HttpCacheability.Private );
}
if ( context.Response.StatusCode == HttpStatus.Ok &&
context.User is System.ASP.Security.AnonymousUser )
{
fAnonymousAccessAllowed = true;
}
cacheSettings = context.Response.Cache.GetCurrentSettings();
if ( cacheSettings.NoServerCaching ||
cacheSettings.Cacheability != HttpCacheability.Public ||
!fAnonymousAccessAllowed ||
cacheSettings.VaryHeaders != null )
{
return;
}
//
// If it expires now or in the past, don't cache it
// If it expires less than a minute from now, don't cache it
// (the reason for the latter rule is that the XSP output cache
// will not flush its cache of recently expired items until its
// expire check done every minute. When UL has smarts (M11) to
// handle cases like this itself, the problem will go away)
//
if ( DateTime.Compare( cacheSettings.Expires,
DateTime.Now.AddMinutes( 1 ) ) != 1 )
{
return;
}
//
// Now check whether config allows us to cache in UL
//
contentOptions = (Dictionary) context.GetConfig( "CacheOptions" );
if ( contentOptions != null )
{
strCacheDisable = (string) contentOptions[ "DisableUlCache" ];
if ( strCacheDisable != null &&
strCacheDisable.Equals( "true" ) )
{
//
// UL cache disabled. Bail
//
return;
}
}
//
// OK. Cache in UL. Tell the XSP output cache to flush
// its response but keep the cache entry for invalidation
// purposes
//
//
// First get the UlWorkerRequest
//
workerRequest = (ULWorkerRequest) context.GetServiceObject(
typeof( HttpWorkerRequest ) );
//
// Now get the full URL of the request, as this is the key
// needed to flush the appropriate UL cache entry
//
strFlushUrl = workerRequest.GetFullUrl();
//
// Get the flush delegate
//
flushDelegate = new OnCacheItemFlush( ULWorkerRequest.UlCacheFlushDelegate );
//
// Now instruct output cache module to bump out the response
// it was going to cache and then use flushDelegate upon removing
// the entry from its cache
//
if ( OutputCacheModule.DelegateCacheItemStorage( context,
flushDelegate,
strFlushUrl ) )
{
//
// Enable the UL cache only if call succeeded (i.e. only if
// the delegate will be called on flush/removal from XSP
// cache
//
workerRequest.EnableUlCache = true;
}
}
public string Phase
{
override get { return HttpModulePhase.Logging; }
}
}
}