4. HTTP Message (Messaggio HTTP)
4.1 Message Types (Tipi di Messaggio)
I messaggi HTTP consistono in richieste (request) dal client al server e risposte (response) dal server al client.
HTTP-message = Request | Response ; HTTP/1.1 messages
I messaggi di richiesta (sezione 5) e di risposta (sezione 6) utilizzano il formato di messaggio generico di RFC 822 [9] per trasferire entità (entity) (il payload del messaggio). Entrambi i tipi di messaggio sono composti da una riga iniziale (start line), zero o più campi di intestazione (header field) (chiamati anche "headers"), una riga vuota che indica la fine dei campi di intestazione (cioè, una riga senza nulla prima del CRLF), e possibilmente un corpo del messaggio (message body).
generic-message = start-line
*(message-header CRLF)
CRLF
[ message-body ]
start-line = Request-Line | Status-Line
Per robustezza, i server dovrebbero (SHOULD) ignorare qualsiasi riga vuota ricevuta nella posizione in cui è attesa una Request-Line. In altre parole, se il server legge il flusso di protocollo all'inizio di un messaggio e riceve prima un CRLF, dovrebbe ignorare quel CRLF.
Alcune implementazioni di client HTTP/1.0 difettose generano CRLF aggiuntivi dopo le richieste POST. Per ribadire ciò che il BNF vieta esplicitamente, i client HTTP/1.1 non devono (MUST NOT) aggiungere CRLF aggiuntivi prima o dopo le richieste.
4.2 Message Headers (Intestazioni dei Messaggi)
I campi di intestazione HTTP, inclusi i campi di intestazione generale (general-header) (sezione 4.5), di intestazione di richiesta (request-header) (sezione 5.3), di intestazione di risposta (response-header) (sezione 6.2) e di intestazione di entità (entity-header) (sezione 7.1), seguono lo stesso formato generico fornito nella sezione 3.1 di RFC 822 [9]. Ogni campo di intestazione consiste in un nome seguito da due punti (":") e dal valore del campo. I nomi dei campi sono insensibili alle maiuscole. Il valore del campo può (MAY) essere preceduto da un numero qualsiasi di LWS, sebbene sia preferito un singolo SP. I campi di intestazione possono essere estesi su più righe precedendo ogni riga aggiuntiva con almeno un SP o HT. Le applicazioni dovrebbero (ought to) seguire la "forma comune" (common form) quando generano costrutti HTTP, se nota o indicata, poiché potrebbero esistere implementazioni che non possono accettare nulla oltre la forma comune.
message-header = field-name ":" [ field-value ]
field-name = token
field-value = *( field-content | LWS )
field-content = <the OCTETs making up the field-value
and consisting of either *TEXT or combinations
of token, separators, and quoted-string>
Il field-content non include alcun LWS iniziale o finale: lo spazio bianco lineare che appare prima del primo carattere non bianco di field-value o dopo l'ultimo carattere non bianco di field-value. Tale LWS iniziale o finale può (MAY) essere rimosso senza modificare la semantica del valore del campo. Qualsiasi LWS che appare tra i field-content può (MAY) essere sostituito con un singolo SP prima di interpretare il valore del campo o di inoltrare il messaggio downstream.
L'ordine di ricezione dei campi di intestazione con nomi di campo diversi non è importante. Tuttavia, è "buona pratica" (good practice) inviare prima i campi di intestazione generali, poi i campi di intestazione di richiesta o di risposta, e infine i campi di intestazione di entità.
Più campi message-header con lo stesso field-name possono (MAY) essere presenti in un messaggio se e solo se l'intero field-value per quel campo di intestazione è definito come un elenco separato da virgole [cioè #(values)]. Deve (MUST) essere possibile combinare i campi di intestazione multipli in un'unica coppia "field-name: field-value", senza modificare la semantica del messaggio, aggiungendo ciascun field-value successivo al primo, ciascuno separato da una virgola. L'ordine in cui i campi di intestazione con lo stesso field-name vengono ricevuti è quindi importante per l'interpretazione del valore del campo combinato, e di conseguenza un proxy non deve (MUST NOT) modificare l'ordine di questi valori di campo quando inoltra un messaggio.
4.3 Message Body (Corpo del Messaggio)
Il message-body di un messaggio HTTP, se presente, viene utilizzato per trasportare l'entity-body associato alla richiesta o alla risposta. Il message-body differisce dall'entity-body solo quando è stata applicata una codifica di trasferimento (transfer-coding), come indicato dal campo di intestazione Transfer-Encoding (sezione 14.41).
message-body = entity-body
| <entity-body encoded as per Transfer-Encoding>
Transfer-Encoding deve (MUST) essere utilizzato per indicare qualsiasi codifica di trasferimento applicata da un'applicazione per garantire un trasferimento sicuro e appropriato del messaggio. Transfer-Encoding è una proprietà del messaggio, piuttosto che dell'entità, e può (MAY) quindi essere aggiunto o rimosso da qualsiasi applicazione intermedia.
Quando un message-body è presente in un messaggio, la lunghezza di trasferimento (transfer-length) di quel message-body è determinata dalle regole definite nella sezione 4.4.
4.4 Message Length (Lunghezza del Messaggio)
La lunghezza di trasferimento di un messaggio è la lunghezza del message-body come appare nel trasferimento. Quando un message-body è presente in un messaggio, la lunghezza di trasferimento di quel corpo è determinata da uno dei seguenti elementi (in ordine di priorità):
-
Qualsiasi messaggio di risposta che non deve (MUST NOT) includere un message-body (come le risposte 1xx, 204 e 304 e qualsiasi risposta a una richiesta HEAD) è sempre terminato dalla prima riga vuota dopo i campi di intestazione, indipendentemente dai campi di intestazione di entità presenti nel messaggio.
-
Se è presente un campo di intestazione Transfer-Encoding e non è "identity", allora la lunghezza di trasferimento è definita dalla codifica di trasferimento "chunked", a meno che il messaggio non sia terminato dalla chiusura della connessione.
-
Se è presente un campo di intestazione Content-Length (sezione 14.13), il suo valore decimale in ottetti rappresenta sia l'Entity-Length sia la transfer-length. Se queste due lunghezze sono diverse (cioè, se è presente un campo di intestazione Transfer-Encoding), il campo di intestazione Content-Length non deve (MUST NOT) essere inviato. (Nota: Alcune implementazioni più vecchie inviavano erroneamente Content-Length con un Transfer-Encoding non-identity.)
-
Se il messaggio utilizza il tipo di media "multipart/byteranges", e la transfer-length non è altrimenti specificata, allora questo tipo di media auto-delimitante (self-delimiting) definisce la transfer-length. Questo tipo di media non deve (MUST NOT) essere utilizzato a meno che il mittente non sappia che il destinatario può analizzarlo; la presenza di un campo di intestazione Range presso un destinatario indica che il client può analizzare le risposte multipart/byteranges.
Un campo di intestazione Range potrebbe essere inoltrato da un proxy HTTP/1.0 che non comprende multipart/byteranges; in tal caso, il server deve (MUST) delimitare il messaggio con un campo Content-Range.
-
Dalla chiusura della connessione da parte del server. (La chiusura della connessione non può essere utilizzata per indicare la fine di un corpo di richiesta, poiché ciò lascerebbe il server incapace di inviare indietro una risposta.)
Per la compatibilità con le applicazioni HTTP/1.0, le richieste HTTP/1.1 contenenti un message-body devono (MUST) includere un campo di intestazione Content-Length valido a meno che non si sappia che il server è conforme a HTTP/1.1. Se una richiesta contiene un message-body e non include un Content-Length, il server dovrebbe (SHOULD) rispondere con 400 (bad request) se non può determinare la lunghezza del messaggio, o con 411 (length required) se desidera insistere sulla ricezione di un Content-Length valido.
Tutte le applicazioni HTTP/1.1 devono (MUST) accettare il transfer-coding "chunked" nei messaggi di richiesta, anche se l'applicazione stessa non invia messaggi chunked. Se una richiesta HTTP/1.1 include un message-body ma non include un Content-Length, il server dovrebbe (SHOULD) rispondere con 400 (bad request) se non può determinare la lunghezza della richiesta, o con 411 (length required) se desidera insistere sulla ricezione di un Content-Length valido.
Se una richiesta contiene un message-body e non viene fornito alcun Content-Length, il server dovrebbe (SHOULD) rispondere con 400 (bad request) se non può determinare la lunghezza del messaggio, o con 411 (length required) se desidera insistere sulla ricezione di un Content-Length valido.
Un messaggio non dovrebbe (SHOULD NOT) includere sia un campo di intestazione Transfer-Encoding sia un campo di intestazione Content-Length. Se un messaggio include entrambi, Transfer-Encoding deve (MUST) rimuovere Content-Length.
Quando un'entità codificata per contenuto viene ricevuta e analizzata, se la codifica del contenuto è nota, la lunghezza del message-body è determinata dai dati decodificati.
4.5 General Header Fields (Campi di Intestazione Generali)
Esistono alcuni campi di intestazione che hanno applicabilità generale per i messaggi di richiesta e risposta, ma che non si applicano all'entità trasferita. Questi campi di intestazione si applicano solo al messaggio in trasferimento.
general-header = Cache-Control ; Section 14.9
| Connection ; Section 14.10
| Date ; Section 14.18
| Pragma ; Section 14.32
| Trailer ; Section 14.40
| Transfer-Encoding ; Section 14.41
| Upgrade ; Section 14.42
| Via ; Section 14.45
| Warning ; Section 14.46
I nomi dei campi di intestazione generali possono essere estesi in modo affidabile solo modificando la versione del protocollo. Tuttavia, nuovi campi di intestazione o sperimentali possono essere assegnati ai valori dei campi senza modificare la versione del protocollo. La sezione 7.1 definisce la semantica dei campi di intestazione di entità.
I campi di intestazione non riconosciuti dovrebbero (SHOULD) essere trattati come campi di intestazione di entità dal destinatario.