Passa al contenuto principale

8. Dati e Metadati di Rappresentazione (Representation Data and Metadata)

8.1. Dati di Rappresentazione (Representation Data)

I dati di rappresentazione associati a un messaggio HTTP sono forniti come contenuto del messaggio o sono riferiti dalla semantica del messaggio e dall'URI di destinazione. I dati di rappresentazione sono in un formato e codifica definiti dai campi di intestazione dei metadati di rappresentazione.

Il tipo di dati dei dati di rappresentazione è determinato tramite i campi di intestazione Content-Type e Content-Encoding. Questi definiscono un modello di codifica ordinato a due livelli:

representation-data := Content-Encoding( Content-Type( data ) )

8.2. Metadati di Rappresentazione (Representation Metadata)

I campi di intestazione di rappresentazione forniscono metadati sulla rappresentazione. Quando un messaggio include contenuto, i campi di intestazione di rappresentazione descrivono come interpretare quei dati. In una risposta a una richiesta HEAD, i campi di intestazione di rappresentazione descrivono i dati di rappresentazione che sarebbero stati inclusi nel contenuto se la stessa richiesta fosse stata un GET.

8.3. Content-Type

Il campo di intestazione「Content-Type」indica il tipo di media della rappresentazione associata: o la rappresentazione inclusa nel contenuto del messaggio o la rappresentazione selezionata, come determinato dalla semantica del messaggio. Il tipo di media indicato definisce sia il formato dei dati sia il modo in cui quei dati sono destinati ad essere elaborati da un destinatario, nell'ambito della semantica del messaggio ricevuto, dopo che qualsiasi codifica di contenuto indicata da Content-Encoding è stata decodificata.

Content-Type = media-type

I tipi di media sono definiti nella Sezione 8.3.1. Un esempio del campo è

Content-Type: text/html; charset=ISO-8859-4

Un mittente che genera un messaggio contenente contenuto DOVREBBE (SHOULD) generare un campo di intestazione Content-Type in quel messaggio a meno che il mittente non conosca il tipo di media previsto della rappresentazione inclusa. Se un campo di intestazione Content-Type non è presente, il destinatario PUÒ (MAY) assumere un tipo di media di「application/octet-stream」([RFC2046], Sezione 4.5.1) o esaminare i dati per determinarne il tipo.

In pratica, i proprietari delle risorse non sempre configurano correttamente il loro server di origine per fornire il Content-Type corretto per una data rappresentazione. Alcuni agenti utente esaminano il contenuto e, in certi casi, sovrascrivono il tipo ricevuto (ad esempio, vedere [Sniffing]). Questo「sniffing MIME」rischia di trarre conclusioni errate sui dati, il che potrebbe esporre l'utente a rischi di sicurezza aggiuntivi (ad esempio,「escalation di privilegi」). Inoltre, è spesso il caso che diversi tipi di media utilizzino lo stesso formato di dati ma differiscano solo nell'elaborazione prevista di quei dati, il che non può essere distinto ispezionando i dati da soli. Quando viene implementato lo sniffing, gli implementatori sono incoraggiati a fornire un mezzo per l'utente per disabilitarlo.

Sebbene Content-Type sia definito come un campo singleton, a volte viene generato erroneamente più volte, risultando in un valore di campo combinato che appare come una lista. I destinatari spesso tentano di gestire questo errore utilizzando l'ultimo membro sintatticamente valido della lista, il che può portare a potenziali problemi di interoperabilità e sicurezza se diverse implementazioni hanno comportamenti di gestione degli errori diversi.

8.3.1. Tipo di Media (Media Type)

HTTP utilizza tipi di media [RFC2046] nei campi di intestazione Content-Type (Sezione 8.3) e Accept (Sezione 12.5.1) al fine di fornire tipizzazione dei dati e negoziazione dei tipi aperti ed estensibili. I tipi di media definiscono sia un formato di dati sia vari modelli di elaborazione: come elaborare quei dati in conformità con il contesto del messaggio.

media-type = type "/" subtype parameters
type = token
subtype = token

Il type/subtype PUÒ (MAY) essere seguito da parametri delimitati da punto e virgola (Sezione 5.6.6) sotto forma di coppie nome/valore. La presenza o l'assenza di un parametro potrebbe essere significativa per l'elaborazione di un tipo di media, a seconda della sua definizione nel registro dei tipi di media.

Un valore di parametro che corrisponde alla produzione token può essere trasmesso senza virgolette. Tuttavia, un valore di parametro con un carattere non valido (cioè, che non corrisponde alla produzione token) DEVE (MUST) essere tra virgolette doppie (Sezione 5.6.4) quando viene inviato.

parameter      = parameter-name "=" parameter-value
parameter-name = token
parameter-value = ( token / quoted-string )

Nota: Alcuni destinatari di parametri di tipo di media li trattano in modo sensibile alle maiuscole. È generalmente raccomandato utilizzare minuscole per i nomi dei parametri e utilizzare il caso più comune per i valori dei parametri.

I tipi di media dovrebbero essere registrati presso IANA secondo le procedure definite in [BCP13].

Nota: A differenza di alcuni costrutti simili in altri campi di intestazione, i parametri dei tipi di media non consentono spazi bianchi (nemmeno「cattivi」) attorno al carattere「=」.

