5. Campi
HTTP utilizza "campi" (Fields) per fornire dati sotto forma di coppie nome/valore estensibili con uno spazio dei nomi di chiavi registrate. I campi vengono inviati e ricevuti all'interno delle sezioni di intestazione e trailer dei messaggi (Sezione 6).
5.1. Nomi di Campi
Un nome di campo (Field Name) etichetta il valore di campo corrispondente come avente la semantica definita da quel nome. Ad esempio, il campo di intestazione Date è definito nella Sezione 6.6.1 come contenente il timestamp di origine per il messaggio in cui appare.
field-name = token
I nomi di campo non sono sensibili alle maiuscole e dovrebbero essere registrati nel "Registro dei Nomi di Campo del Protocollo di Trasferimento Ipertestuale (HTTP)"; vedere Sezione 16.3.1.
L'interpretazione di un campo non cambia tra versioni minori della stessa versione maggiore di HTTP, sebbene il comportamento predefinito di un destinatario in assenza di tale campo possa cambiare. Salvo diversa indicazione, i campi sono definiti per tutte le versioni di HTTP. In particolare, i campi Host e Connection dovrebbero essere riconosciuti da tutte le implementazioni HTTP indipendentemente dal fatto che dichiarino o meno la conformità con HTTP/1.1.
Nuovi campi possono essere introdotti senza modificare la versione del protocollo se la loro semantica definita consente loro di essere ignorati in sicurezza dai destinatari che non li riconoscono; vedere Sezione 16.3.
Un proxy DEVE (MUST) inoltrare i campi di intestazione non riconosciuti a meno che il nome del campo non sia elencato nel campo di intestazione Connection (Sezione 7.6.1) o il proxy sia specificamente configurato per bloccare o altrimenti trasformare tali campi. Gli altri destinatari DOVREBBERO (SHOULD) ignorare i campi di intestazione e trailer non riconosciuti. L'aderenza a questi requisiti consente di estendere la funzionalità di HTTP senza aggiornare o rimuovere gli intermediari distribuiti.
5.2. Righe di Campo e Valore di Campo Combinato
Le sezioni di campi (Field Sections) sono composte da un numero qualsiasi di "righe di campo" (Field Lines), ciascuna con un "nome di campo" (vedere Sezione 5.1) che identifica il campo, e un "valore di riga di campo" (Field Line Value) che trasmette i dati per quell'istanza del campo.
Quando un nome di campo è presente solo una volta in una sezione, il "valore di campo" (Field Value) combinato per quel campo consiste nel valore di riga di campo corrispondente. Quando un nome di campo viene ripetuto all'interno di una sezione, il suo valore di campo combinato consiste nell'elenco dei valori di riga di campo corrispondenti all'interno di quella sezione, concatenati in ordine, con ciascun valore di riga di campo separato da una virgola.
Ad esempio, questa sezione:
Example-Field: Foo, Bar
Example-Field: Baz
contiene due righe di campo, entrambe con il nome di campo "Example-Field". La prima riga di campo ha un valore di riga di campo di "Foo, Bar", mentre il secondo valore di riga di campo è "Baz". Il valore di campo per "Example-Field" è l'elenco "Foo, Bar, Baz".
5.3. Ordine dei Campi
Un destinatario PUÒ (MAY) combinare più righe di campo all'interno di una sezione di campi che hanno lo stesso nome di campo in una riga di campo, senza modificare la semantica del messaggio, aggiungendo ciascun valore di riga di campo successivo al valore di riga di campo iniziale in ordine, separato da una virgola (",") e spazio bianco opzionale (OWS, definito nella Sezione 5.6.3). Per coerenza, utilizzare virgola SP.
L'ordine in cui vengono ricevute le righe di campo con lo stesso nome è quindi significativo per l'interpretazione del valore del campo; un proxy NON DEVE (MUST NOT) modificare l'ordine di questi valori di riga di campo quando inoltra un messaggio.
Ciò significa che, a parte l'eccezione nota di seguito, un mittente NON DEVE (MUST NOT) generare più righe di campo con lo stesso nome in un messaggio (sia nelle intestazioni che nei trailer) o aggiungere una riga di campo quando esiste già una riga di campo con lo stesso nome nel messaggio, a meno che la definizione di quel campo non consenta che più valori di riga di campo siano ricombinati come elenco separato da virgole (cioè, almeno un'alternativa della definizione del campo consente un elenco separato da virgole, come una regola ABNF di #(values) definita nella Sezione 5.6.1).
Nota: In pratica, il campo di intestazione "Set-Cookie" ([COOKIE]) appare spesso in un messaggio di risposta su più righe di campo e non utilizza la sintassi dell'elenco, violando i requisiti sopra indicati su più righe di campo con lo stesso nome di campo. Poiché non può essere combinato in un singolo valore di campo, i destinatari dovrebbero trattare "Set-Cookie" come un caso speciale durante l'elaborazione dei campi. (Vedere l'Appendice A.2.3 di [Kri2001] per i dettagli.)
L'ordine in cui vengono ricevute le righe di campo con nomi di campo diversi in una sezione non è significativo. Tuttavia, è buona pratica inviare prima i campi di intestazione che contengono dati di controllo aggiuntivi, come Host nelle richieste e Date nelle risposte, in modo che le implementazioni possano decidere il prima possibile quando non elaborare un messaggio.
Un server NON DEVE (MUST NOT) applicare una richiesta alla risorsa di destinazione fino a quando non ha ricevuto l'intera sezione di intestazione della richiesta, poiché le righe di campo di intestazione successive potrebbero includere condizioni, credenziali di autenticazione o campi di intestazione duplicati deliberatamente fuorvianti che potrebbero influire sull'elaborazione della richiesta.
5.4. Limiti dei Campi
HTTP non pone un limite predefinito sulla lunghezza di ciascuna riga di campo, valore di campo o sulla lunghezza di una sezione di intestazione o trailer nel suo complesso, come descritto nella Sezione 2. Varie limitazioni ad hoc sulle lunghezze individuali si trovano nella pratica, spesso a seconda della semantica del campo specifico.
Un server che riceve una riga di campo di intestazione di richiesta, un valore di campo o un insieme di campi più grande di quanto desidera elaborare DEVE rispondere con un codice di stato 4xx (Errore del Client) appropriato. Ignorare tali campi di intestazione aumenterebbe la vulnerabilità del server agli attacchi di contrabbando di richieste (Sezione 11.2 di [HTTP/1.1]).
Un client PUÒ (MAY) scartare o troncare le righe di campo ricevute che sono più grandi di quanto il client desidera elaborare se la semantica del campo è tale che il/i valore/i scartato/i può/possono essere ignorato/i in sicurezza senza modificare l'inquadramento del messaggio o la semantica della risposta.
5.5. Valori di Campo
I valori di campo HTTP (Field Values) consistono in una sequenza di caratteri in un formato definito dalla grammatica del campo. La grammatica di ciascun campo è solitamente definita utilizzando ABNF ([RFC5234]).
field-value = *field-content
field-content = field-vchar
[ 1*( SP / HTAB / field-vchar ) field-vchar ]
field-vchar = VCHAR / obs-text
obs-text = %x80-FF
I valori di campo non includono spazi bianchi iniziali o finali. Quando una versione specifica di HTTP consente a tali spazi bianchi di apparire in un messaggio, un'implementazione di analisi dei campi DEVE escludere tali spazi bianchi prima di valutare il valore del campo.
I valori di campo sono solitamente limitati all'intervallo di caratteri US-ASCII [USASCII]. I campi che necessitano di un intervallo di caratteri maggiore possono utilizzare una codifica, come quella definita in [RFC8187]. Storicamente, HTTP ha consentito contenuti di campo con testo nel set di caratteri ISO-8859-1 [ISO-8859-1], supportando altri set di caratteri solo attraverso l'uso della codifica [RFC2047]. Le specifiche per i campi appena definiti DOVREBBERO (SHOULD) limitare i loro valori agli ottetti US-ASCII visibili (VCHAR), SP e HTAB. Un destinatario DOVREBBE (SHOULD) trattare altri ottetti consentiti nel contenuto del campo (cioè, obs-text) come dati opachi.
I valori di campo contenenti caratteri CR, LF o NUL sono non validi e pericolosi, a causa dei vari modi in cui le implementazioni potrebbero analizzare e interpretare tali caratteri; un destinatario di CR, LF o NUL all'interno di un valore di campo DEVE rifiutare il messaggio o sostituire ciascuno di questi caratteri con SP prima dell'ulteriore elaborazione o inoltro di quel messaggio. I valori di campo contenenti altri caratteri CTL sono anch'essi non validi; tuttavia, i destinatari POSSONO (MAY) conservare tali caratteri per motivi di robustezza quando appaiono all'interno di un contesto sicuro (ad es., una stringa tra virgolette specifica dell'applicazione che non sarà elaborata da alcun parser HTTP a valle).
I campi che prevedono solo un singolo membro come valore di campo sono chiamati "campi singleton" (Singleton Fields).
I campi che consentono più membri come valore di campo sono chiamati "campi basati su elenchi" (List-Based Fields). L'estensione dell'operatore di elenco della Sezione 5.6.1 è utilizzata come notazione comune per definire i valori di campo che possono contenere più membri.
Poiché le virgole (",") sono utilizzate come separatore tra i membri, devono essere trattate con cura se sono consentite come dati all'interno di un membro. Questo vale sia per i campi basati su elenchi che per i campi singleton, poiché un campo singleton potrebbe essere erroneamente inviato con più membri e il rilevamento di tali errori migliora l'interoperabilità. I campi che prevedono di contenere una virgola all'interno di un membro, come all'interno di una data HTTP o di un elemento di riferimento URI, dovrebbero definire delimitatori attorno a quell'elemento per distinguere qualsiasi virgola all'interno di quei dati dai potenziali separatori di elenco.
Ad esempio, una data testuale e un URI (entrambi potrebbero contenere una virgola) potrebbero essere trasportati in sicurezza in valori di campo basati su elenchi come questi:
Example-URIs: "http://example.com/a.html,foo",
"http://without-a-comma.example.com/"
Example-Dates: "Sat, 04 May 1996", "Wed, 14 Sep 2005"
Si noti che i delimitatori tra virgolette doppie sono quasi sempre utilizzati con la produzione quoted-string (Sezione 5.6.4); l'utilizzo di una sintassi diversa all'interno delle virgolette doppie probabilmente causerà confusione inutile.
Molti campi (ad es., Content-Type, definito nella Sezione 8.3) utilizzano una sintassi comune per i parametri che consente sia sintassi non quotata (token) che quotata (quoted-string) per un valore di parametro (Sezione 5.6.6). L'uso di una sintassi comune consente ai destinatari di riutilizzare i componenti parser esistenti. Quando si consentono entrambe le forme, il significato di un valore di parametro dovrebbe essere indipendente dalla forma utilizzata per trasmettere quel valore.
Nota: Per definire la sintassi del valore di campo, questa specifica utilizza una regola ABNF denominata in base al nome del campo per definire la grammatica consentita per il valore di quel campo (dopo che il valore del campo è stato estratto dalla sintassi di messaggistica sottostante e più istanze sono state combinate in un elenco).
5.6. Regole Comuni per Definire i Valori di Campo
5.6.1. Elenchi (Estensione ABNF della regola #)
Un'estensione della regola # alle regole ABNF di [RFC5234] è utilizzata per migliorare la leggibilità nelle definizioni di alcuni valori di campo basati su elenchi.
Un costrutto "#" è definito, simile a "*", per definire elenchi di elementi delimitati da virgole. La forma completa è "<n>#<m>element" che indica almeno <n> e al massimo <m> elementi, ciascuno separato da una singola virgola (",") e spazio bianco opzionale (OWS, definito nella Sezione 5.6.3).
5.6.1.1. Requisiti del Mittente
In qualsiasi produzione che utilizza il costrutto di elenco, un mittente NON DEVE (MUST NOT) generare elementi di elenco vuoti. In altre parole, un mittente deve generare elenchi che soddisfano la seguente sintassi:
1#element => element *( OWS "," OWS element )
e:
#element => [ 1#element ]
e per n >= 1 e m > 1:
`<n>`#<m>element => element <n-1>*<m-1>( OWS "," OWS element )
L'Appendice A mostra l'ABNF raccolto per i mittenti dopo l'espansione dei costrutti di elenco.
5.6.1.2. Requisiti del Destinatario
Gli elementi vuoti non contribuiscono al conteggio degli elementi presenti. Un destinatario DEVE analizzare e ignorare un numero ragionevole di elementi di elenco vuoti: abbastanza per gestire gli errori comuni dei mittenti che uniscono i valori, ma non così tanti da poter essere utilizzati come meccanismo di denial-of-service. In altre parole, un destinatario DEVE accettare elenchi che soddisfano la seguente sintassi:
#element => [ element ] *( OWS "," OWS [ element ] )
Si noti che a causa della potenziale presenza di elementi di elenco vuoti, l'ABNF RFC 5234 non può imporre la cardinalità degli elementi di elenco, e quindi tutti i casi sono mappati come se non fosse specificata alcuna cardinalità.
Ad esempio, date queste produzioni ABNF:
example-list = 1#example-list-elmt
example-list-elmt = token ; vedere Sezione 5.6.2
Allora i seguenti sono valori validi per example-list (non includendo le virgolette doppie, che sono presenti solo per la delimitazione):
"foo,bar"
"foo ,bar,"
"foo , ,bar,charlie"
Al contrario, i seguenti sarebbero non validi, poiché la produzione example-list richiede almeno un elemento non vuoto:
""
","
", ,"
5.6.2. Token
I token (Tokens) sono brevi identificatori testuali che non includono spazi bianchi o delimitatori.
token = 1*tchar
tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*"
/ "+" / "-" / "." / "^" / "_" / "`" / "|" / "~"
/ DIGIT / ALPHA
; qualsiasi VCHAR, eccetto i delimitatori
Molti valori di campo HTTP sono definiti utilizzando componenti di sintassi comuni, separati da spazi bianchi o caratteri di delimitazione specifici. I delimitatori sono scelti dall'insieme di caratteri visibili US-ASCII non consentiti in un token (DQUOTE e "(),/:;<=>?@[\]{}").
5.6.3. Spazi Bianchi
Questa specifica utilizza tre regole per denotare l'uso di spazi bianchi lineari: OWS (spazio bianco opzionale, Optional Whitespace), RWS (spazio bianco richiesto, Required Whitespace) e BWS (spazio bianco "cattivo", "Bad" Whitespace).
La regola OWS è utilizzata dove possono apparire zero o più ottetti di spazio bianco lineare. Per gli elementi di protocollo in cui lo spazio bianco opzionale è preferito per migliorare la leggibilità, un mittente DOVREBBE (SHOULD) generare lo spazio bianco opzionale come un singolo SP; altrimenti, un mittente NON DOVREBBE (SHOULD NOT) generare spazio bianco opzionale eccetto quando necessario per filtrare elementi di protocollo non validi o indesiderati durante il filtraggio dei messaggi in loco.
La regola RWS è utilizzata quando è richiesto almeno un ottetto di spazio bianco lineare per separare i token di campo. Un mittente DOVREBBE (SHOULD) generare RWS come un singolo SP.
Le regole OWS e RWS hanno la stessa semantica di un singolo SP. Qualsiasi contenuto noto per essere definito come OWS o RWS PUÒ (MAY) essere sostituito con un singolo SP prima di interpretarlo o inoltrare il messaggio a valle.
La regola BWS è utilizzata dove la grammatica consente spazio bianco opzionale solo per ragioni storiche. Un mittente NON DEVE (MUST NOT) generare BWS nei messaggi. Un destinatario DEVE analizzare tale spazio bianco cattivo e rimuoverlo prima di interpretare l'elemento di protocollo.
BWS non ha semantica. Qualsiasi contenuto noto per essere definito come BWS PUÒ (MAY) essere rimosso prima di interpretarlo o inoltrare il messaggio a valle.
OWS = *( SP / HTAB )
; spazio bianco opzionale
RWS = 1*( SP / HTAB )
; spazio bianco richiesto
BWS = OWS
; spazio bianco "cattivo"
5.6.4. Stringhe Tra Virgolette
Una stringa di testo viene analizzata come un singolo valore se è quotata utilizzando segni di virgolette doppie.
quoted-string = DQUOTE *( qdtext / quoted-pair ) DQUOTE
qdtext = HTAB / SP / %x21 / %x23-5B / %x5D-7E / obs-text
L'ottetto barra rovesciata ("") può essere utilizzato come meccanismo di quotazione a ottetto singolo all'interno dei costrutti quoted-string e comment. I destinatari che elaborano il valore di una quoted-string DEVONO gestire un quoted-pair come se fosse sostituito dall'ottetto che segue la barra rovesciata.
quoted-pair = "\" ( HTAB / SP / VCHAR / obs-text )
Un mittente NON DOVREBBE (SHOULD NOT) generare un quoted-pair in una quoted-string eccetto dove necessario per quotare gli ottetti DQUOTE e barra rovesciata che appaiono in quella stringa. Un mittente NON DOVREBBE (SHOULD NOT) generare un quoted-pair in un commento eccetto dove necessario per quotare le parentesi ["(" e ")"] e gli ottetti barra rovesciata che appaiono in quel commento.
5.6.5. Commenti
I commenti possono essere inclusi in alcuni campi HTTP circondando il testo del commento con parentesi. I commenti sono consentiti solo nei campi che contengono "comment" come parte della loro definizione di valore di campo.
comment = "(" *( ctext / quoted-pair / comment ) ")"
ctext = HTAB / SP / %x21-27 / %x2A-5B / %x5D-7E / obs-text
5.6.6. Parametri
I parametri (Parameters) sono istanze di coppie nome/valore; sono spesso utilizzati nei valori di campo come sintassi comune per aggiungere informazioni ausiliarie a un elemento. Ciascun parametro è solitamente delimitato da un punto e virgola immediatamente precedente.
parameters = *( OWS ";" OWS [ parameter ] )
parameter = parameter-name "=" parameter-value
parameter-name = token
parameter-value = ( token / quoted-string )
I nomi di parametro non sono sensibili alle maiuscole. I valori di parametro potrebbero essere sensibili o non sensibili alle maiuscole, a seconda della semantica del nome del parametro. Esempi di parametri e alcune forme equivalenti possono essere visti nei tipi di media (Sezione 8.3.1) e nel campo di intestazione Accept (Sezione 12.5.1).
Un valore di parametro che corrisponde alla produzione token può essere trasmesso sia come token che all'interno di una quoted-string. I valori quotati e non quotati sono equivalenti.
Nota: I parametri non consentono spazio bianco (nemmeno spazio bianco "cattivo") attorno al carattere "=".
5.6.7. Formati Data/Ora
Prima del 1995, c'erano tre formati diversi comunemente utilizzati dai server per comunicare i timestamp. Per motivi di compatibilità con le vecchie implementazioni, tutti e tre sono definiti qui. Il formato preferito è un sottoinsieme a lunghezza fissa e zona singola della specifica di data e ora utilizzata dal Formato di Messaggio Internet [RFC5322].
HTTP-date = IMF-fixdate / obs-date
Un esempio del formato preferito è
Sun, 06 Nov 1994 08:49:37 GMT ; IMF-fixdate
Esempi dei due formati obsoleti sono
Sunday, 06-Nov-94 08:49:37 GMT ; formato RFC 850 obsoleto
Sun Nov 6 08:49:37 1994 ; formato asctime() di ANSI C
Un destinatario che analizza un valore di timestamp in un campo HTTP DEVE accettare tutti e tre i formati HTTP-date. Quando un mittente genera un campo che contiene uno o più timestamp definiti come HTTP-date, il mittente DEVE generare quei timestamp nel formato IMF-fixdate.
Un valore HTTP-date rappresenta il tempo come un'istanza del Tempo Universale Coordinato (Coordinated Universal Time, UTC). I primi due formati indicano UTC tramite 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 "orologio" (Clock) è un'implementazione capace di fornire un'approssimazione ragionevole dell'istante corrente in UTC. Un'implementazione di orologio dovrebbe utilizzare NTP ([RFC5905]) o qualche protocollo simile per sincronizzarsi con UTC.
Formato preferito:
IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT
; sottoinsieme a lunghezza/zona/capitalizzazione fissa del formato
; vedere Sezione 3.3 di [RFC5322]
day-name = %s"Mon" / %s"Tue" / %s"Wed"
/ %s"Thu" / %s"Fri" / %s"Sat" / %s"Sun"
date1 = day SP month SP year
; ad es., 02 Jun 1982
day = 2DIGIT
month = %s"Jan" / %s"Feb" / %s"Mar" / %s"Apr"
/ %s"May" / %s"Jun" / %s"Jul" / %s"Aug"
/ %s"Sep" / %s"Oct" / %s"Nov" / %s"Dec"
year = 4DIGIT
GMT = %s"GMT"
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 es., 02-Jun-82
day-name-l = %s"Monday" / %s"Tuesday" / %s"Wednesday"
/ %s"Thursday" / %s"Friday" / %s"Saturday"
/ %s"Sunday"
asctime-date = day-name SP date3 SP time-of-day SP year
date3 = month SP ( 2DIGIT / ( SP 1DIGIT ))
; ad es., Jun 2
HTTP-date è sensibile alle maiuscole. Si noti che la Sezione 4.2 di [CACHING] rilassa questo per i destinatari di cache.
Un mittente NON DEVE (MUST NOT) generare spazio bianco aggiuntivo in un HTTP-date oltre a quello specificamente incluso come SP nella grammatica. La semantica di day-name, day, month, year e time-of-day è la stessa di quella definita per i costrutti del Formato di Messaggio Internet con il nome corrispondente ([RFC5322], Sezione 3.3).
I destinatari di un valore di timestamp in formato rfc850-date, che utilizza un anno a due cifre, DEVONO 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.
I destinatari di valori di timestamp sono incoraggiati a essere robusti nell'analisi dei timestamp a meno che non siano altrimenti limitati dalla definizione del campo. Ad esempio, i messaggi vengono occasionalmente inoltrati su HTTP da una fonte non HTTP che potrebbe generare una qualsiasi delle specifiche di data e ora definite dal Formato di Messaggio Internet.
Nota: I requisiti HTTP per il formato di timestamp data/ora si applicano solo al loro utilizzo nel flusso del protocollo. Le implementazioni non sono tenute a utilizzare questi formati per la presentazione all'utente, la registrazione delle richieste, ecc.