Concetti base
IIS7 introduce una nuova reingegnerizzazione del modello di estendibilità del runtime, non più basato esclusivamente sulle ISAPI (scritte in C). Infatti, oggi abbiamo molto di più, ovvero la possibilità di accedere direttamente alla pipeline di elaborazione delle richieste HTTP sfruttando l'integrazione con ASP.NET, che nello specifico avviene tramite l'implementazione, nativa o managed, di moduli e gestori (Modules e Handlers). Se si intraprende la strada managed, dunque, possiamo stilare le seguenti definizioni:
- Module: è l'alter ego di un ISAPI filter in quanto coinvolto nell'elaborazione di una richiesta HTTP (si pensi a funzionalità di Authentication, Compression, Logging). Proprio come in ASP.NET, esso è costituito da una classe che implementa l'interfaccia System.Web.IHttpModule.
public class MyModule : IHttpModule
{
public void Init(HttpApplication context) { context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute); }
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = (HttpApplication)sender;
HttpRequest request = app.Context.Request;
// Logica da eseguire prima che IIS7 invochi il RequestHandler
// associato alla richiesta HTTP corrente
}
public void Dispose() { }
}
- Handler: è l'alter ego di una ISAPI extension ed è responsabile della gestione di richieste/risposte HTTP per ContentTypes specifici (es. pagine ASPX). In questo caso abbiamo bisogno di una classe che implementi l'interfaccia System.Web.IHttpHandler o System.Web.IAsyncHttpHandler.
public class MyHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
// Logica di processamento della richiesta HTTP
}
}
La differenza principale tra un Module ed un Handler si trova sostanzialmente nel fatto che un Handler è tipicamente mappato verso un path o una estensione specifica (es. il modulo ASPClassic per risorse *.asp oppure il PageHandlerFactory per pagine *.aspx), mentre un Module costituisce più in generale una funzionalità esposta in un determinato punto della pipeline. Quindi, nel momento in cui si progetta una nuova feature del nostro Web Server IIS7, la prima domanda che ci dobbiamo porre è se questa feature è responsabile di elaborare richieste per percorsi/estensioni specifiche (Handler) o se va applicata a richieste HTTP in base a determinate regole (Module).
Eventi principali della pipeline
La pipeline di IIS7 che viene attivata alla ricezione di una richiesta HTTP è composta da una sequenza di stati associati ai seguenti principali eventi:
- BeginRequest (primo evento associato al ricevimento di una richiesta HTTP, che viene poi inoltrata ad ASP.NET)
- AuthenticateRequest (determinazione dell'identità dell'utente da parte di un modulo di sicurezza - es. FormsAuthentication)
- AuthorizeRequest (determinazione dell'autorizzazione da parte di un modulo di sicurezza)
- ResolveRequestCache (accesso all'elaborazione di richieste già presenti in cache)
- MapRequestHandler (selezione dell'handler che si occuperà di elaborare la richiesta)
- AcquireRequestState (lo stato associato alla richiesta -es. Session- viene acquisito da ASP.NET)
- PreRequestHandlerExecute (evento generato immediatamente prima dell'esecuzione dell' handler)
ESECUZIONE REQUEST HANDLER (in modalità Classic, la pipeline di ASP.NET è eseguita in questo punto)
- ReleaseRequestState (ASP.NET termina l'esecuzione di tutti gli handler della richiesta. Salvataggio dello stato)
- UpdateRequestCache (salvataggio temporaneo della risposta HTTP nella cache)
- LogRequest (log della richiesta HTTP)
- EndRequest
Note di configurazione
IIS7 possiede due modalità di esecuzione: Classic e Integrated. La prima è l'unica disponibile nelle versioni precedenti (basata sulle ISAPI) mentre la seconda permette l'estendibilità sia nativa che managed, che di fatto apre le porte ad una serie di nuovi scenari, come l'agganciamento di moduli ASP.NET (es. FormsAuthentication) a richieste HTTP altrimenti gestite da altri moduli predefiniti (es. ASPClassic).
E' evidente che ci troviamo di fronte a uno scenario che può indurre in confusione: da una parte abbiamo Modules e Handlers nativi o managed e dall'altra abbiamo modalità di esecuzione Classic o Integrated. Dobbiamo muoverci con cautela.
Anzitutto, IIS7 introduce due nuove configuration sections per l'estendibilità: <handlers> e <modules> (%WINDIR%\system32\inetsrv\config\applicationHost.config). Come ci relazioniamo quindi con le sezioni <httpHandlers> e <httpModules> già esistenti in ASP.NET? Questo punto è cruciale.
- Se si esegue la pipeline di IIS7 in modalità Classic, le sezioni <httpHandlers> e <httpModules> di ASP.NET possono rimanere al loro posto poiché ci troviamo nell'analoga modalità di esecuzione prevista da IIS6. La pipeline di ASP.NET diventa quindi "una pipeline nella pipeline" ed in fase di esecuzione si colloca nell'esecuzione dei Request Handler previsti da ASP.NET (vedi i sopracitati eventi della pipeline).
- Se si esegue la pipeline di IIS7 in modalità Integrated, abbiamo invece bisogno di migrare le sezioni <httpHandlers> e <httpModules> nelle rispettive nuove sezioni <handlers> e <modules> (il tutto è automatizzabile tramite l'utility %WINDIR%\system32\inetsrv\appcmd.exe).
Fortunatamente, per aumentare l'efficacia e la flessibilità nell'utilizzo dei nostri Module/Handler, ci viene messo a disposizione un modello dichiartivo basato su preconditions, al fine di gestire quando e come i Modules e gli Handlers debbano essere eseguiti:
Tipo precondition | Valori possibili | Note |
Bitness | bitness32|bitness64 | Modalità di esecuzione a 32 o 64 bit |
RuntimeVersion | runtimeVersionvX.X | Versione del framework per il runtime |
ManagedHandler | managedHandler | Si applica solo ai Module!!! In caso di preCondition=”managedHandler", il modulo verrà eseguito solo per richieste HTTP gestite da un handler managed, altrimenti verrà eseguito per tutte le richieste. Un modulo managed ovviamente è utilizzabile solo se la pipeline di IIS7 viene eseguita in modalità IntegratedMode. In ClassicMode invece, si usano i soliti <httpModules> di ASP.NET. Le sezioni <httpHandlers> e <httpModules> di ASP.NET infatti sono agnostiche rispetto alle preconditions. |
Mode | integratedMode|ClassicMode | Si applica solo agli Handler!!! In caso di omissione, un handler può essere eseguito in entrambe le modalità (sebbene non sia possibile per un handler managed essere eseguito in ClassicMode). |
Technorati Tag:
IIS7,
ASP.NET