7. Campi di intestazione di risposta (Response Header Fields)
I campi di intestazione di risposta consentono al server di trasmettere informazioni aggiuntive sulla risposta oltre a quelle collocate nella riga di stato. Questi campi di intestazione forniscono informazioni sul server, sull'accesso ulteriore alla risorsa di destinazione o su risorse correlate.
Sebbene ogni campo di intestazione di risposta abbia un significato definito, in generale, la semantica precisa può essere ulteriormente perfezionata dalla semantica del metodo di richiesta e/o del codice di stato di risposta.
7.1. Dati di controllo (Control Data)
I campi di intestazione di risposta possono fornire dati di controllo che integrano il codice di stato, dirigono la memorizzazione nella cache o indicano al client dove andare successivamente.
7.1.1. Data di origine (Origination Date)
7.1.1.1. Date
Il campo di intestazione "Date" rappresenta la data e l'ora in cui il messaggio è stato originato, avendo la stessa semantica del campo Data di Origine (orig-date) definito nella Sezione 3.6.1 di [RFC5322]. Il valore del campo è un HTTP-date, come definito nella Sezione 7.1.1.1 di [RFC7231].
Date = HTTP-date
Un esempio:
Date: Tue, 15 Nov 1994 08:12:31 GMT
Quando viene generato un campo di intestazione Date, il mittente DOVREBBE (SHOULD) generare il suo valore di campo come la migliore approssimazione disponibile della data e dell'ora di generazione del messaggio. In teoria, la data dovrebbe rappresentare il momento appena prima che il payload venga generato. In pratica, la data può essere generata in qualsiasi momento durante l'origine del messaggio.
Un server di origine NON DEVE (MUST NOT) inviare un campo di intestazione Date se non ha un orologio in grado di fornire un'approssimazione ragionevole dell'istante corrente in tempo coordinato universale (UTC). Un server di origine PUÒ (MAY) inviare un campo di intestazione Date se la risposta è nella classe 1xx (Informational) o 5xx (Server Error) di codici di stato. Un server di origine DEVE (MUST) inviare un campo di intestazione Date in tutti gli altri casi.
Un destinatario con un orologio che riceve un messaggio di risposta senza un campo di intestazione Date DEVE (MUST) registrare l'ora in cui è stato ricevuto e aggiungere un campo di intestazione Date corrispondente alla sezione di intestazione del messaggio se viene memorizzato nella cache o inoltrato a valle.
Un agente utente PUÒ (MAY) inviare un campo di intestazione Date in una richiesta, sebbene generalmente non lo farà a meno che non si ritenga che trasmetta informazioni utili al server. Ad esempio, le applicazioni personalizzate di HTTP potrebbero trasmettere una Data se si prevede che il server regoli la sua interpretazione della richiesta dell'utente in base alle differenze tra gli orologi dell'agente utente e del server.
7.1.1.2. HTTP-date
Le applicazioni HTTP hanno storicamente consentito tre formati diversi per la rappresentazione di timestamp di data/ora:
Sun, 06 Nov 1994 08:49:37 GMT ; IMF-fixdate
Sunday, 06-Nov-94 08:49:37 GMT ; formato RFC 850 obsoleto
Sun Nov 6 08:49:37 1994 ; formato asctime() di ANSI C
Il primo formato è preferito come standard Internet e rappresenta un sottoinsieme di lunghezza fissa di quello definito da [RFC5322] (Sezione 3.3). Il secondo formato è in uso comune, ma si basa sul formato data obsoleto RFC 850 [RFC0850] e manca di un anno a quattro cifre. I client e i server HTTP/1.1 che analizzano il valore della data DEVONO (MUST) accettare tutti e tre i formati (per compatibilità con HTTP/1.0), sebbene DEVONO (MUST) generare solo il formato IMF-fixdate per rappresentare i valori HTTP-date nei campi di intestazione.
Nota: I destinatari di un valore di timestamp in formato rfc850-date, che utilizza un anno a due cifre, DEVONO (MUST) interpretare un timestamp che sembra essere più di 50 anni nel futuro come rappresentante dell'anno più recente nel passato che aveva le stesse ultime due cifre.
Un valore HTTP-date rappresenta il tempo come un'istanza del tempo coordinato universale (UTC). I primi due formati indicano UTC con l'abbreviazione di tre lettere per Greenwich Mean Time, "GMT", un predecessore del nome UTC; i valori nel formato asctime sono assunti essere in UTC. Un mittente che genera valori HTTP-date da un orologio locale dovrebbe (ought to) utilizzare NTP ([RFC5905]) o un protocollo simile per sincronizzare il suo orologio con UTC.
Formato preferito:
HTTP-date = IMF-fixdate / obs-date
IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT
; sottoinsieme di lunghezza/zona/maiuscole fisse del formato
; vedere Sezione 3.3 di [RFC5322]
day-name = %x4D.6F.6E ; "Mon", case-sensitive
/ %x54.75.65 ; "Tue", case-sensitive
/ %x57.65.64 ; "Wed", case-sensitive
/ %x54.68.75 ; "Thu", case-sensitive
/ %x46.72.69 ; "Fri", case-sensitive
/ %x53.61.74 ; "Sat", case-sensitive
/ %x53.75.6E ; "Sun", case-sensitive
date1 = day SP month SP year
; ad esempio, 02 Jun 1982
day = 2DIGIT
month = %x4A.61.6E ; "Jan", case-sensitive
/ %x46.65.62 ; "Feb", case-sensitive
/ %x4D.61.72 ; "Mar", case-sensitive
/ %x41.70.72 ; "Apr", case-sensitive
/ %x4D.61.79 ; "May", case-sensitive
/ %x4A.75.6E ; "Jun", case-sensitive
/ %x4A.75.6C ; "Jul", case-sensitive
/ %x41.75.67 ; "Aug", case-sensitive
/ %x53.65.70 ; "Sep", case-sensitive
/ %x4F.63.74 ; "Oct", case-sensitive
/ %x4E.6F.76 ; "Nov", case-sensitive
/ %x44.65.63 ; "Dec", case-sensitive
year = 4DIGIT
GMT = %x47.4D.54 ; "GMT", case-sensitive
time-of-day = hour ":" minute ":" second
; 00:00:00 - 23:59:60 (secondo intercalare)
hour = 2DIGIT
minute = 2DIGIT
second = 2DIGIT
Formati obsoleti:
obs-date = rfc850-date / asctime-date
rfc850-date = day-name-l "," SP date2 SP time-of-day SP GMT
date2 = day "-" month "-" 2DIGIT
; ad esempio, 02-Jun-82
day-name-l = %x4D.6F.6E.64.61.79 ; "Monday", case-sensitive
/ %x54.75.65.73.64.61.79 ; "Tuesday", case-sensitive
/ %x57.65.64.6E.65.73.64.61.79 ; "Wednesday", case-sensitive
/ %x54.68.75.72.73.64.61.79 ; "Thursday", case-sensitive
/ %x46.72.69.64.61.79 ; "Friday", case-sensitive
/ %x53.61.74.75.72.64.61.79 ; "Saturday", case-sensitive
/ %x53.75.6E.64.61.79 ; "Sunday", case-sensitive
asctime-date = day-name SP date3 SP time-of-day SP year
date3 = month SP ( 2DIGIT / ( SP 1DIGIT ))
; ad esempio, Jun 2
HTTP-date è case-sensitive. Un mittente NON DEVE (MUST NOT) generare spazi bianchi aggiuntivi in un HTTP-date oltre a quelli specificamente inclusi come SP nella grammatica. La semantica di day-name, day, month, year e time-of-day è la stessa di quella definita per i costrutti Internet Message Format con il nome corrispondente ([RFC5322], Sezione 3.3).
7.1.2. Location
Il campo di intestazione "Location" è utilizzato in alcune risposte per fare riferimento a una risorsa specifica in relazione alla risposta. Il tipo di relazione è definito dalla combinazione del metodo di richiesta e della semantica del codice di stato.
Location = URI-reference
Il valore del campo consiste in una singola URI-reference. Quando ha la forma di un riferimento relativo ([RFC3986], Sezione 4.2), il valore finale viene calcolato risolvendolo rispetto all'URI di richiesta effettivo ([RFC7230], Sezione 5.5).
Per le risposte 201 (Created), il valore Location è un riferimento URI a una risorsa che identifica la risorsa principale creata dalla richiesta. Per le risposte 3xx (Redirection), il valore Location si riferisce alla risorsa di destinazione preferita per il reindirizzamento automatico della richiesta.
Se il valore Location fornito in una risposta 3xx (Redirection) non ha un componente frammento, un agente utente DEVE (MUST) elaborare il reindirizzamento come se il valore ereditasse il componente frammento del riferimento URI utilizzato per generare l'obiettivo della richiesta (cioè, il reindirizzamento eredita il frammento del riferimento originale, se presente).
Ad esempio, una richiesta GET generata per il riferimento URI "http://www.example.org/~tim" potrebbe risultare in diversi reindirizzamenti prima di arrivare finalmente a "http://www.example.com/~tim/". Se il primo reindirizzamento è a "http://www.example.org/people/~tim", allora quel reindirizzamento sarà a "http://www.example.org/people/~tim" e non a "http://www.example.org/people/~tim#fred".
Ci sono circostanze in cui un identificatore di frammento in un valore Location non sarebbe appropriato. Ad esempio, il campo di intestazione Location in una risposta 201 (Created) dovrebbe fornire un URI specifico per la risorsa creata.
Nota: Alcuni destinatari tentano di recuperare da campi Location che non sono riferimenti URI validi. Questa specifica non impone o definisce tale elaborazione, ma lo consente per motivi di robustezza. Un valore del campo Location che è un percorso assoluto è accettabile, ma sarà interpretato relativamente all'URI di richiesta effettivo.
Nota: La negoziazione del contenuto della risposta può causare che il valore Location sia diverso dall'URI di richiesta effettivo. Se la risposta è memorizzabile nella cache, una cache può utilizzare quel valore Location per determinare una chiave più appropriata per la risposta (vedere Sezione 4.1 di [RFC7234]).
7.1.3. Retry-After
I server inviano il campo di intestazione "Retry-After" per indicare quanto tempo l'agente utente dovrebbe attendere prima di effettuare una richiesta di follow-up. Quando inviato con una risposta 503 (Service Unavailable), Retry-After indica quanto tempo si prevede che il servizio non sia disponibile per il client. Quando inviato con una risposta 429 (Too Many Requests), Retry-After indica quanto tempo l'agente utente dovrebbe attendere prima di effettuare una richiesta di follow-up. Quando inviato con qualsiasi risposta 3xx (Redirection), Retry-After indica il tempo minimo che l'agente utente è invitato ad attendere prima di emettere la richiesta reindirizzata.
Il valore di questo campo può essere un HTTP-date o un numero di secondi da ritardare dopo aver ricevuto la risposta.
Retry-After = HTTP-date / delay-seconds
Un valore delay-seconds è un intero decimale non negativo, che rappresenta il tempo in secondi.
delay-seconds = 1*DIGIT
Due esempi del suo utilizzo:
Retry-After: Fri, 31 Dec 1999 23:59:59 GMT
Retry-After: 120
In quest'ultimo esempio, il ritardo è di 2 minuti.
7.1.4. Vary
Il campo di intestazione "Vary" in una risposta descrive quali parti di un messaggio di richiesta, oltre al metodo e all'obiettivo della richiesta, potrebbero influenzare il processo del server di origine per selezionare e rappresentare questa risposta. Il valore consiste in un singolo asterisco ("*") o in un elenco di nomi di campi di intestazione (non case-sensitive).
Vary = "*" / 1#field-name
Un valore del campo Vary di "" segnala che qualsiasi cosa sulla richiesta potrebbe svolgere un ruolo nella selezione della rappresentazione della risposta, possibilmente inclusi elementi al di fuori della sintassi del messaggio (ad esempio, l'indirizzo di rete del client). Un destinatario non sarà in grado di determinare se questa risposta è appropriata per una richiesta successiva senza inoltrare la richiesta al server di origine. Un proxy NON DEVE (MUST NOT) generare un campo Vary con un valore "".
Un valore del campo Vary costituito da un elenco di nomi separati da virgole indica che i campi di intestazione di richiesta denominati, noti come campi di intestazione di richiesta selettivi, potrebbero avere un ruolo nella selezione della rappresentazione. I potenziali campi di intestazione di richiesta selettivi non sono limitati a quelli definiti da questa specifica.
Ad esempio, una risposta che contiene:
Vary: accept-encoding, accept-language
indica che il server di origine potrebbe aver utilizzato i campi Accept-Encoding e Accept-Language della richiesta (o la loro assenza) come fattori determinanti nella scelta del contenuto per questa risposta.
Un server di origine potrebbe inviare Vary con un elenco di campi per due scopi:
-
Informare i destinatari della cache che NON DEVONO (MUST NOT) utilizzare questa risposta per soddisfare una richiesta successiva a meno che la richiesta successiva non abbia gli stessi valori per i campi elencati della richiesta originale (Sezione 4.1 di [RFC7234]). In altre parole, Vary espande la chiave della cache richiesta per abbinare una nuova richiesta alla voce della cache memorizzata.
-
Informare i destinatari dell'agente utente che questa risposta è soggetta a negoziazione del contenuto (Sezione 3.4) e che una rappresentazione diversa potrebbe essere inviata in una richiesta successiva se vengono forniti parametri aggiuntivi nei campi di intestazione elencati (negoziazione proattiva).
Un server di origine DOVREBBE (SHOULD) inviare un campo di intestazione Vary quando il suo algoritmo per selezionare una rappresentazione varia in base ad aspetti del messaggio di richiesta diversi dal metodo e dall'obiettivo della richiesta, a meno che la varianza non possa essere incrociata o il server di origine sia stato deliberatamente configurato per impedire la trasparenza della cache. Ad esempio, non è necessario inviare il nome del campo Authorization in Vary perché il riutilizzo tra utenti è vincolato dalla definizione del campo (Sezione 4.2 di [RFC7235]). Allo stesso modo, un server di origine potrebbe utilizzare un campo di intestazione di richiesta per selezionare una rappresentazione che è interamente sotto il suo controllo (ad esempio, tramite un campo di intestazione privato o metadati di richiesta interni) e, in tal caso, non avrebbe bisogno di pubblicizzarlo in Vary.
7.2. Campi di intestazione del validatore (Validator Header Fields)
I campi di intestazione del validatore trasmettono metadati sulla rappresentazione selezionata (Sezione 3). Nelle risposte ai metodi sicuri, i campi del validatore descrivono la rappresentazione selezionata. Nelle risposte ai metodi di cambio di stato, i campi del validatore descrivono la nuova rappresentazione che ha sostituito la precedente rappresentazione selezionata come risultato dell'elaborazione riuscita della richiesta.
7.2.1. ETag
Il campo di intestazione "ETag" in una risposta fornisce l'entity-tag corrente per la rappresentazione selezionata, come determinato alla conclusione della gestione della richiesta. Un entity-tag è un validatore opaco per differenziare tra più rappresentazioni della stessa risorsa, indipendentemente dal fatto che tali rappresentazioni multiple siano dovute a cambiamenti di stato della risorsa nel tempo, alla negoziazione del contenuto che risulta in rappresentazioni multiple valide allo stesso tempo, o entrambi.
ETag = entity-tag
La grammatica entity-tag è definita nella Sezione 2.3 di [RFC7232]:
entity-tag = [ weak ] opaque-tag
weak = %x57.2F ; "W/", case-sensitive
opaque-tag = DQUOTE *etagc DQUOTE
etagc = %x21 / %x23-7E / obs-text
; VCHAR tranne virgolette doppie, più obs-text
Nota: In precedenza, opaque-tag era definito come una quoted-string ([RFC2616], Sezione 3.11); pertanto, alcuni destinatari potrebbero eseguire l'unescaping del backslash. I server dovrebbero quindi (ought to) evitare i caratteri backslash negli entity-tag.
Un entity-tag può essere un validatore debole o forte, con forte come predefinito. Se un server di origine fornisce un entity-tag per una rappresentazione e la generazione di quell'entity-tag non soddisfa tutte le caratteristiche di un validatore forte (Sezione 2.1 di [RFC7232]), allora il server di origine DEVE (MUST) contrassegnare l'entity-tag come debole prefissando il suo valore opaco con "W/" (case-sensitive).
Un mittente PUÒ (MAY) inviare il campo ETag in una sezione trailer (Sezione 4.1.2 di [RFC7230]), ma questo è utile solo per le risposte che non hanno una codifica del contenuto e in cui l'agente utente può calcolare l'entity-tag prima di ricevere la sezione trailer. Quando ETag viene inviato nella sezione trailer, sostituisce qualsiasi valore del campo ETag inviato nella sezione di intestazione.
Esempi:
ETag: "xyzzy"
ETag: W/"xyzzy"
ETag: ""
Un server di origine DOVREBBE (SHOULD) inviare un ETag per qualsiasi rappresentazione selezionata per la quale il rilevamento delle modifiche può essere ragionevolmente e coerentemente determinato, poiché l'uso dell'entity-tag nelle richieste condizionali e nella valutazione della freschezza della cache ([RFC7234]) può ridurre sostanzialmente i trasferimenti non necessari e migliorare significativamente la disponibilità e la scalabilità del servizio.
7.2.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 per 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
Un server di origine DOVREBBE (SHOULD) inviare Last-Modified per qualsiasi rappresentazione selezionata per la quale una data di ultima modifica può essere ragionevolmente e coerentemente determinata, poiché il suo utilizzo nelle richieste condizionali e nella valutazione della freschezza della cache ([RFC7234]) 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 dell'ultima modifica sarebbe solitamente il tempo più recente in cui una di quelle parti è stata modificata.
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 risposta. Ciò consente a un destinatario di effettuare 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 7.1.1.1) NON DEVE (MUST NOT) inviare una data Last-Modified successiva al tempo di origine del messaggio del server (Date). Se il tempo dell'ultima modifica è derivato da metadati specifici dell'implementazione che valutano a un momento 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. Ciò impedisce che una data di modifica futura abbia un impatto negativo sulla convalida della cache.
Un server di origine senza orologio NON DEVE (MUST NOT) assegnare valori Last-Modified a una risposta a meno che questi valori non siano stati associati alla risorsa da qualche altro sistema con un orologio o a meno che i valori non siano stati precedentemente ricevuti dal server di origine (ad esempio, da un database backend).
7.3. Sfide di autenticazione (Authentication Challenges)
Le sfide di autenticazione indicano quali meccanismi sono disponibili per il client per fornire credenziali di autenticazione nelle richieste future.
7.3.1. WWW-Authenticate
Il campo di intestazione "WWW-Authenticate" indica lo/gli schema/i di autenticazione e i parametri applicabili alla risorsa di destinazione.
WWW-Authenticate = 1#challenge
Un server che genera una risposta 401 (Unauthorized) DEVE (MUST) inviare un campo di intestazione WWW-Authenticate contenente almeno una sfida. Un server PUÒ (MAY) generare un campo di intestazione WWW-Authenticate in altri messaggi di risposta per indicare che la fornitura di credenziali (o credenziali diverse) potrebbe influenzare la risposta.
Un proxy che inoltra una risposta NON DEVE (MUST NOT) modificare alcun campo WWW-Authenticate in quella risposta.
Si consiglia agli agenti utente di prestare particolare attenzione nell'analisi del valore del campo, poiché potrebbe contenere più di una sfida e ogni sfida può contenere un elenco di parametri di autenticazione separati da virgole. Inoltre, il campo di intestazione stesso può apparire più volte.
Per ulteriori dettagli, vedere la Sezione 4.1 di [RFC7235].
7.3.2. Proxy-Authenticate
Il campo di intestazione "Proxy-Authenticate" consiste in almeno una sfida che indica lo/gli schema/i di autenticazione e i parametri applicabili al proxy per questo obiettivo di richiesta. Un proxy DEVE (MUST) inviare almeno un campo di intestazione Proxy-Authenticate in ogni risposta 407 (Proxy Authentication Required) che genera.
Proxy-Authenticate = 1#challenge
A differenza di WWW-Authenticate, il campo di intestazione Proxy-Authenticate si applica solo al client in uscita successivo nella catena di risposta. Questo perché solo il client che ha scelto un dato proxy è probabile che abbia le credenziali necessarie per l'autenticazione. Tuttavia, quando più proxy vengono utilizzati all'interno dello stesso dominio amministrativo, come i proxy di caching d'ufficio e regionali all'interno di una grande rete aziendale, è comune che le credenziali vengano generate dall'agente utente e passate attraverso la gerarchia fino a quando non vengono consumate. Quindi, in tale configurazione, apparirà come se Proxy-Authenticate venisse inoltrato perché ogni proxy invierà lo stesso set di sfide.
Per ulteriori dettagli, vedere la Sezione 4.3 di [RFC7235].
7.4. Contesto di risposta (Response Context)
I seguenti campi di intestazione di risposta forniscono informazioni aggiuntive sulla risposta, oltre a quanto implicato dal codice di stato, o sul server che gestisce la risposta.
7.4.1. Allow
Il campo di intestazione "Allow" elenca l'insieme di metodi pubblicizzati come supportati dalla risorsa di destinazione. Lo scopo di questo campo è strettamente quello di informare il destinatario dei metodi di richiesta validi associati alla risorsa.
Allow = #method
Esempio di utilizzo:
Allow: GET, HEAD, PUT
L'insieme effettivo di metodi consentiti è definito dal server di origine al momento di ogni richiesta. Un server di origine DEVE (MUST) generare un campo Allow in una risposta 405 (Method Not Allowed) e PUÒ (MAY) farlo in qualsiasi altra risposta. Un valore del campo Allow vuoto indica che la risorsa non consente alcun metodo, il che potrebbe verificarsi in una risposta 405 se la risorsa è stata temporaneamente disabilitata dalla configurazione.
Un proxy NON DEVE (MUST NOT) modificare il campo di intestazione Allow -- non ha bisogno di comprendere tutti i metodi indicati per gestirli secondo le regole generali di gestione dei messaggi.
7.4.2. Server
Il campo di intestazione "Server" contiene informazioni sul software utilizzato dal server di origine per gestire la richiesta, che è spesso utilizzato dai client per aiutare a identificare l'ambito dei problemi di interoperabilità segnalati, per aggirare o personalizzare le richieste per evitare particolari limitazioni del server e per l'analisi relativa all'uso del server o del sistema operativo. Un server di origine PUÒ (MAY) generare un campo Server in qualsiasi risposta.
Server = product *( RWS ( product / comment ) )
Il valore del campo Server consiste in uno o più identificatori di prodotto, ciascuno seguito da zero o più commenti (Sezione 3.2 di [RFC7230]), che insieme identificano il software del server di origine e i suoi sottoprodotti significativi. Per convenzione, gli identificatori di prodotto sono elencati in ordine decrescente della loro importanza per l'identificazione del software del server di origine. Ogni identificatore di prodotto consiste in un nome e una versione opzionale, come definito nella Sezione 5.5.3 di [RFC7230].
Esempio:
Server: CERN/3.0 libwww/2.17
Un server di origine NON DOVREBBE (SHOULD NOT) generare un campo Server contenente dettagli inutilmente granulari e DOVREBBE (SHOULD) limitare l'aggiunta di sottoprodotti da parte di terzi. I valori del campo Server eccessivamente lunghi e dettagliati aumentano la latenza della risposta e rivelano potenzialmente dettagli di implementazione interni che potrebbero rendere (leggermente) più facile per gli aggressori trovare e sfruttare falle di sicurezza note.