Lo strato applicativo di Internet

World Wide Web

L'aspetto di Internet, per come è noto ai più, si basa essenzialmente sulla navigazione del World Wide Web (trad. lett. ragnatela mondiale), fondata su tre meccanismi per rendere le informazioni prontamente disponibili:

A questo semplice trittico, si sono via via aggiunte sempre più tecnologie (CSS, Javascript, CGI, CMS, RSS, CDN, Web Services, Web Semantico), a cui in questa e nella prossima sezione tenteremo di dare un ordinamento.

Storia

Nel 1991 Tim Berners-Lee, durante il suo lavoro al CERN di Ginevra, affrontò il problema di visualizzare congiuntamente i grafici e le tabelle prodotti come risultati di esperimenti scientifici, condotti su macchine diverse ed in laboratori differenti. Per questo, realizzò (assieme al collega Robert Cailliau) un meccanismo di condivisione delle documentazione scientifica in formato elettronico, tale da renderla accessibile in modo indipendente dal particolare tipo di computer dell'utente. Successivamente, accettò l'offerta di trasferirsi al Massachusetts Institute of Technology (MIT) di Boston, presso cui nel 1994 fondò il World Wide Web Consortium (W3C).

Il linguaggio con cui si definisce il contenuto della presentazione è l'HTML, con cui sono scritte le pagine definite statiche, visualizzabili mediante una applicazione browser, detta anche User Agent. Queste pagine sono richieste, mediante il protocollo HTTP, ad un sistema remoto dove è in esecuzione un Web Server. La URL è un indirizzo di livello applicativo, che consente di individuare contemporaneamente il protocollo, il computer che ospita il web server, e la specifica pagina richiesta.

W3C

Il World Wide Web Consortium (W3C) è l'organizzazione nata allo scopo di studiare, migliorare e definire nuove tecnologie relative al WWW, con il fine di conseguire il massimo delle potenzialità offerte da questo mezzo. Non è un ente di standardizzazione, ed i suoi documenti sono delle raccomandazioni a cui i produttori di software sono invitati ad attenersi. D'altra parte, tra i membri del W3C compaiono gli stessi produttori a cui le raccomandazioni sono indirizzate, oltre ad aziende telefoniche, istituzioni di ricerca, e società strategicamente interessate alla crescita del Web. Infine, il W3C mette a disposizione una serie di validatori della sintassi usata nella redazione delle pagine web.

Markup Language

Un linguaggio di marcatura (markup) ha lo scopo di indicare il modo in cui alcune parti di un testo devono essere visualizzate, mediante l'uso di descrittori appositi detti TAG (etichette) che compaiono a coppie, elimitando gli elementi dell'HTML. Mentre i linguaggi di tipo procedurale (es. LaTeX) contengono le istruzioni da eseguire per la visualizzazione desiderata, i linguaggi descrittivi lasciano al visualizzatore il compito di stabilire il risultato finale effettivo, e danno solo delle indicazioni di tipo semantico sulla natura delle singole parti di testo. In questa seconda categoria, troviamo SGML, XML, HTML.

SGML

Lo Standard Generalized Markup Language (SGML) è un metalinguaggio standardizzato (ISO 8879), discendente dal Generalized Markup Language (GML) sviluppato in IBM, ed è basato sul concetto di definizione del tipo di documento o Document Type Definition (DTD), che a sua volta stabilisce quali sono i TAG permessi in un determinato documento SGML, in modo che questo possa essere verificato formalmente, prima di procedere alla sua visualizzazione, in accordo al markup.

XML

L'eXtensible Markup Language (XML) è una semplificazione e adattamento dell'SGML, da cui è nato, e permette di definire la grammatica di diversi linguaggi specifici derivati. Il suo scopo primario è quello dello scambio di dati strutturati, come ad esempio quelli prelevati da un database, che potrebbero essere descritti nel seguente modo:

<?xml version="1.0" encoding="ISO-8859-1"?>
<utenti>
    <utente>
        <nome>Luca</nome>
        <cognome>Ruggiero</cognome>
    </utente>
    <utente>
        <nome>Max</nome>
        <cognome>Rossi</cognome>
    </utente>
</utenti>

Nella prima riga, detta prologo, si indica la versione, la codifica dei caratteri, e se esiste, il DTD che ne definisce i tag (anche se per questo scopo, si preferisce fare uso di XML Schema Definition - XSD). Ogni tag può essere corredato da attributi, e la sezione contenuta tra un tag di apertura ed uno di chiusura prende il nome di nodo; il nodo più esterno, che racchiude tutti gli altri, prende il nome di Elemento Radice. Un file XML può essere visualizzato da parte di un browser così come si trova, oppure in associazione con un foglio di stile (CSS o XSL) che ne definisce l'aspetto. In particolare, l'XHTML è un file XML che usa un insieme ridotto dei tag di HTML, ed una sintassi più rigida, e che può essere visualizzato da un browser web solo se accompagnato da un foglio di stile CSS.

HTML

L'Hyper Text Mark-Up Language è stato sviluppato alla fine degli anni '80 da Tim Berners-Lee come semplificazione dell'SGML, e la sua sintassi, definita dal W3C, è praticamente ferma dal 1999 alla versione 4.01 e non più modificata, perché in un qualche futuro, l'HTML verrà soppiantato da XHTML e XML, o da HTML5. Un file HTML è composto di elementi racchiusi tra una coppia di tag (tag significa etichetta, qui con la funzione di descrivere l'aspetto che dovrà avere l'elemento), uno di apertura ed uno di chiusura, e quest'ultimo, per certi elementi, è opzionale. Ad esempio, l'elemento <b>testo testo testo</b> verrà visualizzato in grassetto, come testo testo testo.

Molto spesso nel tag di apertura di un elemento vengono specificati, oltre al suo tipo, anche uno o più attributi, con lo scopo di arricchire e/o specializzare la semantica standard del tag, assegnando ad una o più proprietà, dei valori definiti in modo esplicito. Per questo, il formato di un elemento HTML avrà il generico aspetto

<tipo attr1=valore1 attr2=valore2 ... >
  testo al quale si applica la semantica del tag
</tipo>

Volendo fare un esempio che non c'entra nulla, è come se un documento HTML fosse un banco per la vendita di ortofrutta, esposta in cassette (elementi), ognuno recante una etichetta (tag) con su scritto il tipo del prodotto (pere, pomodori, carote...) assieme a degli attributi (provenienza, prezzo, tasto bilancia...).

Si può inoltre dire che un file HTML è un file SGML che adotta il DTD di HTML. La prima riga di un documento HTML contiene infatti l'indicazione della DTD adottata, indicando così al browser qual'è la versione di HTML che stiamo utilizzando. Il documento HTML vero e proprio è quindi racchiuso tra i tag <html> e </html>, all'interno dei quali troviamo due sezioni:

Ad esempio, il listato seguente raffigura come si presenta il sorgente della pagina che stiamo leggendo, che usa il DTD 4.01 Transitional

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html lang="it">

 <head> 
   <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
   <title>World Wide Web</title>
   <link rel="stylesheet" type="text/css" href="../corso.css">
   <meta content="Alessandro Falaschi" name="author">
 </head>

 <body>
  <a href="../index.html">Lo strato applicativo di Internet</a>
  <br>
  .
  .
  .
 </body>

</html>

Document Object Model

Come mostrato dall'esempio, i tag possono essere nidificati, nel senso che all'interno di un tag di apertura/chiusura se ne può inserire un altro, e li dentro, un altro ancora. Questo determina la possibilità di interpretare un documento HTML come una struttura ad albero, in cui tutti i tag interni ad un altro, sono rappresentati come discendenti dal primo. Il risultato è il cosiddetto albero DOM (Document Object Model), che ad esempio, nel caso del semplice codice HTML mostrato appresso, dà luogo all'albero mostrato a fianco. Nel caso in cui invece dell'HTML si debba analizzare allo stesso modo un documento XML, allora il parser da impiegare è SAX (Simple API for XML).

