Passa al contenuto principale

5. Semantica richiesta/risposta

CoAP opera secondo un modello richiesta/risposta simile a quello di HTTP: un endpoint CoAP nel ruolo di "client" invia una o più richieste CoAP a un "server", che soddisfa le richieste inviando risposte CoAP. A differenza di HTTP, le richieste e le risposte non vengono inviate su una connessione precedentemente stabilita, ma vengono scambiate in modo asincrono tramite messaggi CoAP.

5.1. Richieste​

Una richiesta CoAP è costituita dal metodo da applicare alla risorsa, dall'identificatore della risorsa, da un payload e da un Internet media type (se presente), nonché da metadati opzionali relativi alla richiesta.

CoAP supporta i metodi di base GET, POST, PUT e DELETE, che sono facilmente mappabili su HTTP. Essi hanno le stesse proprietà di safe (solo recupero) e idempotent (è possibile invocarli più volte con gli stessi effetti) di HTTP (vedere la Sezione 9.1 di [RFC2616]). Il metodo GET è safe; pertanto, non deve intraprendere alcuna azione su una risorsa diversa dal recupero (MUST NOT). I metodi GET, PUT e DELETE devono essere eseguiti in modo tale da risultare idempotent (MUST). POST non è idempotent, poiché il suo effetto è determinato dall'origin server e dipende dalla target resource; di solito comporta la creazione di una nuova risorsa o l'aggiornamento della target resource.

Una richiesta viene avviata impostando il campo Code nell'header CoAP di un messaggio Confirmable o Non-confirmable su un Method Code e includendo le informazioni della richiesta.

I metodi utilizzati nelle richieste sono descritti in dettaglio nella Sezione 5.8.

5.2. Risposte​

Dopo aver ricevuto e interpretato una richiesta, un server risponde con una risposta CoAP che viene abbinata alla richiesta per mezzo di un token generato dal client (Sezione 5.3); si noti che questo è diverso dal Message ID che abbina un messaggio Confirmable al suo Acknowledgement.

Una risposta è identificata dall'impostazione del campo Code nell'header CoAP su un Response Code. Analogamente all'HTTP Status Code, il CoAP Response Code indica il risultato del tentativo di comprendere e soddisfare la richiesta. Questi code sono definiti integralmente nella Sezione 5.9. I numeri di Response Code da impostare nel campo Code dell'header CoAP sono mantenuti nel CoAP Response Code Registry (Sezione 12.1.2).

 0
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|class| detail |
+-+-+-+-+-+-+-+-+

Figura 9: Struttura di un Response Code

I tre bit superiori del numero di Response Code a 8 bit definiscono la classe della risposta. I cinque bit inferiori non hanno alcun ruolo di categorizzazione; forniscono dettagli aggiuntivi alla classe complessiva (Figura 9).

Come notazione leggibile dall'essere umano per le specifiche e la diagnostica del protocollo, i numeri di code CoAP, incluso il Response Code, sono documentati nel formato "c.dd", dove "c" è la classe in decimale e "dd" è il dettaglio come numero decimale a due cifre. Ad esempio, "Forbidden" è scritto come 4.03 -- indicando un valore di code a 8 bit pari a esadecimale 0x83 (40x20+3) o decimale 131 (432+3).

Esistono 3 classi di Response Code:

2 - Success: la richiesta è stata ricevuta, compresa e accettata con successo.

4 - Client Error: la richiesta contiene una sintassi errata o non può essere soddisfatta.

5 - Server Error: il server non è riuscito a soddisfare una richiesta apparentemente valida.

I Response Code sono progettati per essere estensibili: i Response Code della classe Client Error o Server Error che non vengono riconosciuti da un endpoint sono trattati come equivalenti al Response Code generico di quella classe (rispettivamente 4.00 e 5.00). Tuttavia, non esiste un Response Code generico che indichi il successo, quindi un Response Code della classe Success che non venga riconosciuto da un endpoint può essere utilizzato solo per determinare che la richiesta ha avuto successo, senza ulteriori dettagli.

I possibili Response Code sono descritti in dettaglio nella Sezione 5.9.

Le risposte possono essere inviate in diversi modi, definiti nelle sottosezioni seguenti.

5.2.1. Piggybacked​

Nel caso più elementare, la risposta è trasportata direttamente nel messaggio Acknowledgement che conferma la richiesta (il che richiede che la richiesta sia stata trasportata in un messaggio Confirmable). Questa è chiamata "Piggybacked Response".

La risposta viene restituita nel messaggio Acknowledgement, indipendentemente dal fatto che indichi un successo o un fallimento. In effetti, la risposta è piggybacked sul messaggio Acknowledgement e non è richiesto alcun messaggio separato per restituire la risposta.

Nota di implementazione: il protocollo lascia al server la decisione se effettuare il piggyback di una risposta o meno (cioè inviare una separate response). Il client deve essere preparato a ricevere l'una o l'altra (MUST). A livello di qualità dell'implementazione, vi è una forte aspettativa che i server implementino il codice per effettuare il piggyback ogni volta che è possibile -- risparmiando risorse nella rete e sia presso il client che presso il server.

5.2.2. Separate​

Potrebbe non essere possibile restituire una piggybacked response in tutti i casi. Ad esempio, un server potrebbe impiegare più tempo per ottenere la rappresentazione della risorsa richiesta di quanto possa attendere per inviare il messaggio Acknowledgement, senza rischiare che il client ritrasmetta ripetutamente il messaggio di richiesta (vedere anche la discussione di PROCESSING_DELAY nella Sezione 4.8.2). La risposta a una richiesta trasportata in un messaggio Non-confirmable viene sempre inviata separatamente (poiché non esiste un messaggio Acknowledgement).

Un modo per implementarlo in un server è avviare il tentativo di ottenere la rappresentazione della risorsa e, mentre questo è in corso, far scadere un timer di acknowledgement. Un server può anche inviare immediatamente un acknowledgement se sa in anticipo che non ci sarà alcuna piggybacked response. In entrambi i casi, l'acknowledgement è effettivamente una promessa che la richiesta sarà gestita in seguito.

Quando il server ha finalmente ottenuto la rappresentazione della risorsa, invia la risposta. Quando si desidera che questo messaggio non vada perso, esso viene inviato come messaggio Confirmable dal server al client e riceve risposta dal client con un Acknowledgement, che riecheggia il nuovo Message ID scelto dal server. (Può anche essere inviato come messaggio Non-confirmable; vedere la Sezione 5.2.3.)