8.3.2. Charset

HTTP utilizza nomi di set di caratteri nei campi di intestazione Content-Type (Sezione 8.3) e Accept-Charset (deprecato; Sezione 12.5.2) per indicare o negoziare lo schema di codifica dei caratteri di una rappresentazione testuale. Un charset è identificato da un token insensibile alle maiuscole.

charset = token

I nomi di charset dovrebbero essere registrati nel registro IANA「Character Sets」(http://www.iana.org/assignments/character-sets) secondo le procedure definite nella Sezione 2 di [RFC2978].

Nota: Il parametro「charset」su un tipo di media può avere semantiche diverse a seconda della definizione specifica del tipo di media.

Il parametro「charset」è spesso utilizzato con tipi di media per contenuti testuali. Mentre gli standard che definiscono tali tipi di media dovrebbero prescrivere l'uso di un particolare charset se è probabile che migliori l'interoperabilità, gli utenti e gli implementatori di HTTP sono fortemente incoraggiati a specificare esplicitamente un charset quando influisce sull'interpretazione del contenuto ricevuto, anche quando la definizione del tipo di media prevede un charset in assenza del parametro charset (come spesso accade per i tipi di media「text」).

8.3.3. Tipi Multipart (Multipart Types)

MIME fornisce un certo numero di tipi「multipart」-- incapsulamenti di una o più rappresentazioni all'interno di un singolo contenuto di messaggio. Tutti i tipi multipart condividono una sintassi comune, come definito nella Sezione 5.1 di [RFC2046], e includono un parametro boundary come parte del valore del tipo di media. Il contenuto del messaggio è esso stesso un elemento di protocollo; un mittente DEVE (MUST) generare solo CRLF per rappresentare le interruzioni di riga tra le parti del corpo.

Il framing dei messaggi HTTP non utilizza il boundary multipart come indicatore della lunghezza del corpo del messaggio, sebbene possa essere utilizzato da implementazioni che generano o elaborano il contenuto. Ad esempio, il tipo「multipart/form-data」è spesso utilizzato per trasportare dati di moduli in una richiesta, come descritto in [RFC7578], e il tipo「multipart/byteranges」è definito da questa specifica per l'uso in alcune risposte 206 (Partial Content) (vedere Sezione 15.3.7).

8.4. Content-Encoding

Il campo di intestazione「Content-Encoding」indica quali codifiche di contenuto sono state applicate alla rappresentazione, oltre a quelle inerenti al tipo di media, e quindi quali meccanismi di decodifica devono essere applicati per ottenere dati nel tipo di media riferito dal campo di intestazione Content-Type. Content-Encoding è utilizzato principalmente per consentire la compressione dei dati di una rappresentazione senza perdere l'identità del suo tipo di media sottostante.

Content-Encoding = #content-coding

Un esempio del suo utilizzo è

Content-Encoding: gzip

Se una o più codifiche sono state applicate a una rappresentazione, il mittente che ha applicato le codifiche DEVE (MUST) generare un campo di intestazione Content-Encoding che elenca le codifiche di contenuto nell'ordine in cui sono state applicate. Si noti che la codifica denominata「identity」è riservata per il suo ruolo speciale in Accept-Encoding e quindi NON DOVREBBE (SHOULD NOT) essere inclusa.

Informazioni aggiuntive sui parametri di codifica possono essere fornite da altri campi di intestazione non definiti da questa specifica.

A differenza di Transfer-Encoding (Sezione 6.1 di [HTTP/1.1]), le codifiche elencate in Content-Encoding sono una caratteristica della rappresentazione; la rappresentazione è definita in termini di forma codificata, e tutti gli altri metadati sulla rappresentazione riguardano la forma codificata a meno che non sia altrimenti indicato nella definizione dei metadati. Tipicamente, la rappresentazione viene decodificata solo immediatamente prima del rendering o di un uso analogo.

Se il tipo di media include una codifica inerente, come un formato di dati che è sempre compresso, allora quella codifica non verrebbe ripetuta in Content-Encoding anche se capita di essere lo stesso algoritmo di una delle codifiche di contenuto. Tale codifica di contenuto verrebbe elencata solo se, per qualche ragione bizzarra, viene applicata una seconda volta per formare la rappresentazione. Allo stesso modo, un server di origine può scegliere di pubblicare gli stessi dati come rappresentazioni multiple che differiscono solo nel fatto che la codifica sia definita come parte di Content-Type o Content-Encoding, poiché alcuni agenti utente si comporteranno in modo diverso nella loro gestione di ciascuna risposta (ad esempio, aprendo una finestra di dialogo「Salva con nome...」invece di decompressione automatica e rendering del contenuto).

Un server di origine PUÒ (MAY) rispondere con un codice di stato di 415 (Unsupported Media Type) se una rappresentazione nel messaggio di richiesta ha una codifica di contenuto che non è accettabile.

8.4.1. Codifiche di Contenuto (Content Codings)

I valori di codifica del contenuto indicano una trasformazione di codifica che è stata o può essere applicata a una rappresentazione. Le codifiche di contenuto sono utilizzate principalmente per consentire la compressione di una rappresentazione o la trasformazione altrimenti utile senza perdere l'identità del suo tipo di media sottostante e senza perdita di informazioni. Frequentemente, la rappresentazione viene memorizzata in forma codificata, trasmessa direttamente e decodificata solo dal destinatario finale.

content-coding   = token

Tutte le codifiche di contenuto sono insensibili alle maiuscole e dovrebbero essere registrate nel「Registro di Codifica di Contenuto HTTP」, come definito nella Sezione 16.6.1. Sono utilizzate nei campi di intestazione Accept-Encoding (Sezione 12.5.3) e Content-Encoding (Sezione 8.4).

Le seguenti codifiche di contenuto sono definite da questa specifica:

  • compress (e x-compress): Vedere Sezione 8.4.1.1.
  • deflate: Vedere Sezione 8.4.1.2.
  • gzip (e x-gzip): Vedere Sezione 8.4.1.3.

8.4.1.1. Codifica Compress

La codifica「compress」è una codifica Lempel-Ziv-Welch (LZW) adattiva [Welch] che è comunemente prodotta dal programma di compressione file UNIX「compress」. Un destinatario DOVREBBE (SHOULD) considerare「x-compress」come equivalente a「compress」.

8.4.1.2. Codifica Deflate

La codifica「deflate」è un formato di dati「zlib」[RFC1950] contenente un flusso di dati compresso「deflate」[RFC1951] che utilizza una combinazione dell'algoritmo di compressione Lempel-Ziv (LZ77) e della codifica Huffman.

Nota: Alcune implementazioni non conformi inviano i dati compressi「deflate」senza il wrapper zlib.

8.4.1.3. Codifica Gzip

La codifica「gzip」è una codifica LZ77 con un Controllo di Ridondanza Ciclica (CRC) a 32 bit che è comunemente prodotta dal programma di compressione file gzip [RFC1952]. Un destinatario DOVREBBE (SHOULD) considerare「x-gzip」come equivalente a「gzip」.

8.5. Content-Language

Il campo di intestazione「Content-Language」descrive la o le lingue naturali del pubblico previsto per la rappresentazione. Si noti che questo potrebbe non essere equivalente a tutte le lingue utilizzate all'interno della rappresentazione.

Content-Language = #language-tag

I tag di lingua sono definiti nella Sezione 8.5.1. Lo scopo principale di Content-Language è consentire a un utente di identificare e differenziare le rappresentazioni secondo le proprie lingue preferite dell'utente. Pertanto, se il contenuto è destinato solo a un pubblico che legge il danese, il campo appropriato è

Content-Language: da

Se non è specificato Content-Language, l'impostazione predefinita è che il contenuto sia destinato a tutti i pubblici linguistici. Questo potrebbe significare che il mittente non lo considera specifico per alcuna lingua naturale, o che il mittente non sa per quale lingua è destinato.

Più lingue POSSONO (MAY) essere elencate per contenuti destinati a più pubblici. Ad esempio, una resa del「Trattato di Waitangi」, presentata simultaneamente nelle versioni originali maori e inglesi, richiederebbe

Content-Language: mi, en

Tuttavia, il fatto che più lingue siano presenti all'interno di una rappresentazione non significa che sia destinata a più pubblici linguistici. Un esempio sarebbe un manuale di lingua per principianti, come「A First Lesson in Latin」, che è chiaramente destinato ad essere utilizzato da un pubblico che legge l'inglese. In questo caso, Content-Language dovrebbe includere correttamente solo「en」.

Content-Language PUÒ (MAY) essere applicato a qualsiasi tipo di media -- non è limitato ai documenti testuali.

8.5.1. Tag di Lingua (Language Tags)

Un tag di lingua, come definito in [RFC5646], identifica una lingua naturale parlata, scritta o altrimenti trasmessa dagli esseri umani per la comunicazione di informazioni ad altri esseri umani. I linguaggi informatici sono esplicitamente esclusi.

HTTP utilizza tag di lingua nei campi di intestazione Accept-Language e Content-Language. Accept-Language utilizza la produzione language-range più ampia definita nella Sezione 12.5.4, mentre Content-Language utilizza la produzione language-tag definita di seguito.

language-tag = <Language-Tag, vedere [RFC5646], Sezione 2.1>

Un tag di lingua è una sequenza di uno o più sub-tag insensibili alle maiuscole, ciascuno separato da un carattere trattino ("-", %x2D). Nella maggior parte dei casi, un tag di lingua consiste in un sub-tag di lingua primario che identifica un'ampia famiglia di lingue correlate (ad esempio,「en」= inglese) ed è opzionalmente seguito da una serie di sub-tag che raffinano o restringono l'intervallo di quella lingua (ad esempio,「en-CA」= la varietà di inglese comunicata in Canada). Gli spazi bianchi non sono consentiti all'interno di un tag di lingua. I tag di esempio includono:

fr, en-US, es-419, az-Arab, x-pig-latin, man-Nkoo-GN

Vedere [RFC5646] per ulteriori informazioni.

8.6. Content-Length

Il campo di intestazione「Content-Length」indica la lunghezza dei dati della rappresentazione associata come numero intero decimale non negativo di ottetti. Quando si trasferisce una rappresentazione come contenuto, Content-Length si riferisce specificamente alla quantità di dati inclusi in modo che possa essere utilizzato per delimitare il framing (ad esempio, Sezione 6.2 di [HTTP/1.1]). In altri casi in cui è attesa una rappresentazione completa, Content-Length si riferisce alla lunghezza attualmente selezionata della rappresentazione.

Content-Length = 1*DIGIT

Un esempio è

Content-Length: 3495

Un agente utente DOVREBBE (SHOULD) inviare Content-Length in una richiesta quando il metodo definisce un significato per il contenuto incluso e non sta inviando Transfer-Encoding. Ad esempio, un campo di intestazione Content-Length viene normalmente inviato in una richiesta POST anche quando il valore è 0 (indicando contenuto vuoto).

Un agente utente NON DOVREBBE (SHOULD NOT) inviare un campo di intestazione Content-Length quando il messaggio di richiesta non contiene contenuto e la semantica del metodo non anticipa tali dati.

Un server PUÒ (MAY) inviare un campo di intestazione Content-Length in una risposta a una richiesta HEAD (Sezione 9.3.2); un server NON DEVE (MUST NOT) inviare Content-Length in tale risposta a meno che il suo valore di campo non sia uguale al numero decimale di ottetti che sarebbero stati inviati nel contenuto di una risposta se la stessa richiesta avesse utilizzato il metodo GET.

Un server PUÒ (MAY) inviare un campo di intestazione Content-Length in una risposta 304 (Not Modified) a una richiesta GET condizionale (Sezione 15.4.5); un server NON DEVE (MUST NOT) inviare Content-Length in tale risposta a meno che il suo valore di campo non sia uguale al numero decimale di ottetti che sarebbero stati inviati nel contenuto di una risposta 200 (OK) alla stessa richiesta.

Un server NON DEVE (MUST NOT) inviare un campo di intestazione Content-Length in qualsiasi risposta con un codice di stato di 1xx (Informational) o 204 (No Content). Un server NON DEVE (MUST NOT) inviare un campo di intestazione Content-Length in qualsiasi risposta 2xx (Successful) a una richiesta CONNECT (Sezione 9.3.6).

A parte i casi definiti sopra, in assenza di Transfer-Encoding, un server di origine DOVREBBE (SHOULD) inviare un campo di intestazione Content-Length quando la dimensione del contenuto è nota prima di inviare la sezione di intestazione completa. Questo permetterà ai destinatari a valle di misurare il progresso del trasferimento, conoscere i propri confini di framing e riutilizzare la connessione per richieste successive.

Poiché Content-Length è utilizzato per la delimitazione dei messaggi in HTTP/1.1, il suo valore di campo può influenzare il modo in cui il messaggio viene analizzato dai destinatari anche quando il framing del messaggio non è soggetto alle regole HTTP/1.1. Se il valore non corrisponde alla lunghezza dei dati effettiva della rappresentazione, i risultati possono variare da un cattivo framing del messaggio a potenziale request smuggling o response splitting, a seconda delle circostanze.

Un mittente NON DEVE (MUST NOT) inviare un campo di intestazione Content-Length in qualsiasi messaggio che contiene un campo di intestazione Transfer-Encoding.

Nota: L'uso di Content-Length da parte di HTTP per il framing dei messaggi differisce significativamente dall'uso dello stesso campo in MIME, dove è un campo opzionale utilizzato solo all'interno del tipo di media「message/external-body」.

8.7. Content-Location

Il campo di intestazione「Content-Location」fa riferimento a un URI che può essere utilizzato come identificatore per una risorsa specifica corrispondente alla rappresentazione nel contenuto di questo messaggio. In altre parole, se si dovesse eseguire una richiesta GET su questo URI al momento della generazione di questo messaggio, allora una risposta 200 (OK) conterrebbe la stessa rappresentazione che è inclusa come contenuto in questo messaggio.

Content-Location = absolute-URI / partial-URI

Il valore Content-Location non è una sostituzione dell'URI di destinazione (Sezione 7.1). È un metadato di rappresentazione. Ha la stessa sintassi e semantica del campo di intestazione con lo stesso nome definito per le parti del corpo MIME nella Sezione 4 di [RFC2557]. Tuttavia, la sua apparizione in un messaggio HTTP ha alcune implicazioni speciali per i destinatari HTTP.

Se Content-Location è incluso in un messaggio di risposta 2xx (Successful) e il suo valore fa riferimento a un URI con lo stesso schema, autorità e percorso dell'URI di destinazione, allora il destinatario PUÒ (MAY) considerare il contenuto come una rappresentazione corrente di quella risorsa di destinazione. Per una richiesta GET (Sezione 9.3.1) o HEAD (Sezione 9.3.2), questo è lo stesso delle semantiche predefinite quando nessun Content-Location è fornito dal server. Per una richiesta che cambia stato come PUT (Sezione 9.3.4) o POST (Sezione 9.3.3), implica che il contenuto della risposta del server contiene una rappresentazione corrente di quella risorsa di destinazione, distinguendola così dalle rappresentazioni che potrebbero solo riportare sull'azione (ad esempio,「Ha funzionato!」). Questo consente alle applicazioni di authoring di aggiornare le loro copie locali senza la necessità di una richiesta GET successiva.

Se Content-Location è incluso in un messaggio di risposta 2xx (Successful) e il suo valore di campo fa riferimento a un URI che differisce dall'URI di destinazione, allora il server di origine afferma che l'URI è un identificatore per una risorsa diversa corrispondente alla rappresentazione inclusa. Tale affermazione può essere considerata attendibile solo se entrambi gli identificatori condividono lo stesso proprietario della risorsa, il che non può essere determinato programmaticamente tramite HTTP.

  • Per una risposta a una richiesta GET o HEAD, questo è un'indicazione che l'URI di destinazione si riferisce a una risorsa soggetta a negoziazione di contenuto e il valore del campo Content-Location è un identificatore più specifico per la rappresentazione selezionata.

  • Per una risposta 201 (Created) a una richiesta POST, il valore del campo Content-Location è un riferimento alla risorsa che contiene la rappresentazione corrente corrispondente alla nuova risorsa.

Altrimenti, tale Content-Location indica che questo contenuto è una rappresentazione che riporta lo stato dell'azione richiesta e che lo stesso rapporto è disponibile (per accesso futuro con GET) all'URI dato. Ad esempio, una transazione di acquisto effettuata tramite una richiesta POST potrebbe includere un documento di ricevuta come contenuto della risposta 200 (OK); il valore del campo Content-Location fornisce un identificatore per recuperare una copia di quella stessa ricevuta in futuro.

Un agente utente che invia Content-Location in un messaggio di richiesta sta affermando che il suo valore si riferisce a dove l'agente utente ha originariamente ottenuto il contenuto della rappresentazione inclusa (prima di qualsiasi modifica apportata da quell'agente utente). In altre parole, l'agente utente sta fornendo un collegamento di ritorno alla fonte della rappresentazione originale.