<!-- My document -->
<html>
 <head>
   <title>My Document</title>
 </head>
<body>
 
<h1>Header</h1>
  <p>
    Paragraph
  </p>  </body>
</html>

Sebbene inizialmente l'HTML fosse stato pensato per essere scritto a mano, attualmente è abbastanza comune ricorrere a strumenti wysiwyg, come ad esempio Document made with Kompozer (video), con cui sono realizzate queste pagine; ciononostante, può accadere di dover modificare manualmente una pagina preesistente, e conoscere qualcosa dei possibili elementi può essere molto utile (ma altri editor wysiwyg sono, ad esempio Amaya, Bluegriffon, Sigil).

Tipi di elementi

Questo corso non ha nessuna pretesa di includere, tra le altre cose, un corso di HTML. Ma chi volesse approfondire l'argomento, può prendere come ottimo punto di partenza questo sito con le traduzioni italiane del sito di W3C, e che presenta diverso materiale utile, come un tutorial di HTML e CSS, la raccomandazione HTML 4.01, e la tabella degli elementi da questa definiti, che è riportata qui sotto.

Legenda: Facoltativo, Proibito, Vuoto, Disapprovato, DTD Transitoria, DTD Frameset

Nome Tag
inizio
Tag
fine
Vuoto Disap. DTD Descrizione
A           ancora
ABBR           forma abbreviata (es., WWW, HTTP, ecc.)
ACRONYM            
ADDRESS           informazioni sull'autore
APPLET       D T applet Java
AREA   P V     area di una mappa immagine lato-cliente
B           stile di testo grassetto
BASE   P V     URI di base del documento
BASEFONT   P V D T dimensione di base dei caratteri
BDO           sovrascrive l'algoritmo bidirezionale
BIG           stile di testo ingrandito
BLOCKQUOTE           citazione lunga
BODY F F       corpo del documento
BR   P V     interruzione di riga forzata
BUTTON           pulsante
CAPTION           didascalia di tabella
CENTER       D T abbreviazione per DIV align=center
CITE           citazione
CODE           frammento di codice
COL   P V     colonna di tabella
COLGROUP   F       gruppo di colonne di tabella
DD   F       definizione di un termine
DEL           testo cancellato
DFN           racchiude una definizione
DIR       D T elenco di directory
DIV           contenitore generico di lingua/stile
DL           elenco di definizioni
DT   F       termine definito
EM           enfasi
FIELDSET           gruppo di controlli di un modulo
FONT       D T cambiamento locale di carattere
FORM           modulo interattivo
FRAME   P V   F sottofinestra
FRAMESET         F suddivisione della finestra
H1           titolo
H2           titolo
H3           titolo
H4           titolo
H5           titolo
H6           titolo
HEAD F F       intestazione del documento
HR   P V     riga orizzontale
HTML F F       elemento radice del documento
I           stile italico del testo
IFRAME         T sottofinestra a livello di riga
IMG   P V     immagine incorporata
INPUT   P V     controllo di modulo
INS           testo aggiunto
ISINDEX   P V D T campo di immissione a riga singola
KBD           testo che deve essere inserito dall'utente
LABEL           etichetta di un campo modulo
LEGEND           didascalia di un gruppo di campi modulo
LI   F       elemento di un elenco
LINK   P V     un collegamento indipendente dal mezzo
MAP           mappa immagine sul lato cliente
MENU       D T elenco di menu
META   P V     metainformazioni generiche
NOFRAMES         F contenitore di contenuto alternativo
per la riproduzione non basata sui frame
NOSCRIPT           contenitore di contenuto alternativo
per la riproduzione non basata su script
OBJECT           oggetto generico incorporato
OL           elenco ordinato
OPTGROUP           gruppo di opzioni
OPTION   F       opzione selezionabile
P   F       paragrafo
PARAM   P V     valore di proprietà denominata
PRE           testo preformattato
Q           breve citazione in riga
S       D T stile per il testo cancellato
SAMP           esempio tipico di listato di programma, script, ecc.
SCRIPT           dichiarazioni di script
SELECT           selettore di scelte
SMALL           stile di testo rimpicciolito
SPAN           generico contenitore di lingua/stile
STRIKE       D T testo cancellato
STRONG           forte enfasi
STYLE           informazioni di stile
SUB           pedice
SUP           apice
TABLE            
TBODY F F       corpo della tabella
TD   F       cella di dati di una tabella
TEXTAREA           campo di testo su più righe
TFOOT   F       piede della tabella
TH   F       cella d'intestazione di una tabella
THEAD   F       intestazione di tabella
TITLE           titolo del documento
TR   F       riga di tabella
TT           stile di testo di telescrivente o a spaziatura fissa
U       D T stile di testo sottolineato
UL           elenco non ordinato
VAR           instanza di una variabile o argomento di un programma

Per ogni elemento della tabella si possono individuare gli attributi supportati, che hanno lo scopo di modificare e/o specificare meglio la funzione dell'elemento, come ad es. href e target, usati con l'elemento <a>, che specificano rispettivamente il collegamento da seguire, e dove aprire la nuova pagina:

<p>Avete visto le nostre <a href="../gabbie/uccelli.gif" target="_top">gabbie per uccelli</a>?</p>

che produrrà il risultato:

Avete visto le nostre gabbie per uccelli?

Gli elementi che si usano più di frequente, sono

Un elenco un pò più dettagliato, è presente presso Wikipedia.

CSS

I fogli di stile a cascata (CSS = Cascading Style Sheets) contengono le dichiarazioni necessarie a definire lo stile (per es. tipo di carattere, colori e spaziature) da applicare ai documenti HTML e XHTML, e la definizione di queste regole è ancora una volta emanata dal W3C. In questo modo, i contenuti possono essere sviluppati in modo indipendente dalla loro modalità di visualizzazione, rendendo in definitiva più omogenee le diverse pagine di uno stesso sito. Ad esempio, non occorre ripetere una specifica di colore per tutti gli elementi simili, con il rischio che qualora si desideri cambiarla, occorra ripetere ovunque la stessa operazione: al contrario, la specifica del colore viene eseguita una sola volta, nel foglio di stile.

Sebbene il W3C abbia pubblicato nel 2006 la versione 2.01 delle specifiche CSS, e si stia lavorando alla versione 3.0, la traduzione italiana che riportiamo è quella della versione 2.0 del 1998, che pure è molto diffusa. Il foglio di stile viene associato alla pagina HTML nella sua sezione <head> in uno dei due modi seguenti: usando un file separato, eventualmente ri-usabile a partire da pagine HTML differenti

<html>
 <head>
  <title>Esempio</title>
  <link rel="stylesheet" type="text/css" href="foglio_di_stile.css">
 </head>
 .
 .

oppure in-linea nella stessa pagina per la quale se ne desidera l'applicazione

<html>
 <head>
  <title>Esempio</title>
   <style type="text/css">
     ...codice css...
     ...codice css...
     ...codice css...
   </style>
 </head>
 .
 .

Selettori e regole

Il codice CSS consiste in una serie di regole, ciascuna caratterizzata da un selettore che individua quando applicarla, seguito da una o più istruzioni di assegnazione di uno o più valori a una determinata proprietà:

selettore {
  proprietà1: valore1;
  proprietà2: valore2, valore3;
}

Il selettore può corrispondere a

Alcuni esempi di uso dei selettori, possono essere trovati presso HTML.it.

Qui ci limitiamo invece ad esemplificare i concetti esposti mediante l'esempio pratico delle pagine di questo stesso testo, che usa un CSS specifico allo scopo di non ripetere i comandi relativi al colore dello sfondo, ed alla dimensione dei caratteri, per tutti i riquadri di codice. Ciò è ottenuto realizzando i riquadri come una tabella ad una sola cella, ed usando per gli elementi <table> e <td>, un attributo class=pre, al quale sono associati i seguenti selettori nel file corso.css utilizzato:

