13. Conditional Requests (Richieste condizionali)
Una richiesta condizionale è una richiesta HTTP che include uno o più campi di intestazione della richiesta che indicano una precondizione da testare prima di applicare il metodo di richiesta alla risorsa di destinazione. La sezione 13.2 definisce quando le precondizioni vengono valutate e l'ordine della loro precedenza quando è presente più di una precondizione.
Le richieste GET condizionali sono il meccanismo più efficiente per gli aggiornamenti della cache HTTP [CACHING]. Le condizioni possono anche essere applicate ai metodi di modifica dello stato, come PUT e DELETE, per prevenire il problema dell'"aggiornamento perso": un client sovrascrive accidentalmente il lavoro di un altro client che è stato operante in parallelo.
13.1. Preconditions (Precondizioni)
Le precondizioni sono generalmente definite rispetto a uno stato della risorsa di destinazione nel suo insieme (il suo insieme di valori correnti) o lo stato osservato in una rappresentazione precedentemente ottenuta (un valore in quell'insieme). Se una risorsa ha più rappresentazioni correnti, ognuna con il proprio stato osservabile, una precondizione assumerà che la mappatura di ciascuna richiesta alla rappresentazione selezionata (sezione 3.2) sia coerente nel tempo. In ogni caso, se la mappatura è incoerente o il server non è in grado di selezionare una rappresentazione appropriata, non ne deriverà alcun danno quando la precondizione viene valutata come false.
Ciascuna precondizione definita di seguito include un confronto tra un insieme di validatori ottenuti da rappresentazioni precedenti della risorsa di destinazione e lo stato corrente dei validatori per la rappresentazione selezionata (sezione 8.8). Pertanto, queste precondizioni valutano se lo stato della risorsa di destinazione è cambiato da un determinato stato noto al client. L'effetto di tale valutazione dipende dalla semantica del metodo e dalla scelta della condizione, come definito nella sezione 13.2.
Altre precondizioni, definite da altre specifiche come campi di estensione, potrebbero imporre condizioni su tutti i destinatari, lo stato della risorsa di destinazione in generale, o un gruppo di risorse. Ad esempio, il campo di intestazione "If" in WebDAV può rendere una richiesta condizionale su vari aspetti di più risorse, come i blocchi ([WEBDAV], sezione 10.4), se il destinatario comprende e implementa quel campo.
L'estensibilità delle precondizioni è possibile solo quando la precondizione può essere ignorata in modo sicuro se sconosciuta (come If-Modified-Since), quando la distribuzione può essere assunta per un determinato caso d'uso, o quando l'implementazione è segnalata da qualche altra proprietà della risorsa di destinazione. Ciò incoraggia l'attenzione su standard comuni con distribuzione condivisa.
13.1.1. If-Match
Il campo di intestazione "If-Match" rende il metodo di richiesta condizionale al fatto che il server di origine destinatario abbia almeno una rappresentazione corrente della risorsa di destinazione, quando il valore del campo è "*", o abbia una rappresentazione corrente della risorsa di destinazione che ha un entity tag corrispondente a un membro dell'elenco di entity tag forniti nel valore del campo.
Un server di origine DEVE utilizzare la funzione di confronto forte quando confronta gli entity tag per If-Match (sezione 8.8.3.2), poiché il client intende che questa precondizione impedisca l'applicazione del metodo se c'è stata qualsiasi modifica ai dati di rappresentazione.
If-Match = "*" / #entity-tag
Esempi:
If-Match: "xyzzy"
If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-Match: *
If-Match è più comunemente utilizzato con i metodi di modifica dello stato (ad esempio, POST, PUT, DELETE) per prevenire sovrascritture accidentali quando più agenti utente potrebbero agire in parallelo sulla stessa risorsa (cioè, per prevenire il problema dell'"aggiornamento perso"). In generale, può essere utilizzato con qualsiasi metodo che coinvolga la selezione o la modifica di una rappresentazione per interrompere la richiesta se l'entity tag corrente della rappresentazione selezionata non è un membro del valore del campo If-Match.
Quando un server di origine riceve una richiesta che seleziona una rappresentazione e quella richiesta include un campo di intestazione If-Match, il server di origine DEVE valutare la condizione If-Match secondo la sezione 13.2 prima di eseguire il metodo.
Per valutare un campo di intestazione If-Match ricevuto:
-
Se il valore del campo è "*", la condizione è vera se il server di origine ha una rappresentazione corrente per la risorsa di destinazione.
-
Se il valore del campo è un elenco di entity tag, la condizione è vera se uno qualsiasi dei tag elencati corrisponde all'entity tag della rappresentazione selezionata.
-
Altrimenti, la condizione è falsa.
Un server di origine che valuta una condizione If-Match NON DEVE eseguire il metodo richiesto se la condizione viene valutata come false. Invece, il server di origine PUÒ indicare che la richiesta condizionale è fallita rispondendo con un codice di stato 412 (Precondition Failed).
In alternativa, se la richiesta è un'operazione di modifica dello stato che sembra essere già riuscita sulla risorsa di destinazione, un server di origine PUÒ rispondere con un codice di stato 2xx (Successful) (cioè, la modifica dello stato è già riuscita perché lo stato della risorsa è già ciò che era previsto) se uno o più entity tag elencati nel valore del campo If-Match corrispondono all'entity tag della rappresentazione selezionata.
Un client che fornirà successivamente un campo di intestazione If-Match DOVREBBE prima ottenere uno o più entity tag in una richiesta precedente, tipicamente ottenendo una rappresentazione dal campo di intestazione ETag (sezione 8.8.3) della rappresentazione.
13.1.2. If-None-Match
Il campo di intestazione "If-None-Match" rende il metodo di richiesta condizionale al fatto che il server di origine destinatario non abbia alcuna rappresentazione corrente della risorsa di destinazione, quando il valore del campo è "*", o abbia una rappresentazione corrente della risorsa di destinazione che non ha un entity tag corrispondente a nessuno di quelli forniti nel valore del campo.
Un destinatario DEVE utilizzare la funzione di confronto debole quando confronta gli entity tag per If-None-Match (sezione 8.8.3.2), poiché gli entity tag deboli possono essere utilizzati per la convalida della cache anche se ci sono stati cambiamenti ai dati di rappresentazione che sono semanticamente insignificanti.
If-None-Match = "*" / #entity-tag
Esempi:
If-None-Match: "xyzzy"
If-None-Match: W/"xyzzy"
If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz"
If-None-Match: *
If-None-Match è principalmente utilizzato in due situazioni:
-
Con GET o HEAD per aggiornare una rappresentazione memorizzata nella cache che non ha un entity tag. Se un server di origine riceve una richiesta per If-None-Match con GET o HEAD, DOVREBBE valutarla secondo la sezione 13.2.
-
Con altri metodi per prevenire una modifica involontaria di una rappresentazione esistente. Se una richiesta comporterebbe qualcosa di diverso dalla creazione o sostituzione di una rappresentazione senza precondizione, e il server ha una rappresentazione corrente per quella risorsa, un client DOVREBBE inviare un valore del campo If-None-Match di "*".
Quando un server di origine riceve una richiesta che seleziona una rappresentazione e quella richiesta include un campo di intestazione If-None-Match, il server di origine DEVE valutare la condizione If-None-Match secondo la sezione 13.2 prima di eseguire il metodo.
Per valutare un campo di intestazione If-None-Match ricevuto:
-
Se il valore del campo è "*", la condizione è falsa se il server di origine ha una rappresentazione corrente per la risorsa di destinazione.
-
Se il valore del campo è un elenco di entity tag, la condizione è falsa se uno qualsiasi dei tag elencati corrisponde debolmente (sezione 8.8.3.2) all'entity tag della rappresentazione selezionata.
-
Altrimenti, la condizione è vera.
Un server di origine che valuta una condizione If-None-Match:
-
Se il metodo di richiesta è GET o HEAD e la condizione viene valutata come false, il server di origine DOVREBBE generare una risposta 304 (Not Modified).
-
Se il metodo di richiesta non è GET o HEAD e la condizione viene valutata come false, il server di origine DEVE generare una risposta 412 (Precondition Failed).
-
Altrimenti (cioè, la condizione è vera), il server di origine DOVREBBE elaborare la richiesta normalmente.
13.1.3. If-Modified-Since
Il campo di intestazione "If-Modified-Since" rende un metodo di richiesta GET o HEAD condizionale al fatto che la data di modifica della rappresentazione selezionata sia più recente della data e ora fornite nel valore del campo.
If-Modified-Since = HTTP-date
Esempio:
If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Quando un destinatario è un server di origine e If-Modified-Since è un campo di intestazione della richiesta su un metodo GET o HEAD, il destinatario DOVREBBE inviare una risposta 304 (Not Modified) se la data Last-Modified della rappresentazione selezionata è precedente o uguale alla data fornita nel campo di intestazione If-Modified-Since, a meno che la valutazione secondo la sezione 13.2 non comporti una risposta diversa.
Un destinatario DEVE ignorare If-Modified-Since se la richiesta contiene un campo di intestazione If-None-Match; la condizione in If-None-Match è considerata una sostituzione più accurata della condizione in If-Modified-Since, e le due sono solo condizionalmente compatibili quando valutate indipendentemente.
Un destinatario DOVREBBE ignorare il campo di intestazione If-Modified-Since se la data fornita nel valore del campo non è valida o è nel futuro.
13.1.4. If-Unmodified-Since
Il campo di intestazione "If-Unmodified-Since" rende il metodo di richiesta condizionale al fatto che la data dell'ultima modifica della rappresentazione selezionata sia precedente o uguale alla data fornita nel valore del campo.
If-Unmodified-Since = HTTP-date
Esempio:
If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT
Quando un destinatario è un server di origine e If-Unmodified-Since è un campo di intestazione della richiesta su un metodo di richiesta diverso da GET o HEAD, il destinatario DOVREBBE elaborare la richiesta normalmente se la data Last-Modified della rappresentazione selezionata è precedente o uguale alla data fornita nel campo di intestazione If-Unmodified-Since. Altrimenti, il destinatario DOVREBBE inviare una risposta 412 (Precondition Failed), a meno che la valutazione secondo la sezione 13.2 non comporti una risposta diversa.
Un destinatario DEVE ignorare If-Unmodified-Since se la richiesta contiene un campo di intestazione If-Match; la condizione in If-Match è considerata una sostituzione più accurata della condizione in If-Unmodified-Since, e le due sono solo condizionalmente compatibili quando valutate indipendentemente.
Un destinatario DOVREBBE ignorare il campo di intestazione If-Unmodified-Since se la data fornita nel valore del campo non è valida o è nel futuro.
13.1.5. If-Range
Il campo di intestazione "If-Range" fornisce una condizione speciale per le richieste Range (sezione 14): se il validatore fornito corrisponde al validatore corrente per la rappresentazione selezionata, allora elaborare il campo di intestazione Range come di consueto, restituendo uno o più contenuti parziali. Se il validatore non corrisponde, allora ignorare il campo di intestazione Range e restituire la rappresentazione selezionata completa.
If-Range = entity-tag / HTTP-date
Un client NON DEVE generare un campo di intestazione If-Range in una richiesta che non contiene un campo di intestazione Range.
Un server DEVE ignorare un campo di intestazione If-Range ricevuto in una richiesta che non contiene un campo di intestazione Range.
L'intento di If-Range è consentire a un client di aggiornare in modo efficiente una rappresentazione incompleta memorizzata nella cache quando è diventata obsoleta. Se il campo di intestazione If-Range non fosse presente, una rappresentazione incompleta memorizzata nella cache costringerebbe il client a rivalidarla (utilizzando una richiesta condizionale con If-Match o If-Unmodified-Since) e a richiedere solo le parti mancanti se la rivalidazione mostra che è ancora corrente, o altrimenti a sostituire l'intera rappresentazione memorizzata nella cache. Il campo di intestazione If-Range consente al client di evitare questo viaggio di andata e ritorno extra richiedendo le parti correnti o una rappresentazione completa in una singola richiesta.
Un server valuta la condizione If-Range utilizzando la funzione di confronto forte (sezione 8.8.3.2) quando il valore del campo è un entity tag. Quando il valore del campo è una data HTTP, il server la confronta con il valore del campo Last-Modified della rappresentazione selezionata, corrispondendo se i valori del timestamp sono esattamente uguali.
Un campo di intestazione If-Range DOVREBBE essere utilizzato solo con If-Unmodified-Since e una data Last-Modified o If-Match e un entity tag che corrisponde fortemente.
13.2. Evaluation of Preconditions (Valutazione delle precondizioni)
13.2.1. When to Evaluate (Quando valutare)
Salvo quando la definizione di una precondizione stabilisce diversamente, un server DEVE valutare le precondizioni della richiesta ricevute quando riceve una richiesta che seleziona una rappresentazione, prima di eseguire il metodo, poiché la loro valutazione potrebbe influenzare l'esecuzione del metodo.
Una conseguenza della valutazione delle precondizioni prima di eseguire il metodo è che precondizioni diverse ricevute dopo che il metodo ha già iniziato l'esecuzione non avranno un impatto su quell'esecuzione o sulla sua semantica di risposta.
Queste precondizioni potrebbero essere valutate in diversi passaggi di selezione. In pratica, i validatori per la "rappresentazione selezionata" sono spesso disponibili prima di eseguire il metodo, quindi le precondizioni possono essere valutate prima di creare o modificare una rappresentazione.
13.2.2. Precedence of Preconditions (Precedenza delle precondizioni)
Quando più di un campo di intestazione della richiesta condizionale è presente in una singola richiesta, l'ordine in cui le precondizioni vengono applicate diventa importante. In pratica, i campi che operano sullo stato della risorsa di destinazione sono spesso distribuiti insieme, come If-Unmodified-Since utilizzato con If-Match, o If-Modified-Since utilizzato con If-None-Match. Tuttavia, potrebbero essere presenti combinazioni incoerenti di campi di intestazione di precondizione.
Un server DEVE valutare le precondizioni della richiesta ricevute nel seguente ordine:
-
Quando il destinatario è il server di origine e If-Match è presente, valutare la precondizione If-Match e rispondere con un codice di stato 412 (Precondition Failed) se viene valutata come false.
-
Quando il destinatario è il server di origine, If-Match è assente e If-Unmodified-Since è presente, valutare la precondizione If-Unmodified-Since e rispondere con un codice di stato 412 (Precondition Failed) se viene valutata come false.
-
Quando If-None-Match è presente, valutare la precondizione If-None-Match e rispondere con un codice di stato 304 (Not Modified) (per GET/HEAD) o un codice di stato 412 (Precondition Failed) (per altri metodi) se viene valutata come false.
-
Quando il destinatario è il server di origine, il metodo è GET o HEAD, If-None-Match è assente e If-Modified-Since è presente, valutare la precondizione If-Modified-Since e rispondere con un codice di stato 304 (Not Modified) se viene valutata come false.
-
Quando il metodo è GET, il destinatario ha una richiesta valida per un campo di intestazione Range e If-Range è presente, elaborare il campo di intestazione Range se il validatore corrisponde al validatore corrente per la rappresentazione selezionata; altrimenti, ignorare il campo di intestazione Range e rispondere con una risposta 200 (OK) e la rappresentazione selezionata completa.
-
Altrimenti, tutte le condizioni sono state soddisfatte, quindi eseguire l'azione richiesta normalmente e generare una risposta appropriata.
Un server che genera uno dei codici di stato di risposta sopra riportati come risultato dell'elaborazione DOVREBBE generare una rappresentazione dello stato della risorsa di destinazione nel payload della risposta se l'origine della richiesta non è attendibile.
Qualsiasi estensione ai campi di intestazione If-Match e If-Unmodified-Since deve equivalentemente aggiornare questo algoritmo di valutazione delle precondizioni per mantenere un comportamento coerente.