Quando il server sceglie di utilizzare una separate response, invia l'Acknowledgement alla richiesta Confirmable come messaggio Empty. Una volta che il server ha inviato un Empty Acknowledgement, non deve inviare la risposta in un altro Acknowledgement, anche se il client ritrasmette un'altra richiesta identica (MUST NOT). Se viene ricevuta una richiesta ritrasmessa (forse perché l'Acknowledgement originale è stato ritardato), viene inviato un altro Empty Acknowledgement e qualsiasi risposta deve essere inviata come separate response (MUST).

Se il server invia poi una risposta Confirmable, l'Acknowledgement del client a tale risposta deve essere anch'esso un messaggio Empty (uno che non trasporta né una richiesta né una risposta) (MUST). Il server deve interrompere la ritrasmissione della propria risposta alla ricezione di qualsiasi Acknowledgement corrispondente (ignorando silenziosamente qualsiasi Response Code o payload) o messaggio Reset (MUST).

Note di implementazione: si noti che, poiché il datagram transport sottostante potrebbe non preservare l'ordine, il messaggio Confirmable che trasporta la risposta può effettivamente arrivare prima o dopo il messaggio Acknowledgement per la richiesta; ai fini della terminazione della sequenza di ritrasmissione, questo funge anch'esso da acknowledgement. Si noti inoltre che, sebbene il protocollo CoAP stesso non ponga qui alcuna richiesta specifica, vi è un'aspettativa che la risposta arrivi entro un lasso di tempo ragionevole dal punto di vista dell'applicazione. Poiché non esiste un protocollo di trasporto sottostante che possa essere istruito a eseguire un meccanismo di keep-alive, il richiedente potrebbe voler impostare un timeout non correlato ai timer di ritrasmissione di CoAP, nel caso in cui il server sia distrutto o comunque incapace di inviare la risposta.

5.2.3. Non-confirmable​

Se il messaggio di richiesta è Non-confirmable, allora anche la risposta dovrebbe essere restituita in un messaggio Non-confirmable (SHOULD). Tuttavia, un endpoint deve essere preparato a ricevere una risposta Non-confirmable (preceduta o seguita da un messaggio Empty Acknowledgement) in risposta a una richiesta Confirmable, oppure una risposta Confirmable in risposta a una richiesta Non-confirmable (MUST).

5.3. Corrispondenza richiesta/risposta​

Indipendentemente da come viene inviata una risposta, essa viene abbinata alla richiesta per mezzo di un token incluso dal client nella richiesta, insieme a ulteriori informazioni di indirizzo dell'endpoint corrispondente.

5.3.1. Token​

Il Token viene utilizzato per abbinare una risposta a una richiesta. Il valore del token è una sequenza da 0 a 8 byte. (Si noti che ogni messaggio trasporta un token, anche se di lunghezza zero.) Ogni richiesta trasporta un token generato dal client che il server deve riecheggiare (senza modifiche) in qualsiasi risposta risultante (MUST).

Un token è destinato all'uso come identificatore locale al client per differenziare tra richieste concorrenti (vedere la Sezione 5.3); avrebbe potuto essere chiamato "request ID".

Il client dovrebbe generare token in modo tale che i token attualmente in uso per una data coppia di endpoint sorgente/destinazione siano unici (SHOULD). (Si noti che un'implementazione client può utilizzare lo stesso token per qualsiasi richiesta se utilizza ogni volta un endpoint diverso, ad esempio un numero di port sorgente diverso.) Un valore di token vuoto è appropriato, ad esempio, quando non sono in uso altri token verso una destinazione, o quando le richieste vengono effettuate in modo seriale per destinazione e ricevono piggybacked response. Esistono, tuttavia, molteplici possibili strategie di implementazione per soddisfare questo requisito.

Un client che invia una richiesta senza utilizzare Transport Layer Security (Sezione 9) dovrebbe utilizzare un token non banale e randomizzato per proteggersi dallo spoofing delle risposte (Sezione 11.4) (SHOULD). Questo uso protettivo dei token è la ragione per cui è consentito che siano di dimensione fino a 8 byte. La dimensione effettiva della componente casuale da utilizzare per il Token dipende dai requisiti di sicurezza del client e dal livello di minaccia posto dallo spoofing delle risposte. Un client connesso alla Internet generale dovrebbe utilizzare almeno 32 bit di casualità, tenendo presente che non essere direttamente connessi a Internet non è necessariamente una protezione sufficiente contro lo spoofing (SHOULD). (Si noti che il Message ID aggiunge poca protezione, poiché di solito è assegnato in modo sequenziale, cioè è indovinabile, e può essere aggirato falsificando una separate response.) I client che desiderano ottimizzare la lunghezza del Token potrebbero inoltre voler rilevare il livello di attacchi in corso (ad esempio, contando i recenti mancati abbinamenti di Token nei messaggi in arrivo) e aumentare opportunamente la lunghezza del Token. [RFC4086] discute i requisiti di casualità per la sicurezza.

Un endpoint che riceve un token che non ha generato deve trattarlo come opaco e non deve fare alcuna assunzione sul suo contenuto o sulla sua struttura (MUST).

5.3.2. Regole di corrispondenza richiesta/risposta​

Le regole esatte per abbinare una risposta a una richiesta sono le seguenti:

  1. L'endpoint sorgente della risposta deve essere lo stesso dell'endpoint di destinazione della richiesta originale (MUST).

  2. In una piggybacked response, il Message ID della richiesta Confirmable e dell'Acknowledgement devono corrispondere, e i token della risposta e della richiesta originale devono corrispondere (MUST). In una separate response, devono corrispondere solo i token della risposta e della richiesta originale (MUST).

Nel caso in cui un messaggio che trasporta una risposta sia inatteso (il client non è in attesa di una risposta dall'endpoint identificato, presso l'endpoint indirizzato e/o con il token dato), la risposta viene rifiutata (Sezioni 4.2 e 4.3).

Nota di implementazione: un client che riceve una risposta in un messaggio CON potrebbe voler ripulire lo stato del messaggio subito dopo aver inviato l'ACK. Se tale ACK va perso e il server ritrasmette il CON, il client potrebbe non avere più alcuno stato a cui correlare questa risposta, rendendo la ritrasmissione un messaggio inatteso; il client invierà probabilmente un messaggio Reset per non ricevere ulteriori ritrasmissioni. Questo comportamento è normale e non indica un errore. (I client che non sono ottimizzati in modo aggressivo nell'uso della memoria di stato avranno comunque uno stato del messaggio che identificherà il secondo CON come una ritrasmissione. I client che effettivamente si aspettano altri messaggi dal server [OBSERVE] dovranno comunque conservare lo stato.)

5.4. Opzioni​

Sia le richieste che le risposte possono includere un elenco di una o più opzioni. Ad esempio, l'URI in una richiesta è trasportato in diverse opzioni, e anche i metadati che in HTTP sarebbero trasportati in un header HTTP sono forniti come opzioni.

CoAP definisce un unico insieme di opzioni utilizzate sia nelle richieste che nelle risposte:

  • Content-Format

  • ETag

  • Location-Path

  • Location-Query

  • Max-Age

  • Proxy-Uri

  • Proxy-Scheme

  • Uri-Host

  • Uri-Path

  • Uri-Port

  • Uri-Query

  • Accept

  • If-Match

  • If-None-Match

  • Size1

La semantica di queste opzioni, insieme alle loro proprietà, è definita in dettaglio nella Sezione 5.10.

Non tutte le opzioni sono definite per l'uso con tutti i metodi e i Response Code. Le possibili opzioni per i metodi e i Response Code sono definite rispettivamente nelle Sezioni 5.8 e 5.9. Nel caso in cui un'opzione non sia definita per un Method o un Response Code, essa non deve essere inclusa da un mittente (MUST NOT) e deve essere trattata come un'opzione non riconosciuta da un destinatario (MUST).

5.4.1. Critical/Elective​

Le opzioni rientrano in una di due classi: "critical" o "elective". La differenza tra queste è il modo in cui viene gestita un'opzione non riconosciuta da un endpoint:

  • Alla ricezione, le opzioni non riconosciute della classe "elective" devono essere ignorate silenziosamente (MUST).

  • Le opzioni non riconosciute della classe "critical" che si verificano in una richiesta Confirmable devono causare la restituzione di una risposta 4.02 (Bad Option) (MUST). Questa risposta dovrebbe includere un payload diagnostico che descrive le opzioni non riconosciute (vedere la Sezione 5.5.2) (SHOULD).

  • Le opzioni non riconosciute della classe "critical" che si verificano in una risposta Confirmable, o piggybacked in un Acknowledgement, devono causare il rifiuto della risposta (Sezione 4.2) (MUST).

  • Le opzioni non riconosciute della classe "critical" che si verificano in un messaggio Non-confirmable devono causare il rifiuto del messaggio (Sezione 4.3) (MUST).

Si noti che, indipendentemente dal fatto che siano critical o elective, un'opzione non è mai "mandatory" (è sempre optional): queste regole sono definite al fine di consentire alle implementazioni di interrompere l'elaborazione delle opzioni che non comprendono o non implementano.

Le regole critical/elective si applicano agli endpoint non-proxy. Un proxy elabora le opzioni in base alle classi Unsafe/Safe-to-Forward definite nella Sezione 5.7.

5.4.2. Proxy Unsafe o Safe-to-Forward e NoCacheKey​

Oltre a essere contrassegnata come critical o elective, un'opzione è anche classificata in base a come un proxy deve gestirla se non la riconosce. A questo scopo, un'opzione può essere considerata Unsafe to forward (UnSafe è impostato) oppure Safe-to-Forward (UnSafe è azzerato).

Inoltre, per un'opzione contrassegnata come Safe-to-Forward, il numero dell'opzione indica se essa è o meno destinata a far parte della Cache-Key (Sezione 5.6) in una richiesta. Se alcuni dei bit NoCacheKey sono 0, lo è; se tutti i bit NoCacheKey sono 1, non lo è (vedere la Sezione 5.4.6).

Nota: L'indicazione Cache-Key è rilevante solo per i proxy che non implementano l'opzione data come request option e si affidano invece unicamente all'indicazione Unsafe/Safe-to-Forward. Ad esempio, per ETag, usare effettivamente la request option come parte della Cache-Key è estremamente inefficiente, ma è la cosa migliore che si possa fare se ETag non è implementata da un proxy, poiché la risposta differirà in base alla presenza della request option. Un proxy più utile che implementa la request option ETag non usa ETag come parte della Cache-Key.

NoCacheKey è indicato in tre bit, in modo che solo uno su otto codepoint sia qualificato come NoCacheKey, lasciando sette su otto codepoint per quello che sembra essere il caso più probabile.

Il comportamento del proxy rispetto a queste classi è definito nella Sezione 5.7.

5.4.3. Lunghezza​

I valori delle opzioni sono definiti per avere una lunghezza specifica, spesso nella forma di un limite superiore e inferiore. Se la lunghezza di un valore di opzione in una richiesta è al di fuori dell'intervallo definito, tale opzione deve essere trattata come un'opzione non riconosciuta (vedere la Sezione 5.4.1) (MUST).

5.4.4. Valori predefiniti​

Le opzioni possono essere definite per avere un valore predefinito. Se il valore di un'opzione è inteso essere questo valore predefinito, l'opzione non dovrebbe essere inclusa nel messaggio (SHOULD NOT). Se l'opzione non è presente, il valore predefinito deve essere assunto (MUST).

Quando un'opzione critical ha un valore predefinito, questo viene scelto in modo tale che l'assenza dell'opzione in un messaggio possa essere elaborata correttamente sia dalle implementazioni che non conoscono l'opzione critical sia dalle implementazioni che interpretano questa assenza come la presenza del valore predefinito dell'opzione.

5.4.5. Opzioni ripetibili​

La definizione di alcune opzioni specifica che tali opzioni sono repeatable. Un'opzione repeatable può essere inclusa una o più volte in un messaggio (MAY). Un'opzione che non è repeatable non deve essere inclusa più di una volta in un messaggio (MUST NOT).

Se un messaggio include un'opzione con un numero di occorrenze superiore a quello per cui l'opzione è definita, ogni occorrenza sovrannumeraria dell'opzione che appare successivamente nel messaggio deve essere trattata come un'opzione non riconosciuta (vedere la Sezione 5.4.1) (MUST).

5.4.6. Numeri di opzione​

Un'Opzione è identificata da un numero di opzione, che fornisce anche alcune informazioni semantiche aggiuntive, ad esempio i numeri dispari indicano un'opzione critical, mentre i numeri pari indicano un'opzione elective. Si noti che questa non è solo una convenzione, è una caratteristica del protocollo: se un'opzione è elective o critical è interamente determinato dal fatto che il suo numero di opzione sia pari o dispari.

Più in generale, un numero di Opzione è costruito con una maschera di bit per indicare se un'opzione è Critical o Elective, Unsafe o Safe-to-Forward e, nel caso di Safe-to-Forward, per fornire un'indicazione Cache-Key, come mostrato nella figura seguente. Nel testo seguente, la maschera di bit è espressa come un singolo byte applicato al byte meno significativo del numero di opzione nella rappresentazione come intero senza segno. Quando il bit 7 (il bit meno significativo) è 1, un'opzione è Critical (e analogamente Elective quando è 0). Quando il bit 6 è 1, un'opzione è Unsafe (e analogamente Safe-to-Forward quando è 0). Quando il bit 6 è 0, cioè l'opzione non è Unsafe, essa non è una Cache-Key (NoCacheKey) se e solo se i bit 3-5 sono tutti impostati a 1; tutte le altre combinazioni di bit significano che è effettivamente una Cache-Key. Queste classi di opzioni sono spiegate nelle sezioni successive.

  0   1   2   3   4   5   6   7
+---+---+---+---+---+---+---+---+
| | NoCacheKey| U | C |
+---+---+---+---+---+---+---+---+

Figura 10: Maschera del numero di opzione (byte meno significativo)

Un endpoint può utilizzare un equivalente del codice C nella Figura 11 per derivare le caratteristiche di un numero di opzione "onum".

Critical = (onum & 1);
UnSafe = (onum & 2);
NoCacheKey = ((onum & 0x1e) == 0x1c);

Figura 11: Determinazione delle caratteristiche da un numero di opzione

I numeri di opzione per le opzioni definite in questo documento sono elencati nel registro "CoAP Option Numbers" (Sezione 12.2).

5.5. Payload e rappresentazioni​

Sia le richieste che le risposte possono includere un payload, a seconda rispettivamente del Method o del Response Code. Se un Method o un Response Code non è definito per avere un payload, allora un mittente non deve includerne uno (MUST NOT) e un destinatario deve ignorarlo (MUST).

5.5.1. Rappresentazione​

Il payload delle richieste o delle risposte che indicano successo è tipicamente una rappresentazione di una risorsa ("resource representation") o il risultato dell'azione richiesta ("action result"). Il suo formato è specificato dall'Internet media type e dal content coding indicati dall'opzione Content-Format. In assenza di questa opzione, non si assume alcun valore predefinito e il formato dovrà essere inferito dall'applicazione (ad esempio dal contesto dell'applicazione). Il "sniffing" del payload dovrebbe essere tentato solo se non viene fornito alcun content type (SHOULD).

Nota di implementazione: a livello di qualità dell'implementazione, vi è una forte aspettativa che un'indicazione Content-Format venga fornita con le resource representation ogni volta che è possibile. Questo non è un requisito di livello "SHOULD" unicamente perché non è un requisito del protocollo, e inoltre sarebbe difficile delineare esattamente in quali casi questa aspettativa possa essere violata.

Per le risposte che indicano un errore del client o del server, il payload è considerato una rappresentazione del risultato dell'azione richiesta solo se viene fornita un'opzione Content-Format. In assenza di questa opzione, il payload è un Payload diagnostico (Sezione 5.5.2).

5.5.2. Payload diagnostico​

Se non viene fornita alcuna opzione Content-Format, il payload delle risposte che indicano un errore del client o del server è un breve messaggio diagnostico leggibile dall'essere umano, che spiega la situazione di errore. Questo messaggio diagnostico deve essere codificato utilizzando UTF-8 [RFC3629], più specificamente utilizzando la forma Net-Unicode [RFC5198] (MUST).

Il messaggio è simile alla Reason-Phrase su una status line HTTP. Non è destinato agli utenti finali ma agli ingegneri del software che durante il debug devono interpretarlo nel contesto della presente specifica in lingua inglese; pertanto, non è necessario né fornito alcun meccanismo per il language tagging. Contrariamente a quanto è usuale in HTTP, il payload dovrebbe essere vuoto se non vi sono informazioni aggiuntive oltre al Response Code (SHOULD).

5.5.3. Rappresentazione selezionata​

Non tutte le risposte trasportano un payload che fornisce una rappresentazione della risorsa indirizzata dalla richiesta. È tuttavia talvolta utile poter fare riferimento a tale rappresentazione in relazione a una risposta, indipendentemente dal fatto che sia stata effettivamente inclusa.

Usiamo il termine "selected representation" per riferirci alla rappresentazione corrente di una target resource che sarebbe stata selezionata in una risposta di successo se la richiesta corrispondente avesse utilizzato il metodo GET ed escluso qualsiasi opzione di richiesta condizionale (Sezione 5.10.8).

Alcune opzioni di risposta forniscono metadati sulla selected representation, che potrebbero differire dalla rappresentazione inclusa nel messaggio per le risposte ad alcuni metodi che modificano lo stato. Tra le opzioni di risposta definite in questa specifica, solo l'opzione di risposta ETag (Sezione 5.10.6) è definita come metadati sulla selected representation.

5.5.4. Negoziazione dei contenuti​

Un server può essere in grado di fornire una rappresentazione per una risorsa in uno tra più formati di rappresentazione. Senza ulteriori informazioni dal client, fornirà la rappresentazione nel formato che preferisce.

Utilizzando l'opzione Accept (Sezione 5.10.4) in una richiesta, il client può indicare quale content-format preferisce ricevere.

5.6. Caching​

Gli endpoint CoAP possono memorizzare in cache le risposte al fine di ridurre il tempo di risposta e il consumo di larghezza di banda di rete per future richieste equivalenti (MAY).

L'obiettivo del caching in CoAP è riutilizzare un messaggio di risposta precedente per soddisfare una richiesta corrente. In alcuni casi, una risposta memorizzata può essere riutilizzata senza la necessità di una richiesta di rete, riducendo la latenza e i round-trip di rete; a questo scopo viene utilizzato un meccanismo di "freshness" (vedere la Sezione 5.6.1). Anche quando è necessaria una nuova richiesta, è spesso possibile riutilizzare il payload di una risposta precedente per soddisfare la richiesta, riducendo così l'uso della larghezza di banda di rete; a questo scopo viene utilizzato un meccanismo di "validation" (vedere la Sezione 5.6.2).

A differenza di HTTP, la cacheability delle risposte CoAP non dipende dal metodo di richiesta, ma dipende dal Response Code. La cacheability di ciascun Response Code è definita insieme alle definizioni dei Response Code nella Sezione 5.9. I Response Code che indicano successo e non vengono riconosciuti da un endpoint non devono essere memorizzati in cache (MUST NOT).

Per una richiesta presentata, un endpoint CoAP non deve utilizzare una risposta memorizzata, a meno che (MUST NOT):

  • il metodo della richiesta presentata e quello utilizzato per ottenere la risposta memorizzata corrispondano,

  • tutte le opzioni corrispondano tra quelle nella richiesta presentata e quelle della richiesta utilizzata per ottenere la risposta memorizzata (il che include la request URI), salvo che non vi sia necessità di una corrispondenza per qualsiasi opzione di richiesta contrassegnata come NoCacheKey (Sezione 5.4) o riconosciuta dalla Cache e pienamente interpretata rispetto al suo comportamento di cache specificato (come l'opzione di richiesta ETag descritta nella Sezione 5.10.6; vedere anche la Sezione 5.4.2), e

  • la risposta memorizzata sia fresca o convalidata con successo come definito di seguito.

L'insieme di opzioni di richiesta utilizzato per abbinare la voce di cache è anche collettivamente denominato "Cache-Key". Per gli scheme URI diversi da coap e coaps, l'abbinamento di quelle opzioni che costituiscono la request URI può essere eseguito secondo regole specifiche dello scheme URI.

5.6.1. Modello di freschezza​

Quando una risposta è "fresh" nella cache, può essere utilizzata per soddisfare richieste successive senza contattare l'origin server, migliorando così l'efficienza.

Il meccanismo per determinare la freshness consiste nel fatto che un origin server fornisce un tempo di scadenza esplicito nel futuro, utilizzando l'opzione Max-Age (vedere la Sezione 5.10.5). L'opzione Max-Age indica che la risposta deve essere considerata non fresh dopo che la sua età supera il numero di secondi specificato.

L'opzione Max-Age ha un valore predefinito di 60. Pertanto, se non è presente in una risposta memorizzabile in cache, la risposta è considerata non fresh dopo che la sua età supera i 60 secondi. Se un origin server desidera impedire il caching, deve includere esplicitamente un'opzione Max-Age con un valore di zero secondi (MUST).

Se un client ha una risposta memorizzata fresh ed effettua una nuova richiesta che corrisponde alla richiesta per quella risposta memorizzata, la nuova risposta invalida la vecchia risposta.

5.6.2. Modello di validazione​

Quando un endpoint ha una o più risposte memorizzate per una richiesta GET, ma non può utilizzarne nessuna (ad esempio perché non sono fresh), può utilizzare l'opzione ETag (Sezione 5.10.6) nella richiesta GET per dare all'origin server l'opportunità sia di selezionare una risposta memorizzata da utilizzare, sia di aggiornarne la freshness. Questo processo è noto come "validating" o "revalidating" della risposta memorizzata.

Quando invia tale richiesta, l'endpoint dovrebbe aggiungere un'opzione ETag che specifica l'entity-tag di ciascuna risposta memorizzata applicabile (SHOULD).

Una risposta 2.03 (Valid) indica che la risposta memorizzata identificata dall'entity-tag fornito nell'opzione ETag della risposta può essere riutilizzata dopo averla aggiornata come descritto nella Sezione 5.9.1.3.

Qualsiasi altro Response Code indica che nessuna delle risposte memorizzate nominate nella richiesta è adatta. Invece, la risposta dovrebbe essere utilizzata per soddisfare la richiesta e può sostituire la risposta memorizzata (SHOULD, MAY).

5.7. Uso del proxy​

Un proxy è un endpoint CoAP a cui i client CoAP possono affidare l'esecuzione di richieste per loro conto. Ciò può essere utile, ad esempio, quando la richiesta non potrebbe altrimenti essere effettuata, o per servire la risposta da una cache al fine di ridurre il tempo di risposta e il consumo di larghezza di banda di rete o di energia.

In un'architettura complessiva per un Constrained RESTful Environment, i proxy possono servire scopi piuttosto diversi. I proxy possono essere selezionati esplicitamente dai client, un ruolo che chiamiamo "forward-proxy". I proxy possono anche essere inseriti per sostituire gli origin server, un ruolo che chiamiamo "reverse-proxy". Ortogonalmente a questa distinzione, un proxy può mappare da una richiesta CoAP a una richiesta CoAP (proxy CoAP-to-CoAP) oppure tradurre da o verso un protocollo diverso ("cross-proxy"). Le definizioni complete di questi termini sono fornite nella Sezione 1.2.

Note: la terminologia in questa specifica è stata scelta per essere culturalmente compatibile con la terminologia utilizzata negli ambienti applicativi web più ampi, senza necessariamente corrispondervi in ogni dettaglio (che potrebbe persino non essere rilevante per i Constrained RESTful Environment). Non si dovrebbe attribuire troppa semantica alle componenti dei termini (come "forward", "reverse" o "cross").

I proxy HTTP, oltre ad agire come proxy HTTP, spesso offrono una funzione di proxying a livello di protocollo di trasporto ("CONNECT") per consentire la sicurezza del livello di trasporto end-to-end attraverso il proxy. Nessuna tale funzione è definita per i proxy CoAP-to-CoAP in questa specifica, poiché l'inoltro di pacchetti UDP è improbabile che abbia molto valore nei Constrained RESTful Environment. Vedere anche la Sezione 10.2.7 per il caso cross-proxy.

Quando un client utilizza un proxy per effettuare una richiesta che utilizzerà uno scheme URI sicuro (ad esempio "coaps" o "https"), la richiesta verso il proxy dovrebbe essere inviata utilizzando DTLS, tranne nel caso in cui una sicurezza di livello inferiore equivalente sia utilizzata per il tratto tra il client e il proxy (SHOULD).

5.7.1. Operazione del proxy​

Un proxy generalmente necessita di un modo per determinare i potenziali parametri di richiesta per una richiesta che inoltra a una destinazione, in base alla richiesta che ha ricevuto dal suo client. Questo modo è completamente specificato per un forward-proxy ma può dipendere dalla configurazione specifica per un reverse-proxy. In particolare, il client di un reverse-proxy generalmente non indica un locator per la destinazione, rendendo necessaria una qualche forma di traduzione del namespace nel reverse-proxy. Tuttavia, alcuni aspetti del funzionamento dei proxy sono comuni a tutte le loro forme.

Se un proxy non impiega una cache, allora inoltra semplicemente la richiesta tradotta alla destinazione determinata. Altrimenti, se impiega una cache ma non ha una risposta memorizzata che corrisponda alla richiesta tradotta e sia considerata fresh, allora deve aggiornare la sua cache secondo la Sezione 5.6. Per le opzioni nella richiesta che il proxy riconosce, esso sa se l'opzione è destinata ad agire come parte della chiave utilizzata per cercare il valore memorizzato in cache o meno. Ad esempio, poiché le richieste con valori Uri-Path diversi indirizzano risorse diverse, i valori Uri-Path fanno sempre parte della Cache-Key, mentre, ad esempio, i valori Token non fanno mai parte della Cache-Key. Per le opzioni che il proxy non riconosce ma che sono contrassegnate come Safe-to-Forward nel numero di opzione, l'opzione indica anche se deve essere inclusa nella Cache-Key (NoCacheKey non è tutto impostato) o meno (NoCacheKey è tutto impostato). (Le opzioni non riconosciute e contrassegnate come Unsafe portano a 4.02 Bad Option.)

Se la richiesta verso la destinazione va in timeout, allora deve essere restituita una risposta 5.04 (Gateway Timeout) (MUST). Se la richiesta verso la destinazione restituisce una risposta che non può essere elaborata dal proxy (ad esempio a causa di opzioni critical non riconosciute o errori di formato del messaggio), allora deve essere restituita una risposta 5.02 (Bad Gateway) (MUST). Altrimenti, il proxy restituisce la risposta al client.

Se una risposta è generata da una cache, l'opzione Max-Age generata (o implicita) non deve estendere il max-age originariamente impostato dal server, considerando il tempo che la rappresentazione della risorsa ha trascorso nella cache (MUST NOT). Ad esempio, l'opzione Max-Age potrebbe essere regolata dal proxy per ogni risposta utilizzando la formula:

proxy-max-age = original-max-age - cache-age

Ad esempio, se viene effettuata una richiesta a una risorsa proxied che è stata aggiornata 20 secondi fa e aveva un Max-Age originale di 60 secondi, allora il proxied max-age di quella risorsa è ora di 40 secondi. Considerando i potenziali ritardi di rete lungo il percorso dall'origin server, un proxy dovrebbe essere conservativo nei valori di max-age offerti.

Tutte le opzioni presenti in una richiesta proxy devono essere elaborate presso il proxy (MUST). Le opzioni Unsafe in una richiesta che non sono riconosciute dal proxy devono portare a una risposta 4.02 (Bad Option) restituita dal proxy (MUST). Un proxy CoAP-to-CoAP deve inoltrare all'origin server tutte le opzioni Safe-to-Forward che non riconosce (MUST). Analogamente, le opzioni Unsafe in una risposta che non sono riconosciute dal server proxy CoAP-to-CoAP devono portare a una risposta 5.02 (Bad Gateway) (MUST). Anche in questo caso, le opzioni Safe-to-Forward che non sono riconosciute devono essere inoltrate (MUST).

Ulteriori considerazioni per il proxying cross-protocol tra CoAP e HTTP sono discusse nella Sezione 10.

5.7.2. Forward-Proxy​

CoAP distingue tra richieste effettuate (come se fossero) a un origin server e richieste effettuate attraverso un forward-proxy. Le richieste CoAP a un forward-proxy sono effettuate come normali richieste Confirmable o Non-confirmable all'endpoint forward-proxy, ma specificano la request URI in modo diverso: la request URI in una richiesta proxy è specificata come stringa nell'opzione Proxy-Uri (vedere la Sezione 5.10.2), mentre la request URI in una richiesta a un origin server è suddivisa nelle opzioni Uri-Host, Uri-Port, Uri-Path e Uri-Query (vedere la Sezione 5.10.1). In alternativa, l'URI in una richiesta proxy può essere assemblata da un'opzione Proxy-Scheme e dalle opzioni suddivise menzionate.

Quando una richiesta proxy è effettuata a un endpoint e l'endpoint non è disposto o non è in grado di agire come proxy per la request URI, deve restituire una risposta 5.05 (Proxying Not Supported) (MUST). Se l'authority (host e port) è riconosciuta come identificante l'endpoint proxy stesso (vedere la Sezione 5.10.2), allora la richiesta deve essere trattata come una richiesta locale (non-proxied) (MUST).

A meno che un proxy non sia configurato per inoltrare la richiesta proxy a un altro proxy, deve tradurre la richiesta come segue: lo scheme della request URI definisce il protocollo in uscita e i suoi dettagli (ad esempio, CoAP è utilizzato su UDP per lo scheme "coap" e su DTLS per lo scheme "coaps"). Per un proxy CoAP-to-CoAP, l'indirizzo IP e la port dell'origin server sono determinati dalla componente authority della request URI, e la request URI è decodificata e suddivisa nelle opzioni Uri-Host, Uri-Port, Uri-Path e Uri-Query. Questo consuma l'opzione Proxy-Uri o Proxy-Scheme, che pertanto non viene inoltrata all'origin server.

5.7.3. Reverse-Proxy​

I reverse-proxy non fanno uso delle opzioni Proxy-Uri o Proxy-Scheme ma devono determinare la destinazione (next hop) di una richiesta dalle informazioni nella richiesta e dalle informazioni nella loro configurazione. Ad esempio, un reverse-proxy potrebbe offrire varie risorse come se fossero le proprie risorse, dopo aver appreso della loro esistenza tramite resource discovery. Il reverse-proxy è libero di costruire un namespace per gli URI che identificano queste risorse. Un reverse-proxy può anche costruire un namespace che dia al client un maggiore controllo su dove va la richiesta, ad esempio incorporando identificatori di host e numeri di port nel percorso URI delle risorse offerte.

Nell'elaborazione della risposta, un reverse-proxy deve fare attenzione che i valori dell'opzione ETag provenienti da fonti diverse non vengano confusi su una risorsa offerta ai suoi client. In molti casi, l'ETag può essere inoltrato senza modifiche. Se la mappatura da una risorsa offerta dal reverse-proxy alle risorse offerte dai suoi vari origin server non è univoca, il reverse-proxy potrebbe dover generare un nuovo ETag, assicurandosi che la semantica di questa opzione sia adeguatamente preservata.

5.8. Definizioni dei metodi​

In questa sezione, ciascun metodo è definito insieme al suo comportamento. Una richiesta con un Method Code non riconosciuto o non supportato deve generare una piggybacked response 4.05 (Method Not Allowed) (MUST).

5.8.1. GET​

Il metodo GET recupera una rappresentazione per le informazioni che attualmente corrispondono alla risorsa identificata dalla request URI. Se la richiesta include un'opzione Accept, questa indica il content-format preferito di una risposta. Se la richiesta include un'opzione ETag, il metodo GET richiede che tale ETag venga convalidato e che la rappresentazione venga trasferita solo se la convalida fallisce. In caso di successo, nella risposta dovrebbe essere presente un Response Code 2.05 (Content) o 2.03 (Valid) (SHOULD).

Il metodo GET è safe e idempotent.

5.8.2. POST​

Il metodo POST richiede che la rappresentazione racchiusa nella richiesta venga elaborata. La funzione effettiva eseguita dal metodo POST è determinata dall'origin server e dipende dalla target resource. Di solito comporta la creazione di una nuova risorsa o l'aggiornamento della target resource.

Se una risorsa è stata creata sul server, la risposta restituita dal server dovrebbe avere un Response Code 2.01 (Created) e dovrebbe includere l'URI della nuova risorsa in una sequenza di una o più opzioni Location-Path e/o Location-Query (Sezione 5.10.7) (SHOULD). Se il POST riesce ma non comporta la creazione di una nuova risorsa sul server, la risposta dovrebbe avere un Response Code 2.04 (Changed) (SHOULD). Se il POST riesce e comporta l'eliminazione della target resource, la risposta dovrebbe avere un Response Code 2.02 (Deleted) (SHOULD). POST non è né safe né idempotent.

5.8.3. PUT​

Il metodo PUT richiede che la risorsa identificata dalla request URI venga aggiornata o creata con la rappresentazione racchiusa. Il formato della rappresentazione è specificato dal media type e dal content coding indicati nell'opzione Content-Format, se fornita.

Se una risorsa esiste presso la request URI, la rappresentazione racchiusa dovrebbe essere considerata una versione modificata di tale risorsa, e dovrebbe essere restituito un Response Code 2.04 (Changed) (SHOULD). Se non esiste alcuna risorsa, allora il server può creare una nuova risorsa con quella URI, ottenendo un Response Code 2.01 (Created) (MAY). Se la risorsa non può essere creata o modificata, allora dovrebbe essere inviato un Response Code di errore appropriato (SHOULD).

Ulteriori restrizioni a un PUT possono essere apportate includendo le opzioni If-Match (vedere la Sezione 5.10.8.1) o If-None-Match (vedere la Sezione 5.10.8.2) nella richiesta.

PUT non è safe ma è idempotent.

5.8.4. DELETE​

Il metodo DELETE richiede che la risorsa identificata dalla request URI venga eliminata. Un Response Code 2.02 (Deleted) dovrebbe essere utilizzato in caso di successo o nel caso in cui la risorsa non esistesse prima della richiesta (SHOULD).

DELETE non è safe ma è idempotent.

5.9. Definizioni dei codici di risposta​

Ogni Response Code è descritto di seguito, incluse le eventuali opzioni richieste nella risposta. Ove appropriato, alcuni dei code saranno specificati in relazione ai Response Code correlati in HTTP [RFC2616]; ciò non significa che tale relazione modifichi la mappatura HTTP specificata nella Sezione 10.

5.9.1. Successo 2.xx​

Questa classe di Response Code indica che la richiesta del client è stata ricevuta, compresa e accettata con successo.

5.9.1.1. 2.01 Created​

Come HTTP 201 "Created", ma utilizzato solo in risposta a richieste POST e PUT. Il payload restituito con la risposta, se presente, è una rappresentazione dell'action result.

Se la risposta include una o più opzioni Location-Path e/o Location-Query, i valori di queste opzioni specificano la posizione in cui la risorsa è stata creata. In caso contrario, la risorsa è stata creata presso la request URI. Una cache che riceve questa risposta deve contrassegnare come non fresh qualsiasi risposta memorizzata per la risorsa creata (MUST).

Questa risposta non è memorizzabile in cache.

5.9.1.2. 2.02 Deleted​

Questo Response Code è come HTTP 204 "No Content" ma utilizzato solo in risposta a richieste che fanno cessare la disponibilità della risorsa, come DELETE e, in determinate circostanze, POST. Il payload restituito con la risposta, se presente, è una rappresentazione dell'action result.

Questa risposta non è memorizzabile in cache. Tuttavia, una cache deve contrassegnare come non fresh qualsiasi risposta memorizzata per la risorsa eliminata (MUST).

5.9.1.3. 2.03 Valid​

Questo Response Code è correlato a HTTP 304 "Not Modified" ma utilizzato solo per indicare che la risposta identificata dall'entity-tag identificato dall'opzione ETag inclusa è valida. Di conseguenza, la risposta deve includere un'opzione ETag (MUST) e non deve includere un payload (MUST NOT).

Quando una cache che riconosce ed elabora l'opzione di risposta ETag riceve una risposta 2.03 (Valid), deve aggiornare la risposta memorizzata con il valore dell'opzione Max-Age inclusa nella risposta (esplicitamente, o implicitamente come valore predefinito; vedere anche la Sezione 5.6.2) (MUST). Per ciascun tipo di opzione Safe-to-Forward presente nella risposta, l'insieme (possibilmente vuoto) di opzioni di questo tipo presenti nella risposta memorizzata deve essere sostituito con l'insieme di opzioni di questo tipo nella risposta ricevuta (MUST). (Le opzioni Unsafe possono attivare un'elaborazione simile specifica dell'opzione, come definito dall'opzione.)

5.9.1.4. 2.04 Changed​

Questo Response Code è come HTTP 204 "No Content" ma utilizzato solo in risposta a richieste POST e PUT. Il payload restituito con la risposta, se presente, è una rappresentazione dell'action result.

Questa risposta non è memorizzabile in cache. Tuttavia, una cache deve contrassegnare come non fresh qualsiasi risposta memorizzata per la risorsa modificata (MUST).

5.9.1.5. 2.05 Content​

Questo Response Code è come HTTP 200 "OK" ma utilizzato solo in risposta a richieste GET.

Il payload restituito con la risposta è una rappresentazione della target resource.

Questa risposta è memorizzabile in cache: le cache possono utilizzare l'opzione Max-Age per determinare la freshness (vedere la Sezione 5.6.1) e (se presente) l'opzione ETag per la convalida (vedere la Sezione 5.6.2).

5.9.2. Errore client 4.xx​

Questa classe di Response Code è destinata ai casi in cui il client sembra aver commesso un errore. Questi Response Code sono applicabili a qualsiasi metodo di richiesta.

Il server dovrebbe includere un payload diagnostico alle condizioni dettagliate nella Sezione 5.5.2 (SHOULD).

Le risposte di questa classe sono memorizzabili in cache: le cache possono utilizzare l'opzione Max-Age per determinare la freshness (vedere la Sezione 5.6.1). Non possono essere convalidate.

5.9.2.1. 4.00 Bad Request​

Questo Response Code è come HTTP 400 "Bad Request".

5.9.2.2. 4.01 Unauthorized​

Il client non è autorizzato a eseguire l'azione richiesta. Il client non dovrebbe ripetere la richiesta senza prima migliorare il proprio stato di autenticazione verso il server (SHOULD NOT). Quale meccanismo specifico possa essere utilizzato a questo scopo è al di fuori dell'ambito di questo documento; vedere anche la Sezione 9.

5.9.2.3. 4.02 Bad Option​

La richiesta non ha potuto essere compresa dal server a causa di una o più opzioni non riconosciute o malformate. Il client non dovrebbe ripetere la richiesta senza modifiche (SHOULD NOT).

5.9.2.4. 4.03 Forbidden​

Questo Response Code è come HTTP 403 "Forbidden".

5.9.2.5. 4.04 Not Found​

Questo Response Code è come HTTP 404 "Not Found".

5.9.2.6. 4.05 Method Not Allowed​

Questo Response Code è come HTTP 405 "Method Not Allowed" ma senza alcun parallelo con il campo di intestazione "Allow".

5.9.2.7. 4.06 Not Acceptable​

Questo Response Code è come HTTP 406 "Not Acceptable", ma senza response entity.

5.9.2.8. 4.12 Precondition Failed​

Questo Response Code è come HTTP 412 "Precondition Failed".

5.9.2.9. 4.13 Request Entity Too Large​

Questo Response Code è come HTTP 413 "Request Entity Too Large".

La risposta dovrebbe includere un'opzione Size1 (Sezione 5.10.9) per indicare la dimensione massima dell'entity di richiesta che il server è in grado e disposto a gestire, a meno che il server non sia nella posizione di rendere disponibile questa informazione (SHOULD).

5.9.2.10. 4.15 Unsupported Content-Format​

Questo Response Code è come HTTP 415 "Unsupported Media Type".

5.9.3. Errore server 5.xx​

Questa classe di Response Code indica i casi in cui il server è consapevole di aver commesso un errore o è incapace di eseguire la richiesta. Questi Response Code sono applicabili a qualsiasi metodo di richiesta.

Il server dovrebbe includere un payload diagnostico alle condizioni dettagliate nella Sezione 5.5.2 (SHOULD).

Le risposte di questa classe sono memorizzabili in cache: le cache possono utilizzare l'opzione Max-Age per determinare la freshness (vedere la Sezione 5.6.1). Non possono essere convalidate.

5.9.3.1. 5.00 Internal Server Error​

Questo Response Code è come HTTP 500 "Internal Server Error".

5.9.3.2. 5.01 Not Implemented​

Questo Response Code è come HTTP 501 "Not Implemented".

5.9.3.3. 5.02 Bad Gateway​

Questo Response Code è come HTTP 502 "Bad Gateway".

5.9.3.4. 5.03 Service Unavailable​

Questo Response Code è come HTTP 503 "Service Unavailable" ma utilizza l'opzione Max-Age al posto del campo di intestazione "Retry-After" per indicare il numero di secondi dopo i quali riprovare.

5.9.3.5. 5.04 Gateway Timeout​

Questo Response Code è come HTTP 504 "Gateway Timeout".

5.9.3.6. 5.05 Proxying Not Supported​

Il server non è in grado o non è disposto ad agire come forward-proxy per l'URI specificato nell'opzione Proxy-Uri o utilizzando Proxy-Scheme (vedere la Sezione 5.10.2).

5.10. Definizioni delle opzioni​

Le singole opzioni CoAP sono riepilogate nella Tabella 4 e spiegate nelle sottosezioni di questa sezione.

In questa tabella, le colonne C, U e N indicano rispettivamente le proprietà Critical, UnSafe e NoCacheKey. Poiché NoCacheKey ha significato solo per le opzioni che sono Safe-to-Forward (non contrassegnate come Unsafe), la colonna è riempita con un trattino per le opzioni UnSafe.

No.CUNRNameFormatLengthDefault
1xxIf-Matchopaque0-8(none)
3xx-Uri-Hoststring1-255(see
below)
4xETagopaque1-8(none)
5xIf-None-Matchempty0(none)
7xx-Uri-Portuint0-2(see
below)
8xLocation-Pathstring0-255(none)
11xx-xUri-Pathstring0-255(none)
12Content-Formatuint0-2(none)
14x-Max-Ageuint0-460
15xx-xUri-Querystring0-255(none)
17xAcceptuint0-2(none)
20xLocation-Querystring0-255(none)
35xx-Proxy-Uristring1-1034(none)
39xx-Proxy-Schemestring1-255(none)
60xSize1uint0-4(none)

C=Critical, U=Unsafe, N=NoCacheKey, R=Repeatable

Tabella 4: Opzioni

5.10.1. Uri-Host, Uri-Port, Uri-Path e Uri-Query​

Le opzioni Uri-Host, Uri-Port, Uri-Path e Uri-Query sono utilizzate per specificare la target resource di una richiesta a un origin server CoAP. Le opzioni codificano le diverse componenti della request URI in modo tale che nessun percent-encoding sia visibile nei valori delle opzioni e che l'URI completa possa essere ricostruita presso qualsiasi endpoint coinvolto. La sintassi degli URI CoAP è definita nella Sezione 6.

I passaggi per analizzare gli URI in opzioni sono definiti nella Sezione 6.4. Questi passaggi comportano l'inclusione nella richiesta di zero o più opzioni Uri-Host, Uri-Port, Uri-Path e Uri-Query, dove ciascuna opzione contiene i seguenti valori:

  • l'opzione Uri-Host specifica l'Internet host della risorsa richiesta,

  • l'opzione Uri-Port specifica il numero di port del livello di trasporto della risorsa,

  • ciascuna opzione Uri-Path specifica un segmento del percorso assoluto verso la risorsa, e

  • ciascuna opzione Uri-Query specifica un argomento che parametrizza la risorsa.

Nota: i Fragment ([RFC3986], Sezione 3.5) non fanno parte della request URI e pertanto non saranno trasmessi in una richiesta CoAP.

Il valore predefinito dell'opzione Uri-Host è l'IP literal che rappresenta l'indirizzo IP di destinazione del messaggio di richiesta. Analogamente, il valore predefinito dell'opzione Uri-Port è la port UDP di destinazione. I valori predefiniti per le opzioni Uri-Host e Uri-Port sono sufficienti per le richieste alla maggior parte dei server. Le opzioni Uri-Host e Uri-Port esplicite sono tipicamente utilizzate quando un endpoint ospita più virtual server.

L'opzione Uri-Path e Uri-Query può contenere qualsiasi sequenza di caratteri. Non viene eseguito alcun percent-encoding. Il valore di un'opzione Uri-Path non deve essere "." o ".." (poiché la request URI deve essere risolta prima di analizzarla in opzioni) (MUST NOT).

I passaggi per costruire la request URI dalle opzioni sono definiti nella Sezione 6.5. Si noti che un'implementazione non deve necessariamente costruire l'URI; può semplicemente cercare la target resource esaminando le singole opzioni.

Esempi possono essere trovati nell'Appendice B.

5.10.2. Proxy-Uri e Proxy-Scheme​

L'opzione Proxy-Uri è utilizzata per effettuare una richiesta a un forward-proxy (vedere la Sezione 5.7). Al forward-proxy è richiesto di inoltrare la richiesta oppure di servirla da una cache valida e restituire la risposta.

Il valore dell'opzione è un absolute-URI ([RFC3986], Sezione 4.3).

Si noti che il forward-proxy può inoltrare la richiesta a un altro proxy o direttamente al server specificato dall'absolute-URI (MAY). Al fine di evitare loop di richieste, un proxy deve essere in grado di riconoscere tutti i propri server name, inclusi eventuali alias, varianti locali e indirizzi IP numerici (MUST).

Un endpoint che riceve una richiesta con un'opzione Proxy-Uri e che non è in grado o non è disposto ad agire come forward-proxy per la richiesta deve causare la restituzione di una risposta 5.05 (Proxying Not Supported) (MUST).

L'opzione Proxy-Uri deve avere la precedenza su qualsiasi opzione Uri-Host, Uri-Port, Uri-Path o Uri-Query (ciascuna delle quali non deve essere inclusa in una richiesta contenente l'opzione Proxy-Uri) (MUST, MUST NOT).

Come caso speciale per semplificare molti client proxy, l'absolute-URI può essere costruita dalle opzioni Uri-. Quando è presente un'opzione Proxy-Scheme, l'absolute-URI è costruita come segue: si costruisce un URI CoAP dalle opzioni Uri- come definito nella Sezione 6.5. Nell'URI risultante, lo scheme iniziale fino a, ma non incluso, i due punti successivi viene quindi sostituito con il contenuto dell'opzione Proxy-Scheme. Si noti che questo caso è applicabile solo se le componenti dell'URI desiderata diverse dalla componente scheme possono effettivamente essere espresse utilizzando le opzioni Uri-*; ad esempio, per rappresentare un URI con una componente userinfo nell'authority, è possibile utilizzare solo Proxy-Uri.

5.10.3. Content-Format​

L'opzione Content-Format indica il formato di rappresentazione del payload del messaggio. Il formato di rappresentazione è fornito come identificatore numerico Content-Format definito nel registro "CoAP Content-Formats" (Sezione 12.3). In assenza dell'opzione, non si assume alcun valore predefinito, cioè il formato di rappresentazione di qualsiasi payload di messaggio di rappresentazione è indeterminato (Sezione 5.5).

5.10.4. Accept​

L'opzione CoAP Accept può essere utilizzata per indicare quale Content-Format è accettabile per il client. Il formato di rappresentazione è fornito come identificatore numerico Content-Format definito nel registro "CoAP Content-Formats" (Sezione 12.3). Se non viene fornita alcuna opzione Accept, il client non esprime una preferenza (pertanto non si assume alcun valore predefinito). Il client preferisce che la rappresentazione restituita dal server sia nel Content-Format indicato. Il server restituisce il Content-Format preferito se disponibile. Se il Content-Format preferito non può essere restituito, allora deve essere inviato un 4.06 "Not Acceptable" come risposta, a meno che un altro error code abbia la precedenza per questa risposta (MUST).

5.10.5. Max-Age​

L'opzione Max-Age indica il tempo massimo per cui una risposta può essere memorizzata in cache prima di essere considerata non fresh (vedere la Sezione 5.6.1).

Il valore dell'opzione è un numero intero di secondi compreso tra 0 e 2**32-1 inclusi (circa 136,1 anni). In assenza dell'opzione in una risposta, si assume un valore predefinito di 60 secondi.

Il valore è inteso come corrente al momento della trasmissione. I server che forniscono risorse con tolleranze rigorose sul valore di Max-Age dovrebbero aggiornare il valore prima di ogni ritrasmissione (SHOULD). (Vedere anche la Sezione 5.7.1.)

5.10.6. ETag​

Un entity-tag è destinato all'uso come identificatore locale alla risorsa per differenziare tra rappresentazioni della stessa risorsa che variano nel tempo. È generato dal server che fornisce la risorsa, il quale può generarlo in qualsiasi numero di modi, inclusi una version, un checksum, un hash o un tempo. Un endpoint che riceve un entity-tag deve trattarlo come opaco e non deve fare alcuna assunzione sul suo contenuto o sulla sua struttura (MUST). (Gli endpoint che generano un entity-tag sono incoraggiati a utilizzare la rappresentazione più compatta possibile, in particolare per quanto riguarda i client e gli intermediari che potrebbero voler memorizzare più valori ETag.)

5.10.6.1. ETag come opzione di risposta​

L'opzione ETag in una risposta fornisce il valore corrente (cioè dopo che la richiesta è stata elaborata) dell'entity-tag per la "tagged representation". Se non sono presenti opzioni Location-, la tagged representation è la selected representation (Sezione 5.5.3) della target resource. Se sono presenti una o più opzioni Location- e quindi è indicata una location URI (Sezione 5.10.7), la tagged representation è la rappresentazione che sarebbe recuperata da una richiesta GET alla location URI.

Un'opzione di risposta ETag può essere inclusa con qualsiasi risposta per cui esista una tagged representation (ad esempio, non avrebbe senso in una risposta 4.04 o 4.00). L'opzione ETag non deve comparire più di una volta in una risposta (MUST NOT).

Non esiste un valore predefinito per l'opzione ETag; se non è presente in una risposta, il server non fa alcuna dichiarazione sull'entity-tag per la tagged representation.

5.10.6.2. ETag come opzione di richiesta​

In una richiesta GET, un endpoint che ha una o più rappresentazioni precedentemente ottenute dalla risorsa, e ha ottenuto con esse le opzioni di risposta ETag, può specificare un'istanza dell'opzione ETag per una o più di queste risposte memorizzate.

Un server può emettere una risposta 2.03 Valid (Sezione 5.9.1.3) al posto di una risposta 2.05 Content se uno degli ETag forniti è l'entity-tag per la rappresentazione corrente, cioè è valido; la risposta 2.03 Valid riecheggia quindi questo specifico ETag in un'opzione di risposta.

In effetti, un client può determinare se una qualsiasi delle rappresentazioni memorizzate è corrente (vedere la Sezione 5.6.2) senza doverle trasferire di nuovo.

L'opzione ETag può comparire zero, una o più volte in una richiesta (MAY).

5.10.7. Location-Path e Location-Query​

Le opzioni Location-Path e Location-Query indicano insieme un URI relativo che consiste in un percorso assoluto, una query string o entrambi. Una combinazione di queste opzioni è inclusa in una risposta 2.01 (Created) per indicare la posizione della risorsa creata come risultato di una richiesta POST (vedere la Sezione 5.8.2). La posizione è risolta relativamente alla request URI.

Se una risposta con una o più opzioni Location-Path e/o Location-Query passa attraverso una cache che interpreta queste opzioni e l'URI implicita identifica una o più risposte attualmente memorizzate, tali voci devono essere contrassegnate come non fresh (MUST).

Ciascuna opzione Location-Path specifica un segmento del percorso assoluto verso la risorsa, e ciascuna opzione Location-Query specifica un argomento che parametrizza la risorsa. L'opzione Location-Path e Location-Query può contenere qualsiasi sequenza di caratteri. Non viene eseguito alcun percent-encoding. Il valore di un'opzione Location-Path non deve essere "." o ".." (MUST NOT).

I passaggi per costruire la location URI dalle opzioni sono analoghi alla Sezione 6.5, salvo che i primi cinque passaggi vengono saltati e il risultato è un relative URI-reference, che viene poi interpretato relativamente alla request URI. Si noti che il relative URI-reference costruito in questo modo include sempre un percorso assoluto (ad esempio, omettere Location-Path ma fornire Location-Query significa che la componente path nell'URI è "/").

Le opzioni utilizzate per calcolare il relative URI-reference sono collettivamente chiamate opzioni Location-. Oltre a Location-Path e Location-Query, in futuro potrebbero essere definite altre opzioni Location- e sono stati riservati i numeri di opzione 128, 132, 136 e 140. Se uno qualsiasi di questi numeri di opzione riservati si verifica in aggiunta a Location-Path e/o Location-Query e non è supportato, allora deve essere restituito un errore 4.02 (Bad Option) (MUST).

5.10.8. Opzioni di richiesta condizionali​

Le opzioni di richiesta condizionali consentono a un client di chiedere al server di eseguire la richiesta solo se determinate condizioni specificate dall'opzione sono soddisfatte.

Per ciascuna di queste opzioni, se la condizione data non è soddisfatta, allora il server non deve eseguire il metodo richiesto (MUST NOT). Invece, il server deve rispondere con il Response Code 4.12 (Precondition Failed) (MUST).

Se la condizione è soddisfatta, il server esegue il metodo di richiesta come se le opzioni di richiesta condizionali non fossero presenti.

Se la richiesta, senza le opzioni di richiesta condizionali, produrrebbe un risultato diverso da un Response Code 2.xx o 4.12, allora qualsiasi opzione di richiesta condizionale può essere ignorata (MAY).

5.10.8.1. If-Match​

L'opzione If-Match può essere utilizzata per rendere una richiesta condizionata all'esistenza o al valore corrente di un ETag per una o più rappresentazioni della target resource (MAY). If-Match è generalmente utile per le richieste di aggiornamento delle risorse, come le richieste PUT, come mezzo per proteggersi da sovrascritture accidentali quando più client agiscono in parallelo sulla stessa risorsa (cioè il problema del "lost update").

Il valore di un'opzione If-Match è un ETag oppure la stringa vuota. Un'opzione If-Match con un ETag corrisponde a una rappresentazione con esattamente quell'ETag. Un'opzione If-Match con un valore vuoto corrisponde a qualsiasi rappresentazione esistente (cioè pone la precondizione sull'esistenza di qualsiasi rappresentazione corrente per la target resource).

L'opzione If-Match può comparire più volte. Se una qualsiasi delle opzioni corrisponde, allora la condizione è soddisfatta.

Se vi è una o più opzioni If-Match, ma nessuna delle opzioni corrisponde, allora la condizione non è soddisfatta.

5.10.8.2. If-None-Match​

L'opzione If-None-Match può essere utilizzata per rendere una richiesta condizionata alla non esistenza della target resource (MAY). If-None-Match è utile per le richieste di creazione di risorse, come le richieste PUT, come mezzo per proteggersi da sovrascritture accidentali quando più client agiscono in parallelo sulla stessa risorsa. L'opzione If-None-Match non trasporta alcun valore.

Se la target resource esiste, allora la condizione non è soddisfatta.

(Non è molto utile combinare le opzioni If-Match e If-None-Match in una sola richiesta, perché allora la condizione non sarà mai soddisfatta.)

5.10.9. Opzione Size1​

L'opzione Size1 fornisce informazioni sulla dimensione della rappresentazione della risorsa in una richiesta. Il valore dell'opzione è un numero intero di byte. Il suo uso principale è con i block-wise transfer [BLOCK]. Nella presente specifica, è utilizzata nelle risposte 4.13 (Sezione 5.9.2.9) per indicare la dimensione massima dell'entity di richiesta che il server è in grado e disposto a gestire.