Un server di origine che riceve un campo Content-Location in un messaggio di richiesta DEVE (MUST) trattare le informazioni come contesto di richiesta transitorio piuttosto che come metadati da salvare con la rappresentazione. Un server di origine PUÒ (MAY) utilizzare quel contesto per guidare nell'elaborazione della richiesta o per salvarlo per altri usi, come all'interno di link di origine o metadati di versioning. Tuttavia, un server di origine NON DEVE (MUST NOT) utilizzare tali informazioni di contesto per alterare la semantica della richiesta.

Ad esempio, se un client effettua una richiesta PUT su una risorsa negoziata e il server di origine accetta quel PUT (senza reindirizzamento), allora il nuovo stato di quella risorsa dovrebbe essere coerente con la singola rappresentazione fornita in quel PUT; Content-Location non può essere utilizzato come forma di identificatore di selezione di contenuto inversa per aggiornare solo una delle rappresentazioni negoziate. Se l'agente utente avesse voluto quest'ultima semantica, avrebbe applicato il PUT direttamente all'URI Content-Location.

8.8. Campi di Validazione (Validator Fields)

I metadati di risorsa sono indicati come「validatore」se possono essere utilizzati all'interno di una precondizione (Sezione 13) per effettuare una richiesta condizionale (Sezione 13.1).

