ASP: Session ed Application 
per la programmazione client/server

Se qualche tempo fa qualcuno vi avesse commissionato la realizzazione di un guest book o di un sistema di accesso ad un database, o anche un semplice sistema per fare comparire su una pagina HTML una immagine grafica che cambiasse ogni volta che la pagina stessa fosse stata caricata sul browser, avreste sicuramente iniziato a sudare freddo, pensando di dovervi cimentare con la terribile Common Gateway Interface, con lo scripting in linguaggi esoterici tipo il Perl, o chissà cosa altro ancora.
Sia che abbiate già avuto modo di scontrarvi con gli ostici script CGI, sia che siate tra i fortunati che di script e CGI non hanno mai sentito parlare, vi si presenta la possibilità di potere dormire sonni più tranquilli. Infatti Microsoft ha da poco introdotto una tecnologia chiamata ASP, acronimo di Active Server Pages, che ha tutte le carte in regola per rendere obsolete le vecchie tecniche di programmazione Web e fare diventare realtà il sogno di creare proprio sul Web delle vere applicazioni client/server

Agli albori del World Wide Web i contenuti delle pagine HTML erano statici, cioè non cambiavano man mano che le pagine stesse venivano richieste dai client. Naturalmente questa situazione comportava un grande sforzo per chi voleva tenere aggiornati tali contenuti; col passare del tempo tale sforzo si è rivelato insostenibile (immaginatevi di dovere cambiare le informazioni contenute in un centinaio di pagine sul vostro server una volta alla settimana…). In più si poneva il problema di potere fornire informazioni come le condizioni meteorologiche, le quotazioni in borsa ecc. aggiornate in tempo reale (no, una volta alla settimana non è esattamente "in tempo reale"). Come se ciò non fosse bastato l'utente incominciava a sentire la necessità di potere interagire con i server Web in maniera in po’ più articolata rispetto a quella offerta dalla semplice navigazione ipertestuale. Nacque così un protocollo di comunicazione tra client e server Web, la Common Gateway Interface, che permetteva all'utente di fornire al server informazioni che il server stesso poteva organizzare per fornire contenuti costruiti ad hoc.