table.pre {
  border: 1pt solid rgb(253, 152, 253);
  width: auto;
  background-color: rgb(244, 255, 252);
}

td.pre {
  font-weight: normal;
  font-size: small;
  font-family: monospace,Courier New,Courier;
}

Proprietà

Nell'esempio su riportato, la proprietà border è utilizzata per impostare (qualora all'elemento table sia assegnato un attributo di valore pre) il bordo della tabella che delimita il riquadro ad uno spessore di un pixel, a linea continua, e di colore viola, mentre per lo sfondo (proprietà background-color) è scelto il colore celeste, e la larghezza (width) del riquadro dipenderà da quella del contenuto. Quindi, il selettore td.pre determina l'applicazione delle proprietà sui caratteri contenuti all'interno della colonna, stabilendone il peso, la dimensione, ed il tipo di carattere. Pertanto, un riquadro (vuoto!) sarà realizzato mediante un codice HTML pari a

<table class="pre" cellpadding="10" cellspacing="0">
  <tbody>
    <tr>
      <td class="pre">
         --- inserire qui il contentuto del riquadro! ---
      </td>
    </tr>
  </tbody>
</table>

Un elenco delle proprietà esistenti, assieme ai loro possibili valori, ed a degli esempi di utilizzo, è fornita assieme alla raccomandazione di W3C, ed è replicata su diversi siti in rete. Tra i riferimenti, elenchiamo alcuni siti dove scegliere liberamente un template di stile (template letteralmente significa sagoma) da usare per dare un aspetto gradevole alle proprie pagine.

Si, ma le cascate?

Ora che abbiamo (un minimo) più chiaro cosa si intende per style sheet (foglio di stile), evidenziamo che il termine cascading rappresenta il fatto che alcuni selettori possono essere in conflitto tra loro, causando per uno stesso elemento la possibilità di dover applicare regole diverse dagli effetti contrastanti. Per derimere questa contesa, viene applicata una scala di priorità, che attribuisce una maggiore importanza al CSS impostato tra le preferenze da parte dell'umano che sta effettuando la navigazione, rispetto a quello applicato di default dal browser, mentre il CSS impostato dall'autore della pagina prodomina su entrambi. Quindi, predomina la regola più specifica, riconoscendo ad un selettore legato ad un identificatore la priorità rispetto a quello associato ad una classe, e quest'ultimo a sua volta prende il sopravvento su di un selettore relativo ad un elemento HTML.

Caricare le pagine sul server

Ora che abbiamo preparato le pagine che il server web dovrà fornire, su richiesta, al browser, resta il passaggio di come depositarle presso il server. A questo scopo esistono tutta una serie di possibilità, che elenchiamo.

FTP


Il File Transfert Protocol è uno tra i protocolli più anziani di Internet, specificato nella RFC 959, e permette ad un programma client di colloquiare con un server in ascolto sulla porta TCP 21, al fine di leggere/scrivere/navigare tra i files del suo filesystem. Può essere invocato da linea di comando, impartendo manualmente i comandi di cui dispone, oppure può essere utilizzata una interfaccia grafica, ormai incorporata nelle stesse applicazioni genericamente usate per navigare nel filesystem locale (ossia, del proprio computer), permettendo in questo caso, operazioni di tipo drag and drop.

In una prima fase del collegamento, l'utente che sta usando il client si autentica presso il server, trasmettendo la password in chiaro, e questa circostanza è uno dei principali motivi per cui l'uso dell'FTP è sconsigliato/scoraggiato. E' da notare, tuttavia, che esiste anche una modalità anonima di collegamento, in cui il client usa con nome utente anonymous, e come password tipicamente invia il proprio indirizzo email. Vedi, come esempio, questo file di capture. Quando ancora il web non esisteva, questo era il modo in cui venivano messi pubblicamente a disposizione dati e programmi, ed è tuttora in uso, ad esempio come meccanismo di default utilizzato dai browser web, per accedere ad una URI il cui schema è ftp:, come ad esempio ftp://ftp.debian.org/debian/.

Due ulteriori possibilità sono quelle relative ad un collegamento attivo o passivo. La differenza nasce dal fatto che l'FTP utilizza in effetti due diverse connessioni TCP, la prima detta di controllo, su cui avviene l'autenticazione, e dove poi sono inviati i comandi di sessione, ed una seconda connessione, instaurata sotto il controllo della prima, su cui avviene il trasferimento dati vero e proprio.

Nel caso della modalità attiva, la connessione dati è creata su iniziativa del server, in quanto è quest'ultimo a contattare il client, un pò per meglio gestire le richieste di servizio nel caso di elevato traffico, ed un pò per essere sicuro di stare parlando con chi si è presentato con l'IP sorgente. In questo caso, il server usa la porta 20 come sorgente del canale dati, e contatta il client sul numero di porta da esso usato in uscita, incrementato di uno.

L'ultima delle figure a fianco, prelevate da un articolo pubblicato su qcipc, mostra il risultato finale di un setup attivo. Questa tecnica dà però luogo a problemi, ogni volta in cui tra client e server sia interposto un dispositivo NAT, ovvero quando il client posside un indirizzo IP privato, ed il server uno pubblico. Infatti in questo caso, il server non è in grado di aprire una connessione verso il client, e il trasferimento non può avere luogo.

Nel caso specificato (presenza di un NAT), si ricorre allora alla modalità di FTP passivo, mostrata nella figura seguente. In questo caso anche la connessione dati viene aperta su iniziativa del client, e nella prima fase, il server comunica al client un nuovo numero di porta effimera, su cui aprire la connessione dati. Quindi nel caso passivo, è sempre il client ad aprire entrambi i canali (di controllo e dati), e non si presenta nessun problema, anche in presenza di NAT.

A volte, per garantire una maggiore sicurezza e confidenzialità, il client si trova ad operare in una modalità cosiddetta chrooted, cioè a dire, come se sul server fosse stato eseguito il comando chroot, abbreviazione di change root. In tal caso, il client non può più navigare per tutto il filesystem del server, ma solo a partire (e poi, in giù) da quella che sarebbe stata la sua home directory, se si fosse collegato come terminale, sullo stesso computer che ospita il server FTP.

Esistono molte implementazioni di client e server FTP.

SFTP

Lo SSH File Transfer Protocol non è ancora uno standard Internet (l'ultimo Draft è scaduto), ma è utilizzato estensivamente come un vero e proprio protocollo di accesso remoto ad un filesystem. Non consiste nella esecuzione di FTP su di una connessione resa sicura via SSH, ma è un protocollo sviluppato ex-novo, che sfrutta i meccanismi di sicurezza offerti da uno strato che assicura tale funzione, ma l'accoppiata con SSH è particolamente diffusa e utilizzata.

NFS

Il Network File system venne inizialmente sviluppato nel 1984 da Sun Microsystem, e da allora ha subito diverse evoluzioni, fino alla ultima versione normativa definita dalla RFC 3530. Prevede che un computer -server NFS- offra parte del suo filesystem, per essere montato da altri computer -client NFS-, i quali da quel momento in poi, accedono al disco remoto come se fosse il proprio. E' utilizzato in special modo per realizzare delle stazioni di lavoro diskless, oppure per condividere dati e programmi su più macchine, senza doverli replicare.

SMB

Il Server Message Block è il protocollo usato dai prodotti Microsoft per condividere in rete files, stampanti, porte seriali e comunicazioni di varia natura, e include un meccanismo di comunicazione autenticata tra processi. Nato per essere usato principalmente su rete locale in associazione al NetBIOS, funziona anche su TCP/IP. Come per il caso precedente, sebbene possa ben essere usato per salvare le pagine web sul disco del server, ha degli scopi più articolati.

IMAP

L'Internet Message Acces Protocol, sebbene nato per la gestione dell'email, può altrettanto bene essere usato per trasferire file da/verso il proprio computer locale ed un computer remoto!

Webdav

Il Web Distributed Authoring and Versioning è una estensione di HTTP definita nella RFC 4918 per facilitare la collaborazione tra utenti nella gestione di documenti e file presenti su server HTTP. Consiste in un insieme di nuovi metodi ed intestazioni di HTTP che permettono oltre che di leggere, anche di scrivere, spostare, gestire la proprietà ed i diritti, e permettere la modifica delle pagine da parte di un gruppo di autori. Il supporto offerto dai sistemi operativi a Webdav permette in generale di vedere una URI HTTP come un filesystem esterno.

URL, URI, URN

Un indirizzo di livello applicativo che identifica una risorsa accessibile mediante HTTP è chiamata URI (Uniform Resource Identifier), come definito nella RFC 3986, ed estende i concetti di URL (Uniform Resource Locator, utilizzato per indicare anche dove trovare la risorsa, e come utilizzarla) ed URN (Uniform Resource Name, utilizzato esclusivamente per dare un nome univoco alla risorsa) precedentemente usati. La generica sintassi di una URI

<scheme>:<scheme-specific-part>

ne permette l'uso per identificare non solo un indirizzo web, ma anche (ad es.) un indirizzo email, un identificativo VoIP, un codice ISBN, o tante altre cose, in base al tipo di schema che vi compare, in accordo a quelli registrati presso lo IANA. Lo schema è indicativo del namespace sotto cui ricade la risorsa, e la sintassi della parte scheme-specific-part dipende dallo schema usato, ma per parecchi di questi, ci si può riferire a questo generico esempio relativo ad una URL HTTP:



in cui

Quando una URI compare come valore di un attributo href di un elemento anchor in una pagina HTML, il browser tenta di dereferenziare l'indirizzo, intraprendendo una azione legata allo schema che compare nella URI. Se ad esempio si tratta di un'altra pagina web, ne farà richiesta al server che la ospita, e visualizzerà il body della risposta, mentre se ad esempio si tratta di uno schema mailto (es. mailto:jsmith@example.com), manderà in esecuzione l'applicazione-client email (user agent) predefinita, impostando il destinatario a quello che compare nella URI.

HTTP

L'HyperText Transfer Protocol è definito nella sua versione attuale (1.1) dalla RFC 2616, che descrive la sintassi dei suoi messaggi per mezzo di un formalismo noto come forma aumentata di Backus-Naur (ABNF).

ABNF

Un breve parentesi, per illustrare come la ABNF è una sintassi formale orientata alla descrizione di grammatiche context-free, e che funziona mediante l'applicazione ripetuta di regole di produzione del tipo

simbolo = espressione

che indicano come dei simboli non terminali (a sinistra dell'uguale) possono essere riscritti in termini di sequenze di altri (terminali o meno). Partendo da un simbolo non terminale, si applicano ripetutamente le regole, finché non restano solo simboli terminali, per i quali non esistono regole di riscrittura, ed il risultato forma una frase appartenente al linguaggio che si sta descrivendo. L'espressione può indicare il semplice concatenamento di altre regole e simboli terminali, oppure l'alternativa tra essi

terno = numero numero numero / ambo numero
ambo = numero numero
numero = 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 0

mentre altre notazioni hanno altri significati, come ad esempio un [elemento] tra parentesi quadre è opzionale, ed un asterisco come in *ALPHA indica la ripetizione di un qualsiasi numero di ALPHA.

L'ABNF è spesso usata per descrivere i linguaggi di programmazione, e i formati dei protocolli Internet, e per questo, è documentata nella RFC 5234, ed è stata ulteriormente riassunta, nello stesso documento che descrive l'HTTP.

Da estremo a estremo

La figura che segue mostra il meccanismo di richiesta/risposta (client/server), a partire da un click su di una pagina, che determina il prelievo dei files dal sever web, che a sua volta provoca la comparsa del risultato sullo schermo. Lo User Agent (browser) nel ruolo di client, invia una richiesta HTTP su di una connessione TCP aperta verso l'indirizzo di trasporto corrispondente alla porta 80, ed il server restituisce la risposta sulla stessa connessione.

Vi sono quindi due tipi di messaggi HTTP: di richiesta e di risposta. Tanto che la ABNF per l'HTTP, inizia così:

generic-message = start-line
                  *(message-header CRLF)
                  CRLF
                  [ message-body ]

start-line      = Request-Line | Status-Line

Nelle prime versioni del protocollo, la connessione veniva chiusa immediatamente dopo che una richiesta era stata soddisfatta, in accordo alla natura senza stato (stateless) del protocollo: il server non mantiene memoria delle richieste precedenti, anche se provenienti dallo stesso client, ma le tratta tutte in modo indipendente l'una dall'altra. D'altra parte, nel caso in cui nella pagina ricevuta siano presenti elementi HTML (come ad es. di tipo <img>), che referenziano oggetti (immagini) da inserire nella pagina da visualizzare, queste vengono allora richieste subito di seguito alla pagina ricevuta. Per riassumere, un video.

Richiesta

In accordo alla descrizione ABNF su riportata, un messaggio di richiesta HTTP è composto da tre parti:

La riga di richiesta ha l'aspetto generico descritto dalla ABNF, a cui è affiancato un esempio reale

Request-Line   = Method SP Request-URI SP          HTTP-Version CRLF
es.              GET       /wiki/Pagina_principale HTTP/1.1

ed è composta dal metodo (qui, GET), dal nome della risorsa oggetto della richiesta (/wiki/Pagina_principale) così come compare nella URL che ha prodotto la richiesta stessa, e dal nome del protocollo con la sua versione. In generale, la risposta viene generata interpretando la risorsa come il nome di un file, completo di path relativo, che giace sul disco del computer che ospita il server, sotto una apposita directory.

Metodi

Dei metodi possibili descritti dalla RFC, i più frequentemente usati sono

Intestazioni di Richiesta

Il formato delle righe di intestazione HTTP segue quello specificato per il caso delle email, ossia il nome dell'header, seguito da due punti, e poi una stringa che ne specifica il valore. Mentre nelle email, però, gli header sono a prevalente beneficio del ricevente, nell'HTTP sono realmente funzionali al protocollo, e sono presenti sia nelle richieste, che nelle risposte. L'insieme completo dei Request Header che possono comparire nelle richieste è specificato nella RFC. A partire da un esempio concreto, possiamo discutere di

Risposta

E' composta di tre parti:

Il body è presente nel caso in cui il codice di risposta indichi un successo, ed è posto di seguito alla sezione degli header, separato da questi da una linea vuota, come per l'email.

Codici di risposta

La prima riga della risposta ha un aspetto del tipo

HTTP/1.1 200 OK

ed il codice di risposta (nell'esempio, 200 OK) segue le convenzioni già viste per l'email, in cui la prima cifra dà una indicazione relativa all'esito della richiesta, in accordo allo schema. La descrizione dei casi d'uso dei diversi codici è contenuta nella RFC 2616, e wikipedia ne presenta un elenco sintetico. Alcuni codici di risposta particolarmente significativi sono

Intestazioni di risposta

Commentiamo assieme il capture relativo alla richiesta ripetuta della URI http://infocom.uniroma1.it/alef/tesi/.

Incapsulamento risultante

In definitiva, una richiesta o risposta HTTP che entrasse per intero in uno stesso segmento TCP, e nel caso fosse una risposta, contenesse una pagina HTML, avrebbe la composizione mostrata di seguito:

Ethernet IP TCP
Request o Status line e
Header HTTP
                  Body HTTP
Head HTML                    Body HTML                  

Caching

Nella navigazione web sono presenti una o più cache intermedie, che hanno lo scopo di alleggerire il carico dei server. Una prima cache è interna al browser, ma in rete possono esserne dislocate altre, che prendono il nome di Proxy, a cui il client può indirizzare tutte le richieste (dovunque dirette), e che si fa carico di effettuare le richieste per suo conto, e di fornire la risposta.

Se le risorse richieste giacciono già nella cache (del proxy, o del browser), queste possono essere restituite direttamente, senza recuperarle nuovamente dal server di origine, che quindi riduce l'occupazione di banda di uscita. Se diversi client usano lo stesso proxy, e referenziano le stesse pagine, il risparmio di banda può diventare considerevole, e può convenire dislocare un proxy interno ad una sottorete, da far condividere a tutti i client di quella sottorete.

Un meccanismo che consente l'accesso diretto alle repliche presenti in cache è quello di validazione, ottenuto rendendo i metodi di richiesta condizionali, mediante l'inserimento degli header

In questo modo, se il server verifica che l'oggetto è sempre uguale (ossia, la data è la stessa, e/o l'Etag coincide), risponde con un codice 304 Not Modified, ed il browser (il proxy) visualizza (invia) il contenuto della propria cache. Un esempio di tale comportamento, può essere riscontrato nel file di capture già analizzato.

Un secondo meccanismo di gestione delle cache si basa invece su di una logica di obsolescenza (expiration), fondata sull'uso di alcuni header specifici, come

Quando un client sta per effettuare una richiesta di un oggetto che ha in cache, ma che non è ancora spirato, può scegliere di rinunciare ad effettuare la richiesta, e visualizzare la sua copia locale. Al contrario, un server può tentare di impedire che un oggetto da esso inviato venga memorizzato nelle cache, usando i valori no-cache, no-storemust-revalidate, come ad esempio avviene nel caso di pagine dinamiche ottenute mediante l'esecuzione di CGI.

Intercepting e Reverse Proxy

Mentre tutti i browser hanno la possibilità di configurare volontariamente un proxy a cui inoltrare le richieste, può succedere che i router della LAN o del provider provvedano di loro iniziativa a reinstradare i pacchetti IP associati a comunicazioni HTTP, in modo che attraversino un Proxy. Questa funzionalità prende il nome di Transparent o Intercepting Proxy.

Un Reverse Proxy al contrario, invece di essere usato per uscire, è usato per smistare il traffico in ingresso ad una lan, verso una pluralità di web server interni, ognuno che serve pagine per un diverso dominio, e potenzialmente configurati con un IP privato. Questo ha lo scopo di migliorare la sicurezza, di permettere il bilanciamento del carico, oltre naturalmente a realizzare il caching delle pagine in uscita.

Redirezione

Le risorse associate agli URI presenti su determinate pagine web, e dalle quali possono essere richieste, possono nel frattempo essere state trasferite su computer differenti e cambiare la componente dominio della URI, oppure possono essere state ri-nominate, e pur rimanendo sullo stesso server (e dominio), prendere un URI diverso. In tal caso, le richieste che citano il vecchio indirizzo si vedrebbero restituire una risposta del tipo 404 Not Found, producendo disappunto e frustrazione. La soluzione offerta da HTTP si basa su di un meccanismo di redirezione, che usa i codici di risposta 301-303 e 307, e che comunica il nuovo indirizzo come valore associato all'header Location presente nella risposta. La differenza tra i diversi codici di risposta risiede nelle possibilità che il nuovo indirizzo sia temporaneo o permanente (nel qual caso, i collegamenti preferiti dovrebbero aggiornarsi automaticamente), e nella possibilità che il browser segua automaticamente il nuovo indirizzo, oppure chieda prima conferma all'operatore umano.

Affinché il server verso cui sono dirette le richieste per risorse che non ci sono più, risponda con un codice di tipo 3xx Moved anziché 404 Not Found, il server stesso deve essere debitamente configurato in tal senso.

Negoziazione dei contenuti

L'HTTP permette la negoziazione dei contenuti, ossia consente allo User Agent di esprimere le proprie preferenze a riguardo delle diverse possibili versioni degli oggetti richiesti, delegando poi al server di decidere. Oppure, al contrario, si consente al Server di offrire una scelta di possibilità, ed allo UA di decidere quale utilizzare. Queste preferenze vengono espresse mediante l'uso di appositi header nella richiesta, come Accept, Accept-Charset, Accept-Encoding, Accept-Language, e User-Agent. Il server quindi, utilizza l'header di risposta Vary per specificare su quali dimensioni si è effettuata la scelta del tipo di contentenuto da inviare. Per una descrizione dei metodi usati per gestire la fase di negoziazione dei contenuti, ci si può riferire alla documentazione relativa al server Web Apache.

Connessioni Persistenti

Quando uno UA invia più richieste consecutive verso uno stesso server, come nel caso, ad esempio, in cui si vogliano scaricare tutte le immagini contenute in una determinata pagina appena ricevuta, è molto più sensato ri-utilizzare sempre la stessa connessione TCP, piuttosto che aprirne una diversa per ogni diverso oggetto richiesto. In tal modo, oltre a risparmiare sui tempi necessari al Round Trip Time necessario per l'apertura e la chiusura delle connessioni, si riduce l'occupazione di memoria necessaria ai buffer del TCP, e la gestione del controllo di congestione attuata dal TCP può evolvere su di un intervallo temporale più ampio.

Pipeline

Nel caso si adottino connessioni persistenti, un client può inviare le richieste in pipeline, ossia una di seguito all'altra, senza attendere la fine della risposta alla richiesta precedente; in tutti i modi, è prescritto che il server invii le risposte nello stesso ordine con cui sono pervenute le richieste.

Connection Header

Nella versione 1.1 di HTTP, le connessioni persistenti sono il funzionamento di default, che può essere sovvertito qualora il client (il server), invii assieme alla richiesta (risposta) l'header Connection: Close. Viceversa, per compatibilità con versioni precedenti del protocollo, il desiderio esplicito di usare connessioni persistenti può essere segnalato mediante l'header Connection: KeepAlive.

Un esempio di utilizzo delle conessioni persistenti, è dato dal file di capture relativoalla richiesta della URI http://www.ubuntu-it.org/index.php?page=Filosofia.

Compressione e Transfer-Encoding

Qualora la richiesta lo permetta (dichiarando tramite l'header Accept-Encoding della richiesta, uno o più algoritmi scelti tra gzip, compress, e deflate), il body della risposta HTTP può contenere un oggetto che è memorizzato, e trasmesso, in forma compressa, ed in tal caso l'header Content-Encoding esprimerà quale sia stato l'algoritmo di compressione scelto. D'altra parte, l'oggetto richiesto può essere memorizzato presso il server in formato nativo, e compresso solo al momento della trasmissione: questa circostanza, viene segnalata per mezzo dell'header Transfer-Encoding, che oltre ai valori prima elencati, prevede anche la codifica chunked.

Chunked transfer encoding

Più codifiche di trasferimento possono essere applicate in cascata, ma chunked deve essere applicata per ultima, perchè questa anziché realizzare una trasformazione dell'oggetto richiesto, lo segmenta in blocchi (chunks). Questa tecnica è usata quando il server non conosce a priori la dimensione dell'oggetto inviato, perché questo è il risultato di un calcolo ancora in corso, oppure perché si tratta di un contenuto audio/video generato in tempo reale. Al fine di evitare di dover dichiarare una dimensione ignota nell'header Content-length della risposta, l'oggetto viene inviato in modalità chunked, e all'inizio di ogni chunk viene dichiarata l'estensione dello stesso. Come esempio, possiamo esaminare il traffico catturato durante la visita al sito di HttpWatch.

Sicurezza

Nei termini definiti al capitolo precedente, la sicurezza in http è volta ad offrire uno o più dei seguenti servizi:

Mentre per gli ultimi due punti si ricorre essenzialmente alla attivazione del TLS, il primo punto, anche se potenzialmente gestibile con meccanismi appositamente definiti per l'HTTP, viene generalmente implementato a cura di uno strato applicativo ancora superiore all'HTTP, mediante le tecniche dei CGI, dei cookie, o del javascript. Ma iniziamo, comunque, dal meccanismo basato sul solo HTTP.

Autenticazione

Il meccanismo di autenticazione previsto da HTTP si basa su di uno schema challenge-response, in cui il server dopo aver ricevuto la richiesta di un oggetto per il quale è stato ristretto l'accesso, anziché inviare la risposta contenente l'oggetto, emette una risposta con la quale sfida il client ad autenticarsi; questi sottomette quindi una nuova richiesta, a cui allega le proprie credenziali. Sono previste due modalità di autenticazione, dette Basic e Digest, descritte nella RFC 2617, entrambe basate sulla conoscenza di un segreto (ossia, di una coppia username-password) condiviso tra client e server.

Basic Access Authentication

Questo schema è da considerare assolutamente insicuro, e da usare solo in un ambito del tutto fidato, in quanto la password è inviata in chiaro, seppur con codifica base64. La prima risposta (di sfida) del server, che riporta un codice 401 Unauthorized, contiene un header

WWW-Authenticate: Basic realm="Laboratorio Internet"

In tal caso il browser presenta all'utente una nuova finestra, in cui cita il valore del Realm (in modo che l'utente possa ricordare quali credenziali usare), e richiede l'immissione di una coppia utente-password. Ad esempio, l'identità dell'utente "Aladdin" con password "open sesame" saranno combinati assieme come "Aladdin:open sesame", e quindi rappresentati con codifica base64, come QWxhZGRpbjpvcGVuIHNlc2FtZQ== (come verifica, eseguire da terminale il comando echo QWxhZGRpbjpvcGVuIHNlc2FtZQ== | base64 -d). Pertanto, dopo l'immissione di utente e password da parte di chi siede di fronte al computer, il browser reitera la richiesta precedente, aggiungendo alla stessa una intestazione

Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==

che questa volta produce nel server l'invio della pagina protetta. Un esempio del comportamento descritto, si può ottenere visitando questa pagina protetta, (username/password = labint/lablint) a cui corrisponde questo file di capture.

Digest Access Authentication

Dal punto di vista dell'utente, il funzionamento di questo schema è del tutto identico al precedente; al contrario di quello, però, la password viene inviata in una forma crittograficamente sicura. Anche ora il server risponde alla prima richiesta, con una risposta che riporta il codice 401 Unauthorized, ma che stavolta contiene un header di sfida del tipo

WWW-Authenticate: Digest realm="testrealm@host.com",
                         qop="auth,auth-int",
                         nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
                         opaque="5ccc069c403ebaf9f0171e9517f40e41

Mentre il realm ha come prima lo scopo di essere mostrato all'utente, il nonce viene usato assieme al nome utente, alla password, al realm, al metodo, all'URI della risorsa, ad un contatore di richiesta (nc), al codice di quality of protection (qop) prescelto, e ad un nonce del client (cnonce), per calcolare (mediante il calcolo ripetuto di un hash MD5), il valore della response da inserire nell'header Authorization da restituire al server:

Authorization: Digest username="Mufasa",
                      realm="testrealm@host.com",
                      nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
                      uri="/dir/index.html",
                      qop=auth,
                      nc=00000001,
                      cnonce="0a4f113b",
                      response="6629fae49393a05397450978507c4ef1",
                      opaque="5ccc069c403ebaf9f0171e9517f40e41"

Il server usa la stessa password (o meglio, una sua versione crittografata) per effettuare lo stesso calcolo, ed autenticare l'utente.

SSL/TLS

Qualora si desideri un livello di sicurezza maggiore di quello offerto dal semplice uso della autenticazione HHTP, si può ricorrere al Secure Sockets Layer (SSL), ovvero alla sua più recente denominazione TLS. In tal caso, la URI presenta una schema di tipo https, che causa l'apertura di una connessione TCP verso la porta 443 anziché la 80. A quel punto, un messaggio di Client_Hello (capture) determina l'inizio dell'handshake protocol, al termine del quale l'applicazione prosegue come se si trattasse di una normale connessione HTTP su TCP, mentre invece tutto il traffico si svolge in modalità crittografata, come descritto nella RFC 2818. Nelle esercitazioni, troviamo la descrizione di come dotare il nostro server web Apache di un certificato X.509, ed attivare un host virtuale che risponda all'HTTPS.

Header Upgrade

Anzichè usare una diversa porta come per il caso dell'https, la RFC 2817 descrive l'uso del codice di risposta 426 Upgrade Required, e dell'header Upgrade posto nella nuova richiesta, tali da permettere ad una connessione HTTP normale, di passare in una modalità protetta da TLS, sempre usando la stessa porta 80. Questo, oltre che permette di risparmiare un indirizzo di trasporto, consente di ospitare dei server virtuali sicuri su di un medesimo computer, senza necessità di assegnare allo stesso molteplici indirizzi IP. Infatti, se il TLS si attiva prima dell'HTTP, il certificato da inviare ai client è scelto solo in base all'indirizzo IP dal lato server del socket, mentre se parte prima l'HTTP, la scelta può tener conto anche del nome a dominio che compare nell'intestazione Host.

Dal lato del browser

Dopo aver illustrato molti dettagli dell'HTTP, svolgiamo un approfondimento di ciò che accade ai due estremi della navigazione web, iniziando da quando una risposta giunge al browser, e come possano entrare in gioco meccanismi differenti dalla semplice visualizzazione della pagina ricevuta. Quindi, illustriamo come possono essere gestiti gli schemi della URI diversi da http. Infine, discutiamo come si possano inviare, assieme ad una richiesta HTTP, anche alcuni dati intenzionalmente immessi dall'operatore umano.

Gestione dei Mime-Type ed embedding

La risposta HTTP contiene, tra gli altri, l'header Content-Type, che identifica il documento trasportato nel body, come aderente ad uno dei tipi MIME registrati presso IANA. Alcuni di questi sono direttamente visualizzabili dal browser, mentre per altri, viene invocata una Helper Application, posta in corrispondenza al tipo di file dal sistema operativo stesso, oppure memorizzata a seguito di una domanda a riguardo, posta all'utente. Ma non sempre un server web invia un header Content-Type (perchè ciò avvenga, deve essere opportunamente configurato), e così a volte il browser deve tentare di assegnare per suo conto un Mime Type al file ricevuto, in base all'estensione del file, oppure analizzando l'inizio dello stesso. Se tutti i tentativi falliscono, il file viene trattato come application/octet-stream, e viene suggerito di salvarlo su disco.

Plugin

Un volta determinato con successo il Mime-Type dell'oggetto ricevuto, e individuata l'applicazione Helper idonea a visualizzare/riprodurre lo stesso, questa può essere eseguita in modo indipendente, o esterno al browser, oppure direttamente all'interno della finestra del browser. In questo secondo caso, il programma Helper prende il nome di plugin, in quanto non può essere eseguito in modo indipendente, dipendendo dai servizi offerti dal browser stesso, come ad esempio l'interfaccia grafica. A volte invece, un plugin ha il solo scopo di far eseguire una applicazione preesistente, che altrimenti verrebbe eseguita esternamente al browser, all'interno dello stesso. La configurazione attuale dei plugin del browser Firefox, ad esempio, può essere visualizzata immettendo l'indirizzo about:plugins nella sua barra degli indirizzi.

Protocolli registrati

A volte il programma da usare per visualizzare/riprodurre un oggetto richiesto mediante web, non è determinato al momento dell'arrivo della risposta, bensì al momento in cui viene cliccata la URI presente in una pagina web. Se la URI fa riferimento ad uno schema che non è http, allora il browser non invierà nessuna richiesta http, ed invocherà invece un programma apposito, passandogli la URI come argomento, delegando a questo il compito di procedere, in accordo al protocollo associato alla URI.

Ad esempio, cliccando una URI per la quale lo schema è mailto:, verrà mandato in esecuzione lo UserAgent di invio email, nella cui finestra di composizione troveremo pre-impostate le informazioni relative all'indirizzo di destinazione, come desunte dal resto della URI (vedi anche RFC2368). Come ulteriore esempio, nel caso di uno schema ftp://, è il browser stesso ad effettuare una connessione anonima e permettere la navigazione nel file system remoto: provare ad es. con ftp://ftp.debian.org/debian/.

Configurazione di Firefox

In Firefox, le preferenze per quanto riguarda le modalità di navigazione e di gestione delle informazioni ricevute possono essere impostate inserendo l'indirizzo about:config nella barra degli indirizzi; l'effetto di tale azione, oltre a mostrare i valori impostati agendo sul menù delle preferenze, ne visualizza anche molti altri, definiti in accordo a queste regole di configurazione. In particolare,

Esecuzione codice

A volte la risposta HTTP, anziché contenere un oggetto (come ad es. una pagina HTML, una immagine, od un contenuto multimediale) che deve essere semplicemente mostrato dal browser (o da un plugin, o da una helper application), consegna allo UA del vero e proprio codice eseguibile, rendendo così il web un meccanismo di distribuzione di applicazioni, ossia un application server. Fin qui nulla di straordinario, tranne per il fatto che il codice ricevuto deve essere eseguito indipendentemente dal S.O. presente sul computer presso il quale è utilizzato il browser, ed a questo fine, sono state sviluppate le soluzioni proposte con Java, Javascript e Flash, brevissimamente descritte appresso.

Java

Il linguaggio Java è stato definito da Sun Microsystem (ora propretà di Oracle), che recentemente l'ha rilasciato con licenza GPL, ma che fin dal 1998 ha adottato un modello di sviluppo aperto indicato come Java Community Process. Java è basato su oggetti, e presenta una sintassi abbastanza simile al c++ (video corso in italiano).

La compilazione del codice sorgente Java produce un eseguibile detto bytecode che, anziché essere legato ad un particolare tipo di ambiente hardware/software, deve essere eseguito da un altro programma, denominato Java Virtual Machine (JVM), che costituisce lo strato software che effettivamente interagisce con il computer ospite. Pertanto, se il bytecode è uno, di macchine virtuali ce ne sono tante, quante sono le architetture alternative.

Le versioni di JVM più recenti prevedono un ulteriore passo di elaborazione del bytecode, detto compilazione Just In Time (JIT), e che produce il codice macchina relativo alla architettura ospite, direttamente al momento della esecuzione. In una pagina HTML possono essere presenti diverse applet java, inserite nella stessa mediante l'elemento HTML <object>. Il nutrito insieme di librerie di classi disponibili per Java, permette di scrivere applicazioni (applet) di ogni tipo, anche con accesso alla rete, e che una volta ricevute tramite web, sono eseguite in una cosiddetta sandbox, in modo da limitare al minimo indispensabile i diritti di uso ed accesso alle risorse del computer ospite.

JME

La Java Micro Edition è la specifica di un sottoinsieme della piattaforma Java, idoneo per lo sviluppo di applicazioni da utilizzare nell'ambito di dispositivi con prestazioni ridotte, come ad es. i telefoni cellulari, ed il cui codice sorgente è stato rilasciato sotto licenza GPL con il nome di PhoneMe; dato che l'ambiente può essere emulato su computer, lo sviluppo di nuove applicazioni mobili è particolarmente facilitato.

Le funzionalità di cui una applicazione JME può usufruire sono descritte dalla applicazione di un particolare profilo, identificato al momento della configurazione della JME di cui è equipaggiato il dispositivo su cui l'applicazione dovrà essere eseguita. Ad esempio, la Connected Limited Device Configuration (CLDC) contiene un sotto-insieme minimo di librerie di classi Java, e quando accoppiata alla Mobile Information Device Profile (MIDP), viene definito un ambiente dotato di una API alla interfaccia grafica (GUI), e di una API orientata alla esecuzione di giochi bi-dimensionali: le applicazioni scritte per questo profilo, sono dette MIDlets.

Javascript

Mentre per Java, il bytecode ricevuto deve essere eseguito da una JVM (che non è detto sia installata), il codice Javascript è inviato in forma di sorgente, è molto semplificato rispetto a Java (con cui non ha neanche molto a vedere, se è per quello), e viene eseguito direttamente dal browser. Il sorgente viene così interpretato riga per riga dallo UA stesso; per mantenere compatibilità tra i diversi UA, Javascript è stato sottoposto ad un processo di standardizzazione da parte di ECMA, riconosciuto anche da ISO, e che gli ha portato il secondo nome di ECMAscript. Ciononostante, le implementazioni di Javascript su browser diversi sono parzialmente incompatibili, ed il codice Javascript deve fare del suo meglio per tentare di capire dove si trova, ed evitare di eseguire istruzioni che potrebbero essere interpretate per il verso sbagliato. Queste tecniche sono state poi incorporate nelle svariate librerie (o framework) che offrono funzioni di più alto livello, realizzate mediante funzioni scritte in javascript.

L'uso tradizionale di Javascript è stato quello di produrre particolari effetti grafici non ottenibili con il solo HTML, ma che attualmente sono possibili utilizzando il CSS. Javascript viene altresì usato per modificare al volo una pagina HTML ricevuta prima che questa venga visualizzata, intervenendo direttamente su di una sua rappresentazione interna al Browser, nota con il nome di Document Object Model (DOM).

Presso la sezione dei riferimenti troviamo alcuni interessanti links a siti che consentono di sperimentare la programmazione Javascript modificando direttamente degli esempi già pronti.

AJAX

Rappresenta l'acronimo di Asynchronous JavaScript and XML, e individua l'utilizzo congiunto di diverse tecnologie per realizzare pagine web interattive che si comportano in maniera sensibilmente più pronta di quelle tradizionali, in quanto il ciclo richiesta-risposta non avviene più solo ad opera dell'utente, ma è il browser stesso, eseguendo del codice javascipt, a condurre una dialogo asincrono con il Server, mentre l'utente interagisce con la rappresentazione dei dati mostrata dal browser. Ad esempio, nel caso in cui si clicchi per poter vedere delle informazioni aggiuntive, qualora venga mostrato un indicatore di avanzamento, significa che il browser è in attesa dei dati mancanti, e richiesti al server mediante l'oggetto XMLHttpRequest(), usati poi per modificare il DOM della pagina visualizzata. Ad esempio, è questa la tecnologia usata da siti popolari come facebook e google.





La X di AJAX sta per XML, in ossequio al formato di serializzazione dei dati che sono richiesti da Javascript via HTTP, come usato nelle prime implementazioni: in tal caso infatti i dati sono rappresentati come dei frammenti XML, consentendo così di esprimere anche informazioni complesse e strutturate.

JSON

Acronimo di JavaScript Object Notation, si pone in alternativa ad XML per la serializzazione dei dati ricevuti tramite una richiesta HTTP, come dichiarato nel Content-type di risposta, pari a application/json. La RFC 4627 descrive la sintassi usata per esprimere questa rappresentazione dei dati, che può essere riassunta in poche semplici regole, e che sostanzialmente coincide con la notazione usata da Javascript per rappresentare le proprie strutture dati: infatti, lo stesso oggetto JSON ricevuto può essere eseguito dall'interprete javascript mediante la funzione eval(), che trasforma le strutture dati ricevute, in dati direttamente disponibili al programma. D'altra parte, se nel JSON ricevuto fosse presente anche del codice eseguibile (sempre javascript), questo sarebbe effettivamente eseguito, ponendo problemi di sicurezza. Perciò, questo semplice modo di procedere è stato sostituito dall'utilizzo di una diversa funzione, JSON.parse(), che è stata introdotta nelle versioni più recenti dei borowser, e chi si limita ad interpretare unicamente le strutture dati permesse da JSON, e non qualsiasi possibile costrutto di Javascript, come invece avviene per la eval().

Dato che i dati codificati in json possono in linea di principio essere utilizzati da un qualunque altro linguaggio di programmazione, e non solo da javascript, sono state sviluppate una serie di librerie (vedi a metà pagina di json.org) che effettuano il parsing di una stringa json in praticamente qualunque linguaggio di programmazione, rendendono così la codifica json un metodo universale per lo scambio dati.

Flash

Nel 1995 viene distributo FutureSplash, un plugin capace di produrre grafica vettoriale animata all'interno del browser. La ditta originaria viene acquisita nel '96 da Macromedia, sviluppatrice del concorrente Shockwave, e i due prodotti vengono fusi in Macromedia Flash; a partire dal 2005, i diritti sulla tecnologia sono acquisiti da Adobe Systems.

Il plugin Flash viene prodotto per architetture Windows, Macintosh e Linux, e rappresenta una sorta di browser nel browser. Le animazioni Flash vengono definite per mezzo del linguaggio interpretato ActionScript, molto simile al Javascript, e che viene eseguito da una Actionscript Virtual Machine, che nella sua realizzazione più recente dispone anche di un compilatore Just In Time.

La grande diffusione di Flash in moltissimi siti web ne ha favorito la crescita, ed attualmente è la tecnologia in assoluto più usata per la diffusione di contenuti multimediali via web.

Riempimento moduli

In HTML è definito l'elemento <form> (modulo o modello), tra i cui tag di apertura e chiusura, oltre ad altri elementi HTML qualsiasi, si possono inserire elementi particolari detti controlli, che vengono visualizzati dal browser come campi di inserimento all'interno di moduli. Per fissare fin da subito le idee, qui appresso è mostrata la visualizzazione corrispondente al codice mostrato a fianco, in cui compaiono i campi di inserimento prodotti dai controlli <input> con attributo type pari a text, radio, checkbox, submit, oltre ai controlli select e textarea, da verificare con l'aiuto della descrizione semantica dei controlli.

Action

L'elemento <form> presenta un attributo particolare, denominato action, che identifica una URI da invocare quando l'utente aziona un pulsante di inoltro, a cui corrisponde un programma (che come vedremo prende il nome di CGI) da eseguire presso il server HTTP, URI che viene citata nella corrispondente richiesta HTTP, effettuata usando il metodo definito dall'attributo (sempre di form) method

Parametri di chiamata

La particolarità della URI che compare nell'attributo action è che anziché rappresentare una risorsa statica, individua un programma CGI, invocato con argomenti impostati in base ai contenuti inseriti mediante i campi di inserimento offerti dai controlli: per ogni campo (controllo) della form, è specificato infatti un attributo name, che rappresenta un nome di variabile, a cui viene associato il valore immesso dall'utente in corrispondenza di quel campo, oppure preimpostato mediante l'attributo value.

codice HTML risultato visualizzato
<FORM method="get" action="bar.php">
 <TABLE border="1">
   <TR bgcolor="#CCCCFF">
    <TH>Nome</TH>
    <TH>Valore</TH>
   </TR>
   <TR>
    <TD>Ti chiami</TD>
    <TD><input name="tichiami" type="text" size="25"></TD>
   </TR>
   <TR>
    <TD>Genere</TD>
    <TD>
     <input type="radio" name="sex" value="uomo">
            Maschile<BR>
     <input type="radio" name="sex" value="donna" checked>
            Femminile</TD>
   </TR>
   <TR>
    <TD>Colore occhi</TD>
    <TD>
     <select name="occhi">
      <option
selected>blu</option>
      <option>castani</option>
      <option>verdi</option>
      <option>altro</option>
     </select>
    </TD>
   </TR>
   <TR>
    <TD>Altre caratteristiche</TD>
    <TD>
     <input type="checkbox" name="altezza" value="1">
            Alto più di 1,80</input><BR>
     <input type="checkbox" name="peso" value="1">
            peso più di 80 Kg</input>
    </TD>
   </TR>
   <TR>
    <TD colspan="2">Descrivi le tue
                    attitudini atletiche:<BR>
     <textarea name="athletic" cols="50" rows="4">
     </textarea>
    </TD>
   </TR>
   <TR>
    <TD colspan="2" align="center">
     <input type="submit" value="Invia le tue informazioni">
    </TD>
   </TR>
 </TABLE>
</FORM>
Nome Valore
Ti chiami
Genere Maschile
Femminile
Colore occhi
Altre caratteristiche Alto più di 1,80
peso più di 80 Kg
Descrivi le tue attitudini atletiche:

Controlli

Descriviamo la semantica di un sotto-insieme essenziale di controlli HTML, rimandando alla normativa ufficiale per la loro definizione completa, e ad altri siti per la loro sperimentazione interattiva.

Esempio di form

Per sperimentare l'effetto della esecuzione di questo e dei prossimi esempi, occorre installare sul proprio computer il server web Apache e configurarlo come indicato nella esercitazione collegata a questo capitolo, e quindi installare nella propria directory public_html gli esempi forniti e che consistono nei programmi CGI invocati mediante l'attibuto action delle form illustrate nel seguito. Il primo esempio di form, consiste nel seguente codice HTML:

<form method="get" action="http://127.0.0.1/labint/primocgi.cgi">
  <table  style="background-color: rgb(255, 247, 229); width: 85%; margin-left: auto;
                 margin-right: auto;" border="1" cellpadding="4" cellspacing="2">
    <caption><i>Esempio di Inserimento</i></caption>
     <tbody>
      <tr>
        <td align=right width=30%>email:</td>
        <td><input type="text" maxlength="50" name="email"></td>
      </tr>
      <tr>
        <td align=right>ordine:</td>
        <td>
        <table align=left cellpadding="2" cellspacing="2">
          <tbody>
            <tr>
              <td> <input name="ordine" value="pizza" type="radio">pizza</td>
            </tr> <tr>
              <td><input checked="checked" name="ordine" value="lasagna" type="radio">
                         lasagna</td>
            </tr> <tr>
              <td><input name="ordine" value="tiramisu" type="radio">tiramisu</td>
            </tr> <tr>
              <td><input name="ordine" value="pinta" type="radio">pinta</td>
            </tr>
          </tbody>
        </table>
        </td>
      </tr>
      <tr>
        <td align=right><input name="ok" value="ok" type="submit"></td>
        <td align=left><input name="reset" value="reset" type="reset"></td>
      </tr>
    </tbody>
  </table>
</form>

che produce la visualizzazione seguente:

Esempio di Inserimento
email:
ordine:
pizza
lasagna
tiramisu
pinta

e che, quando viene premuto (nella versione on-line del testo) il tasto ok, condiziona il browser ad effettuare una richiesta HTTP (con il metodo GET) della URI http://127.0.0.1/labint/primocgi.cgi indicata nell'attributo action dell'elemento form, e che (avendo configurato Apache ed installato il codice) produce come risultato una pagina HTML, che il server web ci invierà come risposta.

Dato che l'esistenza del meccanismo dei CGI ha reso il WWW classico (ossia, il trittico composto da URI, HTTP e HTML) una sorta di sottostrato su cui realizzare vere e proprie applicazioni di elaborazione distribuita, dedichiamo a questi ulteriori aspetti (e non solo) il prossimo capitolo.

Riferimenti

x
Logo

Lo Strato Applicativo
di Internet

Dal TCP al VoIP, dal DNS all'Email alla crittografia, tutto ciò che accade dietro le quinte di Internet, completo di cattura del traffico.
Scopri come effettuare il download, ricevere gli aggiornamenti, e contribuire!


Realizzato con Document made with Kompozer da Alessandro Falaschi -
Capitolo: Applicazioni Web e Overlay Networks