I campi di validazione trasmettono un validatore corrente per la rappresentazione selezionata (Sezione 3.2).

Nelle risposte a richieste sicure, i campi di validazione descrivono la rappresentazione selezionata (Sezione 3.2). Si noti che, a seconda della semantica del codice di stato, la rappresentazione selezionata per una data risposta non è necessariamente la stessa della rappresentazione inclusa come contenuto di risposta.

In una risposta riuscita a una richiesta che cambia stato, i campi di validazione descrivono la nuova rappresentazione che ha sostituito la precedente rappresentazione selezionata come risultato dell'elaborazione della richiesta.

Ad esempio, un campo di intestazione ETag in una risposta 201 (Created) comunica un validatore per la risorsa creata dalla richiesta, e un campo di intestazione ETag in una risposta 200 (OK) a PUT comunica un validatore per la nuova rappresentazione che ha sostituito la precedente rappresentazione selezionata come risultato della richiesta PUT.

Questa specifica definisce due forme di metadati comunemente utilizzati per osservare lo stato della risorsa e testare le precondizioni sulle richieste: date di modifica (Sezione 8.8.2) e tag di entità opachi (Sezione 8.8.3). Ulteriori informazioni su varie considerazioni di progettazione possono essere trovate nella Sezione 13.2.

8.8.1. Debole versus Forte (Weak versus Strong)