Il prezzo dell'interazione
Oggi ci si rende conto che questo primo passo verso una interazione più articolata è costato molto in termini di sforzo di programmazione per chi ha realizzato i primi pionieristici sistemi (ancora oggi risulta molto macchinoso programmare script che si appoggino alla CGI) e costa ancora molto in termini di tempo di apprendimento per i neofiti.
La tecnologia ASP, essendo al passo con i tempi, e nascendo proprio dalla necessità di una maggiore semplicità di apprendimento e rapidità di sviluppo, supera tutti i limiti storici dello scripting CGI; ma ciò che è ancora più interessante, e che si preannuncia come una importante svolta nella tecnologia dei sistemi informativi basati sul Web, è che le ASP vanno ben oltre la semplice elaborazione dell'informazione fornita dall'utente (che comunque resta sempre la base fondamentale dell'interazione) fornendo una serie di strumenti che porteranno ben presto verso lo stabilirsi di un nuovo stato dell'arte della programmazione client/server e del calcolo distribuito. 
Per una introduzione alla struttura ed alle funzionalità di base di una pagina creata in tecnologia ASP, si rimanda all'articolo comparso a pagina 24 del numero 5 di IoProgrammo.
Le pagine attive risolvono brillantemente due annosi problemi che affliggono lo sviluppo di applicazioni client/server:
•	Permettono finalmente la creazione di software che sfrutta le risorse distribuite su uno o più server senza doversi preoccupare della piattaforma client: dal momento che una pagina ASP viene elaborata sul server che fornisce poi un output in HTML standard al browser, basta che il browser stesso supporti l'HTML;
•	Utilizzano per le transazioni l'HTTP, il protocollo di comunicazione standard per il WWW, il quale fa parte della suite TCP/IP che esiste per qualunque architettura in commercio.
Questo ultimo punto merita una discussione più approfondita: come tutti sanno, se si vuole costruire una applicazione client/server la prima necessità che si presenta è che vi sia tra il client ed il server un protocollo che consenta al server, attraverso uno scambio bidirezionale di informazioni, di tenere traccia delle mosse del client in maniera tale da avere sempre un quadro completo di come il client interagisce e di quali servizi richiede. Apparentemente questa necessità non è soddisfacibile dal protocollo HTTP che per sua natura, una volta esaudita la richiesta del client, dimentica che la connessione sia mai avvenuta.  Le ASP permettono in maniera nativa di utilizzare l'HTTP per le transazioni fornendo però due oggetti di sistema, SESSION ed APPLICATION, i quali, in combinazione, forniscono gli strumenti per tenere traccia di tutte le richieste di ogni singolo client. Sia ben chiaro che questo genere di operazione era già possibile con le vecchie tecniche di scripting, ma ora per la prima volta viene proposto un sistema unificato, elegante e per nulla macchinoso per generare ID univoci per i client, per creare ed utilizzare variabili relative alla sessione corrente e così via.

L'organizzazione di un'applicazione distribuita in ASP
Dal punto di vista tecnico il motore ASP (cioè il modulo che si occupa di controllare se una pagina richiesta al server contenga o meno del codice ASP che va eseguito prima che la pagina stessa sia inviata al client) non è altro che un filtro ISAPI che viene eseguito all'interno di Internet Information Server 3.0. Per esso una applicazione è una directory interna alla home directory dei documenti Web (di solito chiamata wwwroot)  per la quale sia attivo il permesso di esecuzione. Tutti i file che hanno estensione .ASP e che si trovano in questa directory sono considerati come componenti dell'applicazione. Tra di essi esiste un file il cui nome è GLOBAL.ASA che contiene porzioni di codice eseguite all'avvio ed alla chiusura dell'applicazione.
Una applicazione viene avviata quando un client richiede una pagina ASP contenuta nella directory che costituisce l'applicazione stessa. Se supponiamo che un browser ad un certo punto faccia richiesta di una tra queste pagine ASP il server controlla che non esista una istanza dell'oggetto APPLICATION. Se tale istanza non esiste, ne crea una. A questo punto il server controlla il contenuto del file GLOBAL.ASA alla ricerca della procedura APPLICATION_OnStart, che viene eseguita. Il contenuto della procedura è deciso da chi progetta l'applicazione e contiene in genere l'inizializzazione di oggetti come connessioni a database o altri ancora che debbono essere disponibili ed aggiornati fintanto che l'applicazione è attiva e debbono essere condivisi tra tutte le sessioni esistenti. Il passo successivo che il server compie è istanziare un oggetto SESSION generando un ID univoco che viene trasmesso attraverso un cookie (una capsula software contenente una informazione) al browser che lo memorizza. Tale ID è conservato sul server in una proprietà dell'oggetto SESSION chiamata SessionID che servirà al server per capire se un determinato client che manda un cookie contenente un ID abbia o meno una sessione aperta nell'applicazione corrente. 
Fatto ciò il server controlla ancora una volta il file GLOBAL.ASA alla ricerca della procedura SESSION_OnStart la quale contiene informazioni per l'inizializzazione della sessione corrente. Anche tale procedura è realizzata da chi progetta l'applicazione. Esistono inoltre i due eventi/procedure APPLICATION_OnEnd e SESSION_OnEnd il cui uso dovrebbe a questo punto essere chiaro. Naturalmente si può scegliere di non scrivere codice per nessuno degli eventi di apertura e chiusura, come non è obbligatoria l'esistenza del file GLOBAL.ASA stesso.
Quando esiste già un oggetto APPLICATION ed un browser fa richiesta di una pagina ASP appartenente all'applicazione, il server crea nella maniera già vista un nuovo oggetto SESSION da affiancare a quelli già esistenti (sempre che il browser non abbia già una sessione attiva).
Una sessione può essere chiusa se:
•	Viene invocato il metodo ABANDON dell'oggetto SESSION;
•	Il tempo di inattività del browser ha raggiunto il limite in minuti fissato dalla proprietà TIMEOUT dell'oggetto SESSION.
Quando non esistono più sessioni aperte viene invocata dal server la chiusura dell'applicazione.

Dalla teoria alla pratica
Per cercare di capire meglio i fondamenti dell'uso di questi due interessanti oggetti, realizzeremo passo dopo passo un piccolo sistema di autenticazione per mezzo di un nome utente e di una password da usare in un ipotetico server Web.
Nello studio dell'applicazione in questione si assume che il lettore (o la lettrice) conosca un minimo di HTML e Visual Basic Script. Per qualsiasi dubbio si rimanda alla consultazione della documentazione disponibile gratuitamente all'URL http://www.microsoft.com/vbscript o all'interno della ASP Roadmap qualora l'abbiate installata con IIS 3.0.
Innanzi tutto creeremo una directory all'interno della home directory del nostro server che chiameremo MEMBRI. Fatto questo dal menu di avvio di Windows NT sceglieremo lo strumento di amministrazione denominato Internet Service Manager. Da qui selezioneremo WWW come servizio da amministrare e dal menu Proprietà sceglieremo la voce Proprietà del Servizio. Nella finestra che comparirà andrà evidenziata la voce Cartelle. Apparirà una lista delle directory esportate dal server Web ai client. Schiacceremo il pulsante Aggiungi e nella casella di testo denominata Percorso inseriremo il percorso reale della cartella MEMBRI creata in precedenza. A questo punto nella casella di testo denominata Alias scriveremo /MEMBRI. Questo significa che ogni qual volta un browser specificherà un'URL del tipo http://vostroserver/MEMBRI il vostro server gli darà l'accesso alla pagina di default (in genere DEFAULT.HTM) contenuta nella directory MEMBRI.
A questo punto, per potere garantire la corretta esecuzione delle pagine ASP, dovremo permettere l'accesso in esecuzione alla directory per mezzo della casella di selezione Esecuzione. Fatto questo, selezioneremo Ok; nella lista delle cartelle esportate comparirà la directory MEMBRI.
Nel CD allegato alla rivista troverete un file compresso chiamato SECUREX.ZIP che contiene tutti i files descritti e commentati di seguito. Tutti questi files andranno collocati nella directory MEMBRI. Tuttavia uno di essi dovrà essere collocato altrove per ragioni di sicurezza: si tratta del file DBMEMBRI.MDB che è in formato Microsoft Access e contiene un semplice database di nomi utente e password. Questo database verrà utilizzato per l'autenticazione degli accessi. Il file va posto in una directory esterna alla home directory del server Web per evitare che possa venire letto da qualche client indiscreto. Tuttavia per rendere disponibili le informazioni che esso contiene al motore ASP sarà necessario esportarlo attraverso l'interfaccia ODBC. Per farlo aprite il Pannello di Controllo di Windows NT 4.0. Dovreste trovare una icona chiamata ODBC (Open DataBase Connectivity). Aprite ODBC con un doppio click. Selezionate la voce DSN di Sistema e cliccate su Aggiungi. Nella finestra di creazione di una nuova fonte dati evidenziate la voce Microsoft Access Driver dopodiché selezionate il tasto fine. Nella finestra che comparirà scegliete Seleziona e selezionate il percorso che avete scelto per il file DBMEMBRI.MDB. Fatto questo nella casella di testo denominata Nome fonte dati scrivete il nome con cui il database verrà esportato verso il motore ASP (ad es. membri). Fate click su Ok. Ora nella finestra DSN di Sistema dovrebbe comparire il nome con cui il database viene esportato. Ancora una volta selezionate Ok ed il gioco è fatto. 
Qualora non disponeste di ODBC potrete scaricarlo gratuitamente dal sito della Microsoft.
Ora siamo pronti per cominciare a creare l'applicazione.
Innanzi tutto si dovrà realizzare un form, cioè una pagina HTML che richiede all'utente dei dati, all'interno del quale inserire il proprio nome utente e la propria password. I dati così ottenuti verranno passati dal form stesso al server che li elaborerà attraverso uno script ASP. Sarà proprio tale script che procederà all'autenticazione dell'utente. Se l'autenticazione va a buon fine viene scritta sul server un'informazione che consente all'utente stesso di potere accedere alle pagine protette per tutta la durata della sessione corrente. Se al contrario essa fallisce viene generato un messaggio di errore e l'accesso alle informazioni protette non viene consentito.
Un semplice form di esempio chiamato DEFAULT.HTM e compreso nel file SECUREX.ZIP.
Esaminando il file risulta chiaro dalla proprietà ACTION del tag <FORM> che la pressione del pulsante Invia provoca la chiamata e l'esecuzione del file EMEMBRO.ASP. Vale la pena sottolineare che una eventuale istanza dell'oggetto APPLICATION, nonché l'istanza dell'oggetto SESSION relativa alla sessione corrente, viene creata allorché il server processa la prima pagina con l'estensione .ASP, non prima. Questo significa che se nella vostra directory/applicazione sono presenti più tipi di file, comunque gli oggetti APPLICATION e SESSION saranno disponibili solo all'interno di file con estensione .ASP.
A questo punto dovremo scrivere il codice relativo al file EMEMBRO.ASP che opera l'autenticazione vera e propria. Ma prima di fare ciò, ci soffermeremo sul file GLOBAL.ASA. Come ricorderete, esso contiene gli script di inizializzazione e di distruzione dei due oggetti. Proprio per questo motivo è opportuno che in esso avvengano le inizializzazioni di tutte quelle proprietà che ci saranno utili per la gestione delle informazioni condivise tra tutte le sessioni, che porremo al livello dell'oggetto APPLICATION, e relative alle sessioni singole, che si troveranno invece al livello dell'oggetto SESSION. 
Esaminando il  file GLOBAL.ASA la prima cosa che risulta evidente è che tra le proprietà del tag <SCRIPT> ce n'è una chiamata RUNAT che specifica chi deve eseguire il codice racchiso tra i tag <SCRIPT>…</SCRIPT> stessi. È chiaro che a tale proprietà viene dato il valore Server poiché sia l'oggetto APPLICATION che gli oggetti SESSION vengono memorizzati nello spazio interno al server stesso e non sui client. In realtà l'unica cosa che un client riceve è il cookie contenente il SessionID di cui abbiamo detto in precedenza.
A questo punto, se si guarda al codice della procedura Application_OnStart ci si rende conto di come sia semplice aggiungere una nuova proprietà all'oggetto APPLICATION: se noi vogliamo memorizzare al livello dell'applicazione il numero degli utenti autenticati attualmente collegati al server, con la sintassi sopra descritta creiamo la proprietà numMembriConn all'interno di Application e la inizializziamo a zero. Allo stesso modo all'interno dell'oggetto SESSION creiamo la proprietà eMembro che assumerà i valori "si" oppure "no" a seconda che l'autenticazione dell'utente che ha aperto la sessione in questione sia andata a buon fine o meno. Come si può vedere per le due proprietà appena descritte non è stato specificato alcun tipo. Questo poiché il VBScript ammette solo il tipo di dati variant, e qualsiasi variabile VBScript si adatta automaticamente al tipo del dato che la inizializza.
Il file EMEMBRO.ASP fa solo un paio di cose che non potrete capire immediatamente (poichè ne parleremo il un articolo il mese prossimo): apre il database dei membri e controlla che i dati provenienti dal form che ha invocato lo script corrispondano effettivamente a quelli di un utente autenticabile.
Come si può notare, il codice ASP è racchiuso tra i tag <%…%> che, a differenza dei tag <SCRIPT>…</SCRIPT> , indicano una porzione di codice da eseguire immediatamente piuttosto che una dichiarazione di procedura.
Per ora non è importante che capiate la sintassi del codice che apre ed interroga il database, ma solo il senso che esso ha: la prima linea stabilisce un canale di connessione tra il server ed ADO (anche di ADO parleremo il mese prossimo). Una volta stabilito il canale (che si chiama dbm) viene invocato il metodo di apertura del canale verso il database che viene esportato con il nome membri. A questo punto viene invocato il metodo di esecuzione di una query (una interrogazione al database) SQL (Simple Query Language: un linguaggio standard per le interrogazioni) sul canale dbm. Tale metodo quello che si chiama un RecordSet cioè un insieme di record appartenenti al database che soddisfano i parametri dell interrogazione. Questo record viene memorizzato in membro. Uno dei metodi del RecordSet è EOF; se esso vale true allora si è esplorato già tutto l'insieme di record. Dato che membro è stato appena creato se EOF vale true allora vuol dire che nessun record di membri corrisponde ai dati del form. Inevitabilmente l'utente non può essere autenticato. A questo punto è banale capire cosa succede se EOF è false: Vengono reimpostate le proprietà eMembro, Timeout e nome dell'oggetto Session.
Un discorso a parte va fatto per il modo in cui viene cambiata la proprietà numMembriConn di Application: siccome si tratta di una proprietà visibile e modificabile da tutte le istanze degli oggetti SESSION è necessario, per evitare conflitti, che, prima di alterarla, essa venga posta in una modalità di accesso esclusivo. I mezzi per compiere questa operazione sono dati dai due metodi Lock e Unlock propri dell'oggetto APPLICATION.
A questo punto viene usato l'oggetto RESPONSE (abbiate pazienza e parleremo anche di questo) per chiamare un altro script ASP, SOLOMEMBRI.ASP, il quale fornirà l'accesso alle risorse protette sul server.
Se invece nessun record viene trovato (membro.EOF è true) allora non viene aggiornato il numero di utenti connessi e si viene ridirezionati verso uno script, NONMEMBRO.ASP, che si occupa di chiudere la sessione corrente attraverso il metodo Abandon.
L'ultimo passo necessario per dotare il vostro server di un certo grado di sicurezza è cambiare l'estensione di tutte le pagine riservate ai soli utenti accreditati da .HTM o .HTML a .ASP ed aggiungere le seguenti righe di codice all'inizio di ogni pagina:
<%If Session("eMembro")="no" then
	Response.Redirect "nonmembro.asp"
End If%>
A questo punto il gioco sarà fatto.

In conclusione…
Questo piccolo esempio mostra quanto sia semplice usare la tecnologia ASP per controllare gli utenti man mano che essi accedono al vostro server. Naturalmente gli usi dei due oggetti SESSION ed APPLICATION non sono limitati a questo ma possono essere estesi alla soluzione di problemi molto complessi relativi alla gestione del traffico dei client. Purtroppo per ragioni di spazio non abbiamo potuto illustrare molti dei loro usi più interessanti (non basterebbe l'intera rivista) ma speriamo di avere fornito almeno le basi che vi permetteranno di iniziare a sperimentare con essi. E vi assicuriamo che le soddisfazioni non mancheranno…
Valerio Talarico