I validatori esistono in due varianti: forti o deboli. I validatori deboli sono facili da generare ma sono molto meno utili per i confronti. I validatori forti sono ideali per i confronti ma possono essere molto difficili (e occasionalmente impossibili) da generare in modo efficiente. Piuttosto che imporre che tutte le forme di risorsa aderiscano alla stessa forza del validatore, HTTP espone il tipo di validatore in uso e impone restrizioni su quando i validatori deboli possono essere utilizzati come precondizioni.

Un「validatore forte」è un metadato di rappresentazione che cambia valore ogni volta che si verifica un cambiamento nei dati di rappresentazione che sarebbe osservabile nel contenuto di una risposta 200 (OK) a GET.

Un validatore forte potrebbe cambiare per ragioni diverse da un cambiamento nei dati di rappresentazione, come quando viene modificata una parte semanticamente significativa dei metadati di rappresentazione (ad esempio, Content-Type), ma è nell'interesse migliore del server di origine cambiare il valore solo quando è necessario invalidare le risposte memorizzate detenute da cache remote e strumenti di authoring.

Le voci di cache possono persistere per periodi arbitrariamente lunghi, indipendentemente dai tempi di scadenza. Pertanto, una cache potrebbe tentare di validare una voce utilizzando un validatore che ha ottenuto in un passato lontano. Un validatore forte è unico attraverso tutte le versioni di tutte le rappresentazioni associate a una particolare risorsa nel tempo. Tuttavia, non c'è implicazione di unicità attraverso le rappresentazioni di risorse diverse (cioè, lo stesso validatore forte potrebbe essere in uso per le rappresentazioni di più risorse allo stesso tempo e non implica che quelle rappresentazioni siano equivalenti).

Ci sono una varietà di validatori forti utilizzati in pratica. I migliori sono basati su un controllo di revisione rigoroso, in cui ogni cambiamento a una rappresentazione comporta sempre l'assegnazione di un nome di nodo univoco e di un identificatore di revisione prima che la rappresentazione sia resa accessibile a GET. Una funzione hash resistente alle collisioni applicata ai dati di rappresentazione è anch'essa sufficiente se i dati sono disponibili prima dell'invio della sezione di intestazione della risposta e il digest non ha bisogno di essere ricalcolato ogni volta che viene ricevuta una richiesta di validazione. Tuttavia, se una risorsa ha rappresentazioni distinte che differiscono solo nei loro metadati, come potrebbe verificarsi con la negoziazione di contenuto su tipi di media che condividono lo stesso formato di dati, allora il server di origine deve incorporare informazioni aggiuntive nel validatore per distinguere quelle rappresentazioni.

Al contrario, un「validatore debole」è un metadato di rappresentazione che potrebbe non cambiare per ogni cambiamento nei dati di rappresentazione. Questa debolezza potrebbe essere dovuta a limitazioni nel modo in cui viene calcolato il valore (ad esempio, risoluzione dell'orologio), a un'incapacità di garantire l'unicità per tutte le possibili rappresentazioni della risorsa, o a un desiderio di raggruppare le rappresentazioni per un insieme auto-determinato di equivalenze piuttosto che sequenze univoche di dati.

Un server di origine DOVREBBE (SHOULD) cambiare un tag di entità debole ogni volta che considera le rappresentazioni precedenti come non accettabili come sostituto per la rappresentazione corrente. In altre parole, un tag di entità debole dovrebbe cambiare ogni volta che il server di origine vuole che le cache invalidino le vecchie risposte.

Ad esempio, la rappresentazione di un rapporto meteorologico che cambia contenuto ogni secondo, basato su misurazioni dinamiche, potrebbe essere raggruppata in insiemi di rappresentazioni equivalenti (dal punto di vista del server di origine) con lo stesso validatore debole al fine di consentire alle rappresentazioni memorizzate nella cache di essere valide per un periodo di tempo ragionevole (forse regolato dinamicamente in base al carico del server o alla qualità meteorologica). Allo stesso modo, un tempo di modifica di una rappresentazione, se definito con solo una risoluzione di un secondo, potrebbe essere un validatore debole se è possibile che la rappresentazione venga modificata due volte durante un singolo secondo e recuperata tra tali modifiche.

Allo stesso modo, un validatore è debole se è condiviso da due o più rappresentazioni di una data risorsa allo stesso tempo, a meno che quelle rappresentazioni abbiano dati di rappresentazione identici. Ad esempio, se il server di origine invia lo stesso validatore per una rappresentazione con una codifica di contenuto gzip applicata come per una rappresentazione senza codifica di contenuto, allora quel validatore è debole. Tuttavia, due rappresentazioni simultanee possono condividere lo stesso validatore forte se differiscono solo nei metadati di rappresentazione, come quando due diversi tipi di media sono disponibili per gli stessi dati di rappresentazione.

I validatori forti sono utilizzabili per tutte le richieste condizionali, inclusa la validazione della cache, gli intervalli di contenuto parziale e l'evitamento di「aggiornamento perso」. I validatori deboli sono utilizzabili solo quando il client non richiede esatta uguaglianza con i dati di rappresentazione precedentemente ottenuti, come quando si valida una voce di cache o si limita una traversata web a cambiamenti recenti.

8.8.2. Last-Modified

Il campo di intestazione「Last-Modified」in una risposta fornisce un timestamp che indica la data e l'ora in cui il server di origine ritiene che la rappresentazione selezionata sia stata modificata l'ultima volta, come determinato alla conclusione della gestione della richiesta.

Last-Modified = HTTP-date

Un esempio del suo utilizzo è

Last-Modified: Tue, 15 Nov 1994 12:45:26 GMT

8.8.2.1. Generazione (Generation)

Un server di origine DOVREBBE (SHOULD) inviare Last-Modified per qualsiasi rappresentazione selezionata per la quale una data di ultima modifica possa essere ragionevolmente e costantemente determinata, poiché il suo uso nelle richieste condizionali e nella valutazione della freschezza della cache ([CACHING]) può ridurre sostanzialmente i trasferimenti non necessari e migliorare significativamente la disponibilità e la scalabilità del servizio.

Una rappresentazione è tipicamente la somma di molte parti dietro l'interfaccia della risorsa. Il tempo di ultima modifica sarebbe di solito il tempo più recente in cui una qualsiasi di quelle parti è stata modificata. Come quel valore venga determinato per una data risorsa è un dettaglio implementativo oltre lo scopo di questa specifica. Ciò che conta per HTTP è come i destinatari del campo di intestazione Last-Modified possano utilizzare il suo valore per effettuare richieste condizionali e testare la validità delle risposte memorizzate localmente nella cache.

Un server di origine DOVREBBE (SHOULD) ottenere il valore Last-Modified della rappresentazione il più vicino possibile al momento in cui genera il valore del campo Date per la sua risposta. Questo consente a un destinatario di fare una valutazione accurata del tempo di modifica della rappresentazione, specialmente se la rappresentazione cambia vicino al momento in cui viene generata la risposta.

Un server di origine con un orologio (come definito nella Sezione 5.6.7) NON DEVE (MUST NOT) inviare una data Last-Modified che è successiva al tempo di origine del messaggio del server (Date). Se il tempo di ultima modifica è derivato da metadati specifici dell'implementazione che valutano a un tempo futuro, secondo l'orologio del server di origine, allora il server di origine DEVE (MUST) sostituire quel valore con la data di origine del messaggio. Questo impedisce a una data di modifica futura di avere un impatto negativo sulla validazione della cache.

Un server di origine senza orologio NON DEVE (MUST NOT) assegnare valori Last-Modified a una risposta a meno che quei valori non siano associati alla risorsa da qualche altro sistema o utente con un orologio affidabile.

8.8.2.2. Confronto (Comparison)

Un tempo Last-Modified, quando utilizzato come validatore in una richiesta, è implicitamente debole a meno che non sia possibile dedurre che sia forte, utilizzando le seguenti regole:

  • Il validatore viene confrontato da un server di origine con il validatore corrente effettivo per la rappresentazione e,

  • Quel server di origine sa in modo affidabile che la rappresentazione associata non è cambiata due volte durante il secondo coperto dal validatore presentato.

oppure

  • Il validatore sta per essere utilizzato da un client in un campo di intestazione If-Modified-Since, If-Unmodified-Since o If-Range, perché il client ha una voce di cache per la rappresentazione associata, e

  • Quella voce di cache include un valore Date, che fornisce il momento in cui il server di origine ha inviato la risposta originale, e

  • Il tempo Last-Modified presentato è almeno 60 secondi prima del valore Date.

oppure

  • Il validatore viene confrontato da una cache intermedia con il validatore memorizzato nella sua voce di cache per la rappresentazione, e

  • Quella voce di cache include un valore Date, che fornisce il momento in cui il server di origine ha inviato la risposta originale, e

  • Il tempo Last-Modified presentato è almeno 60 secondi prima del valore Date.

Questo metodo si basa sul fatto che se due risposte diverse sono state inviate dal server di origine durante lo stesso secondo, ma entrambe avevano lo stesso tempo Last-Modified, allora almeno una di quelle risposte avrebbe un valore Date uguale al suo tempo Last-Modified. Il limite arbitrario di 60 secondi protegge contro la possibilità che i valori Date e Last-Modified siano generati da orologi diversi o in momenti leggermente diversi durante la preparazione della risposta. Un'implementazione PUÒ (MAY) utilizzare un valore superiore a 60 secondi, se si ritiene che 60 secondi siano troppo brevi.

8.8.3. ETag

Il campo di intestazione「ETag」in una risposta fornisce il tag di entità corrente per la rappresentazione selezionata, come determinato alla conclusione della gestione della richiesta. Un tag di entità è un validatore opaco per differenziare tra più rappresentazioni della stessa risorsa, indipendentemente dal fatto che quelle rappresentazioni multiple siano dovute a cambiamenti di stato della risorsa nel tempo, negoziazione di contenuto che risulta in più rappresentazioni valide allo stesso tempo, o entrambi. Un tag di entità consiste in una stringa opaca tra virgolette, possibilmente preceduta da un indicatore di debolezza.

ETag       = entity-tag

entity-tag = [ weak ] opaque-tag
weak = %s"W/"
opaque-tag = DQUOTE *etagc DQUOTE
etagc = %x21 / %x23-7E / obs-text
; VCHAR eccetto virgolette doppie, più obs-text

Nota: In precedenza, opaque-tag era definito come una quoted-string ([RFC2616], Sezione 3.11); quindi, alcuni destinatari potrebbero eseguire l'unescaping della barra rovesciata. I server dovrebbero quindi evitare caratteri di barra rovesciata nei tag di entità.

Un tag di entità può essere più affidabile di una data di modifica per diversi motivi: potrebbe non esserci un orologio disponibile per il server; il tempo di modifica di una risorsa potrebbe essere impostato nel futuro per scopi di controllo degli accessi; la risoluzione di un tempo di modifica è limitata dal modo in cui viene memorizzato; i sistemi distribuiti potrebbero avere difficoltà a sincronizzare gli orologi; un tag di entità può incorporare metadati aggiuntivi, come il valore di un campo di intestazione Content-Encoding, per distinguere meglio le rappresentazioni; e così via.

Due tag di entità sono equivalenti se i loro opaque-tag corrispondono carattere per carattere, indipendentemente dal fatto che uno o entrambi siano contrassegnati come deboli.

Un tag di entità può essere o un validatore forte o un validatore debole, con forte come predefinito. Se un server di origine fornisce un tag di entità per una rappresentazione e la generazione di quel tag di entità non soddisfa tutte le caratteristiche di un validatore forte (Sezione 8.8.1), allora il server di origine DEVE (MUST) contrassegnare il tag di entità come debole prefissando il suo valore opaco con「W/」(sensibile alle maiuscole).

ETag: W/"xyzzy"
ETag: ""

8.8.3.1. Generazione (Generation)

Il principio dietro i tag di entità è che solo l'autore del servizio conosce abbastanza bene l'implementazione di una risorsa per selezionare il meccanismo di validazione più accurato ed efficiente per quella risorsa, e che qualsiasi tale meccanismo può essere mappato a una semplice sequenza di ottetti per un confronto facile. Poiché il valore è opaco, non c'è bisogno che il client sia consapevole di come viene costruito ogni tag di entità.

Ad esempio, una risorsa che ha un versioning specifico dell'implementazione applicato a tutte le modifiche potrebbe utilizzare un numero di revisione interno, forse combinato con un identificatore di varianza per la negoziazione di contenuto, per differenziare accuratamente tra le rappresentazioni. Altre implementazioni potrebbero utilizzare un hash resistente alle collisioni del contenuto della rappresentazione, una combinazione di vari attributi di file o un timestamp di modifica che ha una risoluzione sub-secondo.

Un server di origine DOVREBBE (SHOULD) inviare un ETag per qualsiasi rappresentazione selezionata per la quale il rilevamento delle modifiche possa essere ragionevolmente e costantemente determinato, poiché l'uso del tag di entità nelle richieste condizionali e nella valutazione della freschezza della cache ([CACHING]) può risultare in una sostanziale riduzione del traffico di rete HTTP e può essere un contributo significativo alla scalabilità e affidabilità del servizio.

8.8.3.2. Confronto (Comparison)

Ci sono due funzioni di confronto dei tag di entità, a seconda che il contesto di confronto consenta l'uso di validatori deboli o meno:

  • Confronto forte: due tag di entità sono equivalenti se entrambi non sono deboli e i loro opaque-tag corrispondono carattere per carattere.

  • Confronto debole: due tag di entità sono equivalenti se i loro opaque-tag corrispondono carattere per carattere, indipendentemente dal fatto che uno o entrambi siano contrassegnati come deboli.

L'esempio seguente mostra i risultati per un insieme di coppie di tag di entità e i risultati sia della funzione di confronto debole che forte:

ETag 1ETag 2Confronto forteConfronto debole
W/"1"W/"1"nessuna corrispondenzacorrispondenza
W/"1"W/"2"nessuna corrispondenzanessuna corrispondenza
W/"1""1"nessuna corrispondenzacorrispondenza
"1""1"corrispondenzacorrispondenza

8.8.3.3. Esempio: Tag di Entità che Variano su Risorse Negoziate per Contenuto

Consideriamo una risorsa che è soggetta a negoziazione di contenuto (Sezione 12.1), e dove le rappresentazioni inviate in risposta a una richiesta GET variano in base al campo di intestazione di richiesta Accept-Encoding (Sezione 12.5.3):

>> Richiesta:

GET /index HTTP/1.1
Host: www.example.com
Accept-Encoding: gzip

>> Risposta:

HTTP/1.1 200 OK
Date: Fri, 26 Mar 2010 00:05:00 GMT
ETag: "123-a"
Content-Length: 70
Vary: Accept-Encoding
Content-Type: text/plain
Content-Encoding: gzip

[...]

Per un insieme diverso di campi di intestazione di richiesta, una rappresentazione diversa potrebbe essere inviata dal server:

>> Richiesta:

GET /index HTTP/1.1
Host: www.example.com

>> Risposta:

HTTP/1.1 200 OK
Date: Fri, 26 Mar 2010 00:05:00 GMT
ETag: "123-b"
Content-Length: 400
Vary: Accept-Encoding
Content-Type: text/plain

[...]

La differenza nei tag di entità in queste due risposte indica che le rappresentazioni inviate contengono dati diversi. I tag di entità forti utilizzati in questo caso permettono l'uso di richieste condizionali sia per la validazione della cache che per le richieste di intervallo.

Al contrario, un server di origine che genera una rappresentazione codificata gzip al volo, senza controllare alcuna versione precedente della rappresentazione che potrebbe essere già stata generata, potrebbe utilizzare tag di entità deboli per indicare contenuto equivalente:

>> Risposta:

HTTP/1.1 200 OK
Date: Fri, 26 Mar 2010 00:05:00 GMT
ETag: W/"123"
Content-Length: 70
Vary: Accept-Encoding
Content-Type: text/plain
Content-Encoding: gzip

[...]

In questo caso, il server assume che la versione compressa della rappresentazione sia equivalente alla versione non compressa, pur non tracciando abbastanza bene le versioni per determinare il validatore forte.