5. Sémantique requête/réponse
CoAP fonctionne selon un modèle requête/réponse similaire à celui de HTTP : un point de terminaison CoAP dans le rôle de "client" envoie une ou plusieurs requêtes CoAP à un "serveur", qui traite ces requêtes en envoyant des réponses CoAP. Contrairement à HTTP, les requêtes et les réponses ne sont pas envoyées sur une connexion préalablement établie, mais sont échangées de manière asynchrone au moyen de messages CoAP.
5.1. Requêtes
Une requête CoAP est constituée de la méthode à appliquer à la ressource, de l'identifiant de la ressource, d'un payload et d'un type de média Internet (le cas échéant), ainsi que de métadonnées facultatives concernant la requête.
CoAP prend en charge les méthodes de base GET, POST, PUT et DELETE, qui se transposent facilement en HTTP. Elles possèdent les mêmes propriétés de sûreté (safe, c'est-à-dire uniquement une récupération) et d'idempotence (idempotent, c'est-à-dire que l'on peut l'invoquer plusieurs fois avec les mêmes effets) que HTTP (voir la section 9.1 de [RFC2616]). La méthode GET est sûre (safe) ; par conséquent, elle ne doit entreprendre aucune autre action sur une ressource que la récupération (MUST NOT). Les méthodes GET, PUT et DELETE doivent être exécutées de manière à être idempotentes (MUST). POST n'est pas idempotente, car son effet est déterminé par le serveur d'origine et dépend de la ressource cible ; elle aboutit généralement à la création d'une nouvelle ressource ou à la mise à jour de la ressource cible.
Une requête est initiée en affectant au champ Code de l'en-tête CoAP d'un message Confirmable ou Non-confirmable une valeur de Method Code et en incluant les informations de la requête.
Les méthodes utilisées dans les requêtes sont décrites en détail à la section 5.8.
5.2. Réponses
Après avoir reçu et interprété une requête, un serveur répond par une réponse CoAP qui est mise en correspondance avec la requête au moyen d'un Token généré par le client (section 5.3) ; notons que cela diffère du Message ID qui met en correspondance un message Confirmable avec son Acknowledgement.
Une réponse est identifiée par le champ Code de l'en-tête CoAP, qui est défini sur une valeur de Response Code. Comme pour le HTTP Status Code, le CoAP Response Code indique le résultat de la tentative de compréhension et de satisfaction de la requête. Ces codes sont définis de manière complète à la section 5.9. Les numéros de Response Code à définir dans le champ Code de l'en-tête CoAP sont maintenus dans le CoAP Response Code Registry (section 12.1.2).
0
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|class| detail |
+-+-+-+-+-+-+-+-+
Figure 9 : Structure d'un Response Code
Les trois bits de poids fort du numéro de Response Code sur 8 bits définissent la classe de la réponse. Les cinq bits de poids faible n'ont aucun rôle de catégorisation ; ils apportent un détail supplémentaire à la classe globale (Figure 9).
Comme notation lisible par l'homme pour les spécifications et les diagnostics de protocole, les numéros de code CoAP, y compris le Response Code, sont documentés au format "c.dd", où "c" est la classe en décimal et "dd" le détail sous forme de deux chiffres décimaux. Par exemple, "Forbidden" s'écrit 4.03 -- ce qui indique une valeur de code de 8 bits de 0x83 en hexadécimal (40x20+3) ou 131 en décimal (432+3).
Il existe 3 classes de Response Codes :
2 - Success : la requête a été reçue, comprise et acceptée avec succès.
4 - Client Error : la requête contient une syntaxe incorrecte ou ne peut pas être satisfaite.
5 - Server Error : le serveur n'a pas réussi à satisfaire une requête apparemment valide.
Les Response Codes sont conçus pour être extensibles : les Response Codes de la classe Client Error ou Server Error qui ne sont pas reconnus par un point de terminaison sont traités comme équivalents au Response Code générique de cette classe (4.00 et 5.00, respectivement). Cependant, il n'existe pas de Response Code générique indiquant le succès, de sorte qu'un Response Code de la classe Success qui n'est pas reconnu par un point de terminaison ne peut servir qu'à déterminer que la requête a réussi, sans plus de détails.
Les Response Codes possibles sont décrits en détail à la section 5.9.
Les réponses peuvent être envoyées de plusieurs manières, qui sont définies dans les sous-sections suivantes.
5.2.1. Piggybackée
Dans le cas le plus élémentaire, la réponse est transportée directement dans le message Acknowledgement qui accuse réception de la requête (ce qui exige que la requête ait été transportée dans un message Confirmable). C'est ce que l'on appelle une "Piggybacked Response".
La réponse est renvoyée dans le message Acknowledgement, indépendamment du fait qu'elle indique un succès ou un échec. En pratique, la réponse est piggybackée sur le message Acknowledgement, et aucun message distinct n'est nécessaire pour renvoyer la réponse.
Note d'implémentation : le protocole laisse au serveur la décision de piggybacker ou non une réponse (c'est-à-dire d'envoyer une réponse séparée). Le client doit être préparé à recevoir l'une ou l'autre (MUST). Au niveau de la qualité de mise en œuvre, il est fortement attendu que les serveurs implémentent le code permettant de piggybacker chaque fois que possible -- ce qui économise des ressources dans le réseau ainsi qu'au niveau du client et du serveur.
5.2.2. Séparée
Il peut ne pas être possible de renvoyer une réponse piggybackée dans tous les cas. Par exemple, un serveur peut avoir besoin de plus de temps pour obtenir la représentation de la ressource demandée qu'il ne peut attendre pour renvoyer le message Acknowledgement sans risquer que le client ne retransmette à plusieurs reprises le message de requête (voir aussi la discussion sur PROCESSING_DELAY à la section 4.8.2). La réponse à une requête transportée dans un message Non-confirmable est toujours envoyée séparément (puisqu'il n'y a pas de message Acknowledgement).
Une façon de mettre cela en œuvre dans un serveur consiste à lancer la tentative d'obtention de la représentation de la ressource et, pendant que celle-ci est en cours, à faire expirer un temporisateur d'accusé de réception. Un serveur peut également envoyer immédiatement un accusé de réception s'il sait à l'avance qu'il n'y aura pas de réponse piggybackée. Dans les deux cas, l'accusé de réception constitue effectivement une promesse que la requête sera traitée ultérieurement.
Lorsque le serveur a finalement obtenu la représentation de la ressource, il envoie la réponse. Lorsqu'il est souhaitable que ce message ne soit pas perdu, il est envoyé comme message Confirmable du serveur vers le client et acquitté par le client au moyen d'un Acknowledgement, reprenant le nouveau Message ID choisi par le serveur. (Il peut également être envoyé comme message Non-confirmable ; voir la section 5.2.3.)
Lorsque le serveur choisit d'utiliser une réponse séparée, il envoie l'Acknowledgement à la requête Confirmable sous forme de message Empty. Une fois que le serveur a renvoyé un Acknowledgement vide, il ne doit pas renvoyer la réponse dans un autre Acknowledgement, même si le client retransmet une autre requête identique (MUST NOT). Si une requête retransmise est reçue (peut-être parce que l'Acknowledgement initial a été retardé), un autre Acknowledgement vide est envoyé, et toute réponse doit être envoyée comme réponse séparée (MUST).
Si le serveur envoie ensuite une réponse Confirmable, l'Acknowledgement du client à cette réponse doit également être un message Empty (un message qui ne transporte ni requête ni réponse) (MUST). Le serveur doit cesser de retransmettre sa réponse dès réception de tout Acknowledgement correspondant (en ignorant silencieusement tout Response Code ou payload) ou de tout message Reset (MUST).
Notes d'implémentation : notons que, comme le transport de datagrammes sous-jacent peut ne pas préserver la séquence, le message Confirmable transportant la réponse peut en réalité arriver avant ou après le message Acknowledgement de la requête ; aux fins de terminaison de la séquence de retransmission, cela sert également d'accusé de réception. Notons aussi que, bien que le protocole CoAP lui-même n'impose rien de spécifique ici, il est attendu que la réponse arrive dans un délai raisonnable du point de vue de l'application. Comme il n'existe pas de protocole de transport sous-jacent qui pourrait être chargé d'exécuter un mécanisme de keep-alive, le demandeur peut souhaiter mettre en place un temporisateur sans rapport avec les temporisateurs de retransmission de CoAP, au cas où le serveur serait détruit ou autrement incapable d'envoyer la réponse.
5.2.3. Non confirmable
Si le message de requête est Non-confirmable, alors la réponse devrait également être renvoyée dans un message Non-confirmable (SHOULD). Cependant, un point de terminaison doit être préparé à recevoir une réponse Non-confirmable (précédée ou suivie d'un message Empty Acknowledgement) en réponse à une requête Confirmable, ou une réponse Confirmable en réponse à une requête Non-confirmable (MUST).
5.3. Correspondance requête/réponse
Quelle que soit la manière dont une réponse est envoyée, elle est mise en correspondance avec la requête au moyen d'un Token inclus par le client dans la requête, ainsi que d'informations d'adresse supplémentaires du point de terminaison correspondant.
5.3.1. Token
Le Token sert à mettre en correspondance une réponse avec une requête. La valeur du token est une séquence de 0 à 8 octets. (Notons que chaque message transporte un token, même s'il est de longueur nulle.) Chaque requête transporte un token généré par le client que le serveur doit reprendre tel quel (sans modification) dans toute réponse résultante (MUST).
Un token est destiné à être utilisé comme identifiant local au client pour distinguer des requêtes concurrentes (voir la section 5.3) ; il aurait pu être appelé "request ID".
Le client devrait générer des tokens de telle manière que les tokens actuellement utilisés pour une paire de points de terminaison source/destination donnée soient uniques (SHOULD). (Notons qu'une implémentation client peut utiliser le même token pour n'importe quelle requête si elle utilise un point de terminaison différent à chaque fois, par exemple un numéro de port source différent.) Une valeur de token vide est appropriée, par exemple, lorsqu'aucun autre token n'est utilisé vers une destination, ou lorsque les requêtes sont émises en série par destination et reçoivent des réponses piggybackées. Il existe toutefois de multiples stratégies de mise en œuvre possibles pour satisfaire cette exigence.
Un client qui envoie une requête sans utiliser la sécurité de la couche transport (Transport Layer Security, section 9) devrait utiliser un token non trivial et aléatoire pour se prémunir contre l'usurpation des réponses (spoofing) (section 11.4) (SHOULD). Cet usage protecteur des tokens est la raison pour laquelle leur taille peut atteindre 8 octets. La taille réelle de la composante aléatoire à utiliser pour le Token dépend des exigences de sécurité du client et du niveau de menace que représente l'usurpation des réponses. Un client connecté à l'Internet général devrait utiliser au moins 32 bits d'aléa, en gardant à l'esprit que le fait de ne pas être directement connecté à Internet ne constitue pas nécessairement une protection suffisante contre l'usurpation (SHOULD). (Notons que le Message ID n'apporte qu'une faible protection, car il est généralement attribué de manière séquentielle, donc devinable, et peut être contourné en usurpant une réponse séparée.) Les clients qui souhaitent optimiser la longueur du Token peuvent en outre vouloir détecter le niveau d'attaques en cours (par exemple en comptabilisant les récentes discordances de Token dans les messages entrants) et ajuster la longueur du Token à la hausse en conséquence. [RFC4086] traite des exigences d'aléa pour la sécurité.
Un point de terminaison qui reçoit un token qu'il n'a pas généré doit le traiter comme opaque et ne faire aucune supposition quant à son contenu ou sa structure (MUST).
5.3.2. Règles de correspondance requête/réponse
Les règles exactes de mise en correspondance d'une réponse avec une requête sont les suivantes :
-
Le point de terminaison source de la réponse doit être identique au point de terminaison de destination de la requête d'origine (MUST).
-
Dans une réponse piggybackée, le Message ID de la requête Confirmable et celui de l'Acknowledgement doivent correspondre, et les tokens de la réponse et de la requête d'origine doivent correspondre (MUST). Dans une réponse séparée, seuls les tokens de la réponse et de la requête d'origine doivent correspondre (MUST).
Dans le cas où un message transportant une réponse est inattendu (le client n'attend pas de réponse du point de terminaison identifié, à l'adresse pointée et/ou avec le token donné), la réponse est rejetée (sections 4.2 et 4.3).
Note d'implémentation : un client qui reçoit une réponse dans un message CON peut vouloir nettoyer l'état du message juste après avoir envoyé l'ACK. Si cet ACK est perdu et que le serveur retransmet le CON, le client peut ne plus avoir d'état auquel corréler cette réponse, ce qui fait de la retransmission un message inattendu ; le client enverra probablement un message Reset afin de ne plus recevoir de retransmissions. Ce comportement est normal et n'indique pas une erreur. (Les clients qui ne sont pas agressivement optimisés dans leur utilisation de la mémoire d'état conserveront encore un état de message qui identifiera le second CON comme une retransmission. Les clients qui attendent réellement davantage de messages du serveur [OBSERVE] devront conserver l'état dans tous les cas.)
5.4. Options
Les requêtes et les réponses peuvent toutes deux inclure une liste d'une ou plusieurs options. Par exemple, l'URI d'une requête est transportée dans plusieurs options, et les métadonnées qui seraient transportées dans un en-tête HTTP en HTTP sont également fournies sous forme d'options.
CoAP définit un ensemble unique d'options utilisées à la fois dans les requêtes et les réponses :
-
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 sémantique de ces options, ainsi que leurs propriétés, est définie en détail à la section 5.10.
Toutes les options ne sont pas définies pour être utilisées avec toutes les méthodes et tous les Response Codes. Les options possibles pour les méthodes et les Response Codes sont définies aux sections 5.8 et 5.9, respectivement. Dans le cas où une option n'est pas définie pour une Method ou un Response Code, elle ne doit pas être incluse par un émetteur (MUST NOT) et doit être traitée comme une option non reconnue par un destinataire (MUST).
5.4.1. Critique/Élective
Les options se répartissent en deux classes : "critical" ou "elective". La différence entre elles réside dans la manière dont une option non reconnue par un point de terminaison est traitée :
-
À la réception, les options non reconnues de la classe "elective" doivent être silencieusement ignorées (MUST).
-
Les options non reconnues de la classe "critical" qui apparaissent dans une requête Confirmable doivent provoquer le renvoi d'une réponse 4.02 (Bad Option) (MUST). Cette réponse devrait inclure un payload de diagnostic décrivant la ou les options non reconnues (voir la section 5.5.2) (SHOULD).
-
Les options non reconnues de la classe "critical" qui apparaissent dans une réponse Confirmable, ou piggybackées dans un Acknowledgement, doivent provoquer le rejet de la réponse (section 4.2) (MUST).
-
Les options non reconnues de la classe "critical" qui apparaissent dans un message Non-confirmable doivent provoquer le rejet du message (section 4.3) (MUST).
Notons que, qu'elle soit critique ou élective, une option n'est jamais "obligatoire" (elle est toujours facultative) : ces règles sont définies afin de permettre aux implémentations d'arrêter le traitement des options qu'elles ne comprennent pas ou n'implémentent pas.
Les règles critique/élective s'appliquent aux points de terminaison non-proxy. Un proxy traite les options en fonction des classes Unsafe/Safe-to-Forward telles que définies à la section 5.7.
5.4.2. Proxy Unsafe ou Safe-to-Forward et NoCacheKey
Outre le fait qu'une option soit marquée comme critique ou élective, les options sont également classées selon la manière dont un proxy doit traiter l'option s'il ne la reconnaît pas. À cette fin, une option peut soit être considérée comme Unsafe à transférer (UnSafe est défini), soit comme Safe-to-Forward (UnSafe est à zéro).
De plus, pour une option marquée Safe-to-Forward, le numéro d'option indique si elle est destinée ou non à faire partie de la Cache-Key (section 5.6) dans une requête. Si certains des bits NoCacheKey sont à 0, elle en fait partie ; si tous les bits NoCacheKey sont à 1, elle n'en fait pas partie (voir la section 5.4.6).
Note : L'indication Cache-Key n'est pertinente que pour les proxys qui n'implémentent pas l'option donnée comme option de requête et se fient uniquement à l'indication Unsafe/Safe-to-Forward. Par exemple, pour ETag, utiliser réellement l'option de requête comme partie de la Cache-Key est grossièrement inefficace, mais c'est la meilleure chose à faire si ETag n'est pas implémenté par un proxy, car la réponse va différer selon la présence de l'option de requête. Un proxy plus utile qui implémente effectivement l'option de requête ETag n'utilise pas ETag comme partie de la Cache-Key.
NoCacheKey est indiqué sur trois bits afin qu'un seul point de code sur huit soit qualifié de NoCacheKey, laissant sept points de code sur huit pour ce qui semble être le cas le plus probable.
Le comportement des proxys vis-à-vis de ces classes est défini à la section 5.7.
5.4.3. Longueur
Les valeurs d'option sont définies comme ayant une longueur spécifique, souvent sous la forme d'une borne supérieure et inférieure. Si la longueur d'une valeur d'option dans une requête est en dehors de la plage définie, cette option doit être traitée comme une option non reconnue (voir la section 5.4.1) (MUST).
5.4.4. Valeurs par défaut
Les options peuvent être définies comme ayant une valeur par défaut. Si la valeur d'une option est censée être cette valeur par défaut, l'option ne devrait pas être incluse dans le message (SHOULD NOT). Si l'option n'est pas présente, la valeur par défaut doit être supposée (MUST).
Lorsqu'une option critique a une valeur par défaut, celle-ci est choisie de telle manière que l'absence de l'option dans un message puisse être traitée correctement à la fois par les implémentations qui ne connaissent pas l'option critique et par celles qui interprètent cette absence comme la présence de la valeur par défaut de l'option.
5.4.5. Options répétables
La définition de certaines options précise que ces options sont répétables. Une option qui est répétable peut être incluse une ou plusieurs fois dans un message (MAY). Une option qui n'est pas répétable ne doit pas être incluse plus d'une fois dans un message (MUST NOT).
Si un message inclut une option avec plus d'occurrences que ce pour quoi l'option est définie, chaque occurrence superflue de l'option qui apparaît ensuite dans le message doit être traitée comme une option non reconnue (voir la section 5.4.1) (MUST).
5.4.6. Numéros d'option
Une option est identifiée par un numéro d'option, qui fournit également quelques informations sémantiques supplémentaires, par exemple : les numéros impairs indiquent une option critique, tandis que les numéros pairs indiquent une option élective. Notons qu'il ne s'agit pas simplement d'une convention, c'est une caractéristique du protocole : le fait qu'une option soit élective ou critique est entièrement déterminé par le caractère pair ou impair de son numéro d'option.
Plus généralement, un numéro d'option est construit avec un masque de bits pour indiquer si une option est Critical ou Elective, Unsafe ou Safe-to-Forward et, dans le cas de Safe-to-Forward, pour fournir une indication Cache-Key, comme le montre la figure suivante. Dans le texte qui suit, le masque de bits est exprimé sous la forme d'un seul octet appliqué à l'octet de poids faible du numéro d'option en représentation d'entier non signé. Lorsque le bit 7 (le bit de poids faible) vaut 1, une option est Critical (et inversement Elective lorsqu'il vaut 0). Lorsque le bit 6 vaut 1, une option est Unsafe (et inversement Safe-to-Forward lorsqu'il vaut 0). Lorsque le bit 6 vaut 0, c'est-à-dire que l'option n'est pas Unsafe, elle n'est pas une Cache-Key (NoCacheKey) si et seulement si les bits 3 à 5 sont tous à 1 ; toutes les autres combinaisons de bits signifient qu'elle est bien une Cache-Key. Ces classes d'options sont expliquées dans les sections suivantes.
0 1 2 3 4 5 6 7
+---+---+---+---+---+---+---+---+
| | NoCacheKey| U | C |
+---+---+---+---+---+---+---+---+
Figure 10 : Masque de numéro d'option (octet de poids faible)
Un point de terminaison peut utiliser un équivalent du code C de la Figure 11 pour dériver les caractéristiques d'un numéro d'option "onum".
Critical = (onum & 1);
UnSafe = (onum & 2);
NoCacheKey = ((onum & 0x1e) == 0x1c);
Figure 11 : Détermination des caractéristiques à partir d'un numéro d'option
Les numéros d'option des options définies dans le présent document sont répertoriés dans le registre "CoAP Option Numbers" (section 12.2).
5.5. Charges utiles et représentations
Les requêtes et les réponses peuvent toutes deux inclure un payload, selon la Method ou le Response Code, respectivement. Si une Method ou un Response Code n'est pas défini comme ayant un payload, alors un émetteur ne doit pas en inclure (MUST NOT), et un destinataire doit l'ignorer (MUST).
5.5.1. Représentation
Le payload des requêtes ou des réponses indiquant un succès est généralement une représentation d'une ressource ("resource representation") ou le résultat de l'action demandée ("action result"). Son format est spécifié par le type de média Internet et le codage de contenu donnés par l'option Content-Format. En l'absence de cette option, aucune valeur par défaut n'est supposée, et le format devra être déduit par l'application (par exemple à partir du contexte applicatif). Le "sniffing" du payload ne devrait être tenté que si aucun type de contenu n'est donné (SHOULD).
Note d'implémentation : au niveau de la qualité de mise en œuvre, il est fortement attendu qu'une indication Content-Format soit fournie avec les représentations de ressources chaque fois que possible. Ce n'est pas une exigence de niveau "SHOULD" uniquement parce qu'il ne s'agit pas d'une exigence de protocole, et il serait également difficile de délimiter exactement les cas dans lesquels cette attente peut être violée.
Pour les réponses indiquant une erreur client ou serveur, le payload n'est considéré comme une représentation du résultat de l'action demandée que si une option Content-Format est donnée. En l'absence de cette option, le payload est un payload de diagnostic (Diagnostic Payload) (section 5.5.2).
5.5.2. Charge utile de diagnostic
Si aucune option Content-Format n'est donnée, le payload des réponses indiquant une erreur client ou serveur est un bref message de diagnostic lisible par l'homme, expliquant la situation d'erreur. Ce message de diagnostic doit être encodé en UTF-8 [RFC3629], plus précisément sous la forme Net-Unicode [RFC5198] (MUST).
Le message est similaire à la Reason-Phrase d'une ligne d'état HTTP. Il n'est pas destiné aux utilisateurs finaux mais aux ingénieurs logiciels qui, lors du débogage, ont besoin de l'interpréter dans le contexte de la présente spécification rédigée en anglais ; par conséquent, aucun mécanisme d'étiquetage de langue n'est nécessaire ni fourni. Contrairement à ce qui est habituel en HTTP, le payload devrait être vide s'il n'y a pas d'information supplémentaire au-delà du Response Code (SHOULD).
5.5.3. Représentation sélectionnée
Toutes les réponses ne transportent pas un payload qui fournit une représentation de la ressource visée par la requête. Il est toutefois parfois utile de pouvoir faire référence à une telle représentation en relation avec une réponse, indépendamment du fait qu'elle ait effectivement été incluse ou non.
Nous utilisons le terme "selected representation" pour désigner la représentation actuelle d'une ressource cible qui aurait été sélectionnée dans une réponse réussie si la requête correspondante avait utilisé la méthode GET et exclu toute option de requête conditionnelle (section 5.10.8).
Certaines options de réponse fournissent des métadonnées sur la représentation sélectionnée, qui peuvent différer de la représentation incluse dans le message pour les réponses à certaines méthodes modifiant l'état. Parmi les options de réponse définies dans la présente spécification, seule l'option de réponse ETag (section 5.10.6) est définie comme une métadonnée sur la représentation sélectionnée.
5.5.4. Négociation de contenu
Un serveur peut être en mesure de fournir une représentation d'une ressource dans l'un de plusieurs formats de représentation. Sans information supplémentaire de la part du client, il fournira la représentation dans le format qu'il préfère.
En utilisant l'option Accept (section 5.10.4) dans une requête, le client peut indiquer le content-format qu'il préfère recevoir.
5.6. Mise en cache
Les points de terminaison CoAP peuvent mettre en cache des réponses afin de réduire le temps de réponse et la consommation de bande passante réseau lors de futures requêtes équivalentes (MAY).
L'objectif de la mise en cache dans CoAP est de réutiliser une réponse antérieure pour satisfaire une requête courante. Dans certains cas, une réponse stockée peut être réutilisée sans nécessiter de requête réseau, réduisant la latence et les allers-retours réseau ; un mécanisme de "fraîcheur" (freshness) est utilisé à cette fin (voir la section 5.6.1). Même lorsqu'une nouvelle requête est nécessaire, il est souvent possible de réutiliser le payload d'une réponse antérieure pour satisfaire la requête, réduisant ainsi l'usage de bande passante réseau ; un mécanisme de "validation" est utilisé à cette fin (voir la section 5.6.2).
Contrairement à HTTP, la capacité de mise en cache des réponses CoAP ne dépend pas de la méthode de requête, mais du Response Code. La capacité de mise en cache de chaque Response Code est définie avec les définitions des Response Codes à la section 5.9. Les Response Codes qui indiquent un succès et ne sont pas reconnus par un point de terminaison ne doivent pas être mis en cache (MUST NOT).
Pour une requête présentée, un point de terminaison CoAP ne doit pas utiliser une réponse stockée, sauf si (MUST NOT) :
-
la méthode de la requête présentée et celle utilisée pour obtenir la réponse stockée correspondent,
-
toutes les options correspondent entre celles de la requête présentée et celles de la requête utilisée pour obtenir la réponse stockée (ce qui inclut l'URI de la requête), sauf qu'il n'est pas nécessaire qu'une option de requête marquée NoCacheKey (section 5.4) ou reconnue par le Cache et entièrement interprétée conformément à son comportement de cache spécifié (comme l'option de requête ETag décrite à la section 5.10.6 ; voir aussi la section 5.4.2) corresponde, et
-
la réponse stockée est soit fraîche, soit validée avec succès comme défini ci-dessous.
L'ensemble des options de requête utilisé pour faire correspondre l'entrée de cache est également appelé collectivement la "Cache-Key". Pour les schémas d'URI autres que coap et coaps, la mise en correspondance des options qui constituent l'URI de la requête peut être effectuée selon des règles spécifiques au schéma d'URI.
5.6.1. Modèle de fraîcheur
Lorsqu'une réponse est "fraîche" dans le cache, elle peut être utilisée pour satisfaire des requêtes ultérieures sans contacter le serveur d'origine, améliorant ainsi l'efficacité.
Le mécanisme de détermination de la fraîcheur consiste, pour un serveur d'origine, à fournir un temps d'expiration explicite dans le futur, à l'aide de l'option Max-Age (voir la section 5.10.5). L'option Max-Age indique que la réponse doit être considérée comme non fraîche une fois que son âge dépasse le nombre de secondes spécifié.
L'option Max-Age a une valeur par défaut de 60. Ainsi, si elle n'est pas présente dans une réponse pouvant être mise en cache, la réponse est considérée comme non fraîche une fois que son âge dépasse 60 secondes. Si un serveur d'origine souhaite empêcher la mise en cache, il doit inclure explicitement une option Max-Age de valeur zéro seconde (MUST).
Si un client dispose d'une réponse stockée fraîche et émet une nouvelle requête correspondant à la requête de cette réponse stockée, la nouvelle réponse invalide l'ancienne réponse.
5.6.2. Modèle de validation
Lorsqu'un point de terminaison dispose d'une ou plusieurs réponses stockées pour une requête GET, mais ne peut utiliser aucune d'entre elles (par exemple parce qu'elles ne sont pas fraîches), il peut utiliser l'option ETag (section 5.10.6) dans la requête GET pour donner au serveur d'origine l'occasion à la fois de sélectionner une réponse stockée à utiliser et de mettre à jour sa fraîcheur. Ce processus est appelé "validation" ou "revalidation" de la réponse stockée.
Lors de l'envoi d'une telle requête, le point de terminaison devrait ajouter une option ETag spécifiant l'entity-tag de chaque réponse stockée applicable (SHOULD).
Une réponse 2.03 (Valid) indique que la réponse stockée identifiée par l'entity-tag donné dans l'option ETag de la réponse peut être réutilisée après sa mise à jour comme décrit à la section 5.9.1.3.
Tout autre Response Code indique qu'aucune des réponses stockées désignées dans la requête n'est appropriée. Dans ce cas, la réponse devrait être utilisée pour satisfaire la requête (SHOULD) et peut remplacer la réponse stockée (MAY).
5.7. Mise en proxy
Un proxy est un point de terminaison CoAP qui peut être chargé par des clients CoAP d'effectuer des requêtes en leur nom. Cela peut être utile, par exemple, lorsque la requête ne pourrait pas être effectuée autrement, ou pour servir la réponse depuis un cache afin de réduire le temps de réponse et la consommation de bande passante réseau ou d'énergie.
Dans une architecture globale pour un environnement RESTful contraint (Constrained RESTful Environment), les proxys peuvent remplir des rôles très différents. Les proxys peuvent être explicitement sélectionnés par les clients, un rôle que nous appelons "forward-proxy". Les proxys peuvent également être insérés pour se substituer à des serveurs d'origine, un rôle que nous appelons "reverse-proxy". Orthogonalement à cette distinction, un proxy peut effectuer une correspondance d'une requête CoAP vers une requête CoAP (proxy CoAP-vers-CoAP) ou effectuer une traduction depuis ou vers un autre protocole ("cross-proxy"). Les définitions complètes de ces termes sont fournies à la section 1.2.
Notes : la terminologie de la présente spécification a été choisie pour être culturellement compatible avec la terminologie utilisée dans les environnements d'applications web plus larges, sans nécessairement correspondre à celle-ci dans tous les détails (ce qui peut même ne pas être pertinent pour les environnements RESTful contraints). Il ne faut pas attribuer trop de sémantique aux composants des termes (tels que "forward", "reverse" ou "cross").
Les proxys HTTP, outre leur rôle de proxys HTTP, offrent souvent une fonction de proxy de protocole de transport ("CONNECT") pour permettre une sécurité de la couche transport de bout en bout à travers le proxy. Aucune fonction de ce type n'est définie pour les proxys CoAP-vers-CoAP dans la présente spécification, car le transfert de paquets UDP est peu susceptible d'avoir beaucoup de valeur dans les environnements RESTful contraints. Voir aussi la section 10.2.7 pour le cas du cross-proxy.
Lorsqu'un client utilise un proxy pour effectuer une requête qui utilisera un schéma d'URI sécurisé (par exemple "coaps" ou "https"), la requête vers le proxy devrait être envoyée en utilisant DTLS, sauf lorsqu'une sécurité de couche inférieure équivalente est utilisée pour le segment entre le client et le proxy (SHOULD).
5.7.1. Fonctionnement du proxy
Un proxy a généralement besoin d'un moyen de déterminer les paramètres potentiels d'une requête qu'il émet vers une destination, à partir de la requête qu'il a reçue de son client. Ce moyen est entièrement spécifié pour un forward-proxy, mais peut dépendre de la configuration spécifique pour un reverse-proxy. En particulier, le client d'un reverse-proxy n'indique généralement pas de localisateur pour la destination, ce qui nécessite une forme de traduction d'espace de noms dans le reverse-proxy. Cependant, certains aspects du fonctionnement des proxys sont communs à toutes leurs formes.
Si un proxy n'utilise pas de cache, il se contente de transférer la requête traduite vers la destination déterminée. Sinon, s'il utilise un cache mais ne dispose pas d'une réponse stockée qui corresponde à la requête traduite et soit considérée comme fraîche, il doit rafraîchir son cache conformément à la section 5.6. Pour les options de la requête que le proxy reconnaît, il sait si l'option est destinée ou non à agir comme partie de la clé utilisée pour rechercher la valeur mise en cache. Par exemple, comme les requêtes portant différentes valeurs de Uri-Path visent des ressources différentes, les valeurs de Uri-Path font toujours partie de la Cache-Key, tandis que, par exemple, les valeurs de Token n'en font jamais partie. Pour les options que le proxy ne reconnaît pas mais qui sont marquées Safe-to-Forward dans le numéro d'option, l'option indique également si elle doit être incluse dans la Cache-Key (NoCacheKey n'est pas entièrement à 1) ou non (NoCacheKey est entièrement à 1). (Les options non reconnues et marquées Unsafe conduisent à 4.02 Bad Option.)
Si la requête vers la destination expire, une réponse 5.04 (Gateway Timeout) doit être renvoyée (MUST). Si la requête vers la destination renvoie une réponse qui ne peut pas être traitée par le proxy (par exemple en raison d'options critiques non reconnues ou d'erreurs de format de message), une réponse 5.02 (Bad Gateway) doit être renvoyée (MUST). Sinon, le proxy renvoie la réponse au client.
Si une réponse est générée à partir d'un cache, l'option Max-Age générée (ou implicite) ne doit pas étendre le max-age initialement défini par le serveur, compte tenu du temps que la représentation de la ressource a passé dans le cache (MUST NOT). Par exemple, l'option Max-Age peut être ajustée par le proxy pour chaque réponse à l'aide de la formule :
proxy-max-age = original-max-age - cache-age
Par exemple, si une requête est faite vers une ressource proxifiée qui a été rafraîchie il y a 20 secondes et avait un Max-Age d'origine de 60 secondes, alors le max-age proxifié de cette ressource est maintenant de 40 secondes. Compte tenu des délais réseau potentiels sur le chemin depuis le serveur d'origine, un proxy devrait être conservateur dans les valeurs de max-age proposées.
Toutes les options présentes dans une requête de proxy doivent être traitées au niveau du proxy (MUST). Les options Unsafe d'une requête qui ne sont pas reconnues par le proxy doivent conduire à ce que le proxy renvoie une réponse 4.02 (Bad Option) (MUST). Un proxy CoAP-vers-CoAP doit transférer au serveur d'origine toutes les options Safe-to-Forward qu'il ne reconnaît pas (MUST). De même, les options Unsafe d'une réponse qui ne sont pas reconnues par le serveur proxy CoAP-vers-CoAP doivent conduire à une réponse 5.02 (Bad Gateway) (MUST). Là encore, les options Safe-to-Forward qui ne sont pas reconnues doivent être transférées (MUST).
Des considérations supplémentaires pour la mise en proxy inter-protocoles entre CoAP et HTTP sont discutées à la section 10.
5.7.2. Forward-Proxies
CoAP distingue les requêtes adressées (comme si c'était) à un serveur d'origine et les requêtes adressées via un forward-proxy. Les requêtes CoAP vers un forward-proxy sont émises comme des requêtes Confirmable ou Non-confirmable normales vers le point de terminaison du forward-proxy, mais elles spécifient l'URI de la requête d'une manière différente : l'URI de la requête dans une requête de proxy est spécifiée sous forme de chaîne dans l'option Proxy-Uri (voir la section 5.10.2), tandis que l'URI de la requête dans une requête vers un serveur d'origine est répartie entre les options Uri-Host, Uri-Port, Uri-Path et Uri-Query (voir la section 5.10.1). Alternativement, l'URI d'une requête de proxy peut être assemblée à partir d'une option Proxy-Scheme et des options réparties mentionnées.
Lorsqu'une requête de proxy est adressée à un point de terminaison et que celui-ci n'est pas disposé ou est incapable d'agir comme proxy pour l'URI de la requête, il doit renvoyer une réponse 5.05 (Proxying Not Supported) (MUST). Si l'autorité (hôte et port) est reconnue comme identifiant le point de terminaison du proxy lui-même (voir la section 5.10.2), alors la requête doit être traitée comme une requête locale (non proxifiée) (MUST).
À moins qu'un proxy ne soit configuré pour transférer la requête de proxy vers un autre proxy, il doit traduire la requête comme suit (MUST) : le schéma de l'URI de la requête définit le protocole sortant et ses détails (par exemple, CoAP est utilisé sur UDP pour le schéma "coap" et sur DTLS pour le schéma "coaps"). Pour un proxy CoAP-vers-CoAP, l'adresse IP et le port du serveur d'origine sont déterminés par la composante autorité de l'URI de la requête, et l'URI de la requête est décodée et répartie entre les options Uri-Host, Uri-Port, Uri-Path et Uri-Query. Cela consomme l'option Proxy-Uri ou Proxy-Scheme, qui n'est par conséquent pas transférée au serveur d'origine.
5.7.3. Reverse-Proxies
Les reverse-proxies n'utilisent pas les options Proxy-Uri ou Proxy-Scheme, mais doivent déterminer la destination (prochain saut) d'une requête à partir des informations contenues dans la requête et des informations de leur configuration. Par exemple, un reverse-proxy peut offrir diverses ressources comme s'il s'agissait de ses propres ressources, après avoir appris leur existence par la découverte de ressources. Le reverse-proxy est libre de construire un espace de noms pour les URI qui identifient ces ressources. Un reverse-proxy peut également construire un espace de noms qui donne au client davantage de contrôle sur la destination de la requête, par exemple en intégrant des identifiants d'hôte et des numéros de port dans le chemin d'URI des ressources offertes.
Lors du traitement de la réponse, un reverse-proxy doit veiller à ce que les valeurs de l'option ETag provenant de sources différentes ne soient pas mélangées sur une ressource offerte à ses clients. Dans de nombreux cas, l'ETag peut être transféré sans modification. Si la correspondance entre une ressource offerte par le reverse-proxy et les ressources offertes par ses divers serveurs d'origine n'est pas unique, le reverse-proxy peut avoir besoin de générer un nouvel ETag, en veillant à ce que la sémantique de cette option soit correctement préservée.
5.8. Définitions des méthodes
Dans cette section, chaque méthode est définie avec son comportement. Une requête portant un Method Code non reconnu ou non pris en charge doit générer une réponse piggybackée 4.05 (Method Not Allowed) (MUST).
5.8.1. GET
La méthode GET récupère une représentation de l'information qui correspond actuellement à la ressource identifiée par l'URI de la requête. Si la requête inclut une option Accept, cela indique le content-format préféré d'une réponse. Si la requête inclut une option ETag, la méthode GET demande que cet ETag soit validé et que la représentation ne soit transférée que si la validation a échoué. En cas de succès, un Response Code 2.05 (Content) ou 2.03 (Valid) devrait être présent dans la réponse (SHOULD).
La méthode GET est sûre (safe) et idempotente.
5.8.2. POST
La méthode POST demande que la représentation incluse dans la requête soit traitée. La fonction réelle exécutée par la méthode POST est déterminée par le serveur d'origine et dépend de la ressource cible. Elle aboutit généralement à la création d'une nouvelle ressource ou à la mise à jour de la ressource cible.
Si une ressource a été créée sur le serveur, la réponse renvoyée par le serveur devrait avoir un Response Code 2.01 (Created) et devrait inclure l'URI de la nouvelle ressource dans une séquence d'une ou plusieurs options Location-Path et/ou Location-Query (section 5.10.7) (SHOULD). Si le POST réussit mais n'aboutit pas à la création d'une nouvelle ressource sur le serveur, la réponse devrait avoir un Response Code 2.04 (Changed) (SHOULD). Si le POST réussit et aboutit à la suppression de la ressource cible, la réponse devrait avoir un Response Code 2.02 (Deleted) (SHOULD). POST n'est ni sûre ni idempotente.
5.8.3. PUT
La méthode PUT demande que la ressource identifiée par l'URI de la requête soit mise à jour ou créée avec la représentation incluse. Le format de représentation est spécifié par le type de média et le codage de contenu donnés dans l'option Content-Format, si elle est fournie.
Si une ressource existe à l'URI de la requête, la représentation incluse devrait être considérée comme une version modifiée de cette ressource, et un Response Code 2.04 (Changed) devrait être renvoyé (SHOULD). Si aucune ressource n'existe, alors le serveur peut créer une nouvelle ressource avec cet URI, ce qui donne un Response Code 2.01 (Created) (MAY). Si la ressource n'a pas pu être créée ou modifiée, alors un Response Code d'erreur approprié devrait être envoyé (SHOULD).
D'autres restrictions à un PUT peuvent être apportées en incluant les options If-Match (voir la section 5.10.8.1) ou If-None-Match (voir la section 5.10.8.2) dans la requête.
PUT n'est pas sûre (safe) mais est idempotente.
5.8.4. DELETE
La méthode DELETE demande que la ressource identifiée par l'URI de la requête soit supprimée. Un Response Code 2.02 (Deleted) devrait être utilisé en cas de succès ou si la ressource n'existait pas avant la requête (SHOULD).
DELETE n'est pas sûre (safe) mais est idempotente.
5.9. Définitions des codes de réponse
Chaque Response Code est décrit ci-dessous, y compris les options requises dans la réponse. Le cas échéant, certains codes seront spécifiés par rapport à des Response Codes connexes de HTTP [RFC2616] ; cela ne signifie pas qu'une telle relation modifie la correspondance HTTP spécifiée à la section 10.
5.9.1. Success 2.xx
Cette classe de Response Code indique que la requête du client a été reçue, comprise et acceptée avec succès.
5.9.1.1. 2.01 Created
Comme HTTP 201 "Created", mais utilisé uniquement en réponse à des requêtes POST et PUT. Le payload renvoyé avec la réponse, s'il existe, est une représentation du résultat de l'action.
Si la réponse inclut une ou plusieurs options Location-Path et/ou Location-Query, les valeurs de ces options spécifient l'emplacement où la ressource a été créée. Sinon, la ressource a été créée à l'URI de la requête. Un cache recevant cette réponse doit marquer comme non fraîche toute réponse stockée pour la ressource créée (MUST).
Cette réponse n'est pas mise en cache.
5.9.1.2. 2.02 Deleted
Ce Response Code est comme HTTP 204 "No Content" mais utilisé uniquement en réponse à des requêtes qui font cesser la disponibilité de la ressource, telles que DELETE et, dans certaines circonstances, POST. Le payload renvoyé avec la réponse, s'il existe, est une représentation du résultat de l'action.
Cette réponse n'est pas mise en cache. Cependant, un cache doit marquer comme non fraîche toute réponse stockée pour la ressource supprimée (MUST).
5.9.1.3. 2.03 Valid
Ce Response Code est apparenté à HTTP 304 "Not Modified" mais utilisé uniquement pour indiquer que la réponse identifiée par l'entity-tag identifié par l'option ETag incluse est valide. En conséquence, la réponse doit inclure une option ETag (MUST) et ne doit pas inclure de payload (MUST NOT).
Lorsqu'un cache qui reconnaît et traite l'option de réponse ETag reçoit une réponse 2.03 (Valid), il doit mettre à jour la réponse stockée avec la valeur de l'option Max-Age incluse dans la réponse (explicitement, ou implicitement comme valeur par défaut ; voir aussi la section 5.6.2) (MUST). Pour chaque type d'option Safe-to-Forward présent dans la réponse, l'ensemble (éventuellement vide) d'options de ce type présentes dans la réponse stockée doit être remplacé par l'ensemble d'options de ce type de la réponse reçue (MUST). (Les options Unsafe peuvent déclencher un traitement similaire spécifique à l'option, tel que défini par l'option.)
5.9.1.4. 2.04 Changed
Ce Response Code est comme HTTP 204 "No Content" mais utilisé uniquement en réponse à des requêtes POST et PUT. Le payload renvoyé avec la réponse, s'il existe, est une représentation du résultat de l'action.
Cette réponse n'est pas mise en cache. Cependant, un cache doit marquer comme non fraîche toute réponse stockée pour la ressource modifiée (MUST).
5.9.1.5. 2.05 Content
Ce Response Code est comme HTTP 200 "OK" mais utilisé uniquement en réponse à des requêtes GET.
Le payload renvoyé avec la réponse est une représentation de la ressource cible.
Cette réponse est mise en cache : les caches peuvent utiliser l'option Max-Age pour déterminer la fraîcheur (voir la section 5.6.1) et (si elle est présente) l'option ETag pour la validation (voir la section 5.6.2).
5.9.2. Client Error 4.xx
Cette classe de Response Code est destinée aux cas où le client semble avoir commis une erreur. Ces Response Codes s'appliquent à toute méthode de requête.
Le serveur devrait inclure un payload de diagnostic dans les conditions détaillées à la section 5.5.2 (SHOULD).
Les réponses de cette classe sont mises en cache : les caches peuvent utiliser l'option Max-Age pour déterminer la fraîcheur (voir la section 5.6.1). Elles ne peuvent pas être validées.
5.9.2.1. 4.00 Bad Request
Ce Response Code est comme HTTP 400 "Bad Request".
5.9.2.2. 4.01 Unauthorized
Le client n'est pas autorisé à effectuer l'action demandée. Le client ne devrait pas répéter la requête sans d'abord améliorer son statut d'authentification auprès du serveur (SHOULD NOT). Le mécanisme spécifique utilisable à cette fin sort du cadre du présent document ; voir aussi la section 9.
5.9.2.3. 4.02 Bad Option
La requête n'a pas pu être comprise par le serveur en raison d'une ou plusieurs options non reconnues ou mal formées. Le client ne devrait pas répéter la requête sans modification (SHOULD NOT).
5.9.2.4. 4.03 Forbidden
Ce Response Code est comme HTTP 403 "Forbidden".
5.9.2.5. 4.04 Not Found
Ce Response Code est comme HTTP 404 "Not Found".
5.9.2.6. 4.05 Method Not Allowed
Ce Response Code est comme HTTP 405 "Method Not Allowed" mais sans équivalent au champ d'en-tête "Allow".
5.9.2.7. 4.06 Not Acceptable
Ce Response Code est comme HTTP 406 "Not Acceptable", mais sans entité de réponse.
5.9.2.8. 4.12 Precondition Failed
Ce Response Code est comme HTTP 412 "Precondition Failed".
5.9.2.9. 4.13 Request Entity Too Large
Ce Response Code est comme HTTP 413 "Request Entity Too Large".
La réponse devrait inclure une option Size1 (section 5.10.9) pour indiquer la taille maximale d'entité de requête que le serveur est capable et disposé à traiter, sauf si le serveur n'est pas en mesure de rendre cette information disponible (SHOULD).
5.9.2.10. 4.15 Unsupported Content-Format
Ce Response Code est comme HTTP 415 "Unsupported Media Type".
5.9.3. Server Error 5.xx
Cette classe de Response Code indique les cas où le serveur a conscience d'avoir commis une erreur ou est incapable d'effectuer la requête. Ces Response Codes s'appliquent à toute méthode de requête.
Le serveur devrait inclure un payload de diagnostic dans les conditions détaillées à la section 5.5.2 (SHOULD).
Les réponses de cette classe sont mises en cache : les caches peuvent utiliser l'option Max-Age pour déterminer la fraîcheur (voir la section 5.6.1). Elles ne peuvent pas être validées.
5.9.3.1. 5.00 Internal Server Error
Ce Response Code est comme HTTP 500 "Internal Server Error".
5.9.3.2. 5.01 Not Implemented
Ce Response Code est comme HTTP 501 "Not Implemented".
5.9.3.3. 5.02 Bad Gateway
Ce Response Code est comme HTTP 502 "Bad Gateway".
5.9.3.4. 5.03 Service Unavailable
Ce Response Code est comme HTTP 503 "Service Unavailable" mais utilise l'option Max-Age à la place du champ d'en-tête "Retry-After" pour indiquer le nombre de secondes après lequel réessayer.
5.9.3.5. 5.04 Gateway Timeout
Ce Response Code est comme HTTP 504 "Gateway Timeout".
5.9.3.6. 5.05 Proxying Not Supported
Le serveur est incapable ou n'est pas disposé à agir comme forward-proxy pour l'URI spécifiée dans l'option Proxy-Uri ou à l'aide de Proxy-Scheme (voir la section 5.10.2).
5.10. Définitions des options
Les options CoAP individuelles sont résumées dans le Tableau 4 et expliquées dans les sous-sections de cette section.
Dans ce tableau, les colonnes C, U et N indiquent respectivement les propriétés Critical, UnSafe et NoCacheKey. Comme NoCacheKey n'a de sens que pour les options Safe-to-Forward (non marquées Unsafe), la colonne est remplie d'un tiret pour les options UnSafe.
| No. | C | U | N | R | Name | Format | Length | Default |
|---|---|---|---|---|---|---|---|---|
| 1 | x | x | If-Match | opaque | 0-8 | (none) | ||
| 3 | x | x | - | Uri-Host | string | 1-255 | (see | |
| below) | ||||||||
| 4 | x | ETag | opaque | 1-8 | (none) | |||
| 5 | x | If-None-Match | empty | 0 | (none) | |||
| 7 | x | x | - | Uri-Port | uint | 0-2 | (see | |
| below) | ||||||||
| 8 | x | Location-Path | string | 0-255 | (none) | |||
| 11 | x | x | - | x | Uri-Path | string | 0-255 | (none) |
| 12 | Content-Format | uint | 0-2 | (none) | ||||
| 14 | x | - | Max-Age | uint | 0-4 | 60 | ||
| 15 | x | x | - | x | Uri-Query | string | 0-255 | (none) |
| 17 | x | Accept | uint | 0-2 | (none) | |||
| 20 | x | Location-Query | string | 0-255 | (none) | |||
| 35 | x | x | - | Proxy-Uri | string | 1-1034 | (none) | |
| 39 | x | x | - | Proxy-Scheme | string | 1-255 | (none) | |
| 60 | x | Size1 | uint | 0-4 | (none) |
C=Critical, U=Unsafe, N=NoCacheKey, R=Repeatable
Tableau 4 : Options
5.10.1. Uri-Host, Uri-Port, Uri-Path et Uri-Query
Les options Uri-Host, Uri-Port, Uri-Path et Uri-Query servent à spécifier la ressource cible d'une requête vers un serveur d'origine CoAP. Les options encodent les différentes composantes de l'URI de la requête de telle manière qu'aucun encodage en pourcentage ne soit visible dans les valeurs des options et que l'URI complète puisse être reconstruite à tout point de terminaison impliqué. La syntaxe des URI CoAP est définie à la section 6.
Les étapes d'analyse des URI en options sont définies à la section 6.4. Ces étapes aboutissent à l'inclusion de zéro ou plusieurs options Uri-Host, Uri-Port, Uri-Path et Uri-Query dans une requête, chaque option contenant les valeurs suivantes :
-
l'option Uri-Host spécifie l'hôte Internet de la ressource demandée,
-
l'option Uri-Port spécifie le numéro de port de la couche transport de la ressource,
-
chaque option Uri-Path spécifie un segment du chemin absolu vers la ressource, et
-
chaque option Uri-Query spécifie un argument paramétrant la ressource.
Note : Les fragments ([RFC3986], section 3.5) ne font pas partie de l'URI de la requête et ne seront donc pas transmis dans une requête CoAP.
La valeur par défaut de l'option Uri-Host est le littéral IP représentant l'adresse IP de destination du message de requête. De même, la valeur par défaut de l'option Uri-Port est le port UDP de destination. Les valeurs par défaut des options Uri-Host et Uri-Port sont suffisantes pour les requêtes vers la plupart des serveurs. Les options Uri-Host et Uri-Port explicites sont généralement utilisées lorsqu'un point de terminaison héberge plusieurs serveurs virtuels.
Les options Uri-Path et Uri-Query peuvent contenir n'importe quelle séquence de caractères. Aucun encodage en pourcentage n'est effectué. La valeur d'une option Uri-Path ne doit pas être "." ou ".." (car l'URI de la requête doit être résolue avant d'être analysée en options) (MUST NOT).
Les étapes de construction de l'URI de la requête à partir des options sont définies à la section 6.5. Notons qu'une implémentation n'a pas nécessairement à construire l'URI ; elle peut simplement rechercher la ressource cible en examinant les options individuelles.
Des exemples figurent à l'annexe B.
5.10.2. Proxy-Uri et Proxy-Scheme
L'option Proxy-Uri sert à effectuer une requête vers un forward-proxy (voir la section 5.7). Il est demandé au forward-proxy de transférer la requête ou de la servir depuis un cache valide et de renvoyer la réponse.
La valeur de l'option est un absolute-URI ([RFC3986], section 4.3).
Notons que le forward-proxy peut transférer la requête vers un autre proxy ou directement vers le serveur spécifié par l'absolute-URI (MAY). Afin d'éviter les boucles de requêtes, un proxy doit être capable de reconnaître tous ses noms de serveur, y compris les alias, les variantes locales et les adresses IP numériques (MUST).
Un point de terminaison qui reçoit une requête comportant une option Proxy-Uri et qui est incapable ou n'est pas disposé à agir comme forward-proxy pour la requête doit provoquer le renvoi d'une réponse 5.05 (Proxying Not Supported) (MUST).
L'option Proxy-Uri doit primer sur l'une quelconque des options Uri-Host, Uri-Port, Uri-Path ou Uri-Query (MUST) (chacune de ces dernières ne doit pas être incluse dans une requête contenant l'option Proxy-Uri (MUST NOT)).
Comme cas particulier destiné à simplifier de nombreux clients de proxy, l'absolute-URI peut être construite à partir des options Uri-. Lorsqu'une option Proxy-Scheme est présente, l'absolute-URI est construite comme suit : un URI CoAP est construit à partir des options Uri- comme défini à la section 6.5. Dans l'URI résultante, le schéma initial jusqu'au deux-points suivant, mais non compris, est alors remplacé par le contenu de l'option Proxy-Scheme. Notons que ce cas ne s'applique que si les composantes de l'URI souhaitée autres que la composante de schéma peuvent réellement être exprimées à l'aide des options Uri-* ; par exemple, pour représenter un URI comportant une composante userinfo dans l'autorité, seule Proxy-Uri peut être utilisée.
5.10.3. Content-Format
L'option Content-Format indique le format de représentation du payload du message. Le format de représentation est donné sous la forme d'un identifiant Content-Format numérique défini dans le registre "CoAP Content-Formats" (section 12.3). En l'absence de l'option, aucune valeur par défaut n'est supposée, c'est-à-dire que le format de représentation du payload de tout message de représentation est indéterminé (section 5.5).
5.10.4. Accept
L'option CoAP Accept peut être utilisée pour indiquer le Content-Format acceptable pour le client. Le format de représentation est donné sous la forme d'un identifiant Content-Format numérique défini dans le registre "CoAP Content-Formats" (section 12.3). Si aucune option Accept n'est donnée, le client n'exprime pas de préférence (donc aucune valeur par défaut n'est supposée). Le client préfère que la représentation renvoyée par le serveur soit dans le Content-Format indiqué. Le serveur renvoie le Content-Format préféré s'il est disponible. Si le Content-Format préféré ne peut pas être renvoyé, alors un 4.06 "Not Acceptable" doit être envoyé comme réponse, sauf si un autre code d'erreur a la priorité pour cette réponse (MUST).
5.10.5. Max-Age
L'option Max-Age indique la durée maximale pendant laquelle une réponse peut être mise en cache avant d'être considérée comme non fraîche (voir la section 5.6.1).
La valeur de l'option est un nombre entier de secondes compris entre 0 et 2**32-1 inclus (environ 136,1 ans). Une valeur par défaut de 60 secondes est supposée en l'absence de l'option dans une réponse.
La valeur est censée être à jour au moment de la transmission. Les serveurs qui fournissent des ressources avec des tolérances strictes sur la valeur de Max-Age devraient mettre à jour la valeur avant chaque retransmission (SHOULD). (Voir aussi la section 5.7.1.)
5.10.6. ETag
Un entity-tag est destiné à être utilisé comme identifiant local à une ressource pour distinguer entre des représentations de la même ressource qui varient dans le temps. Il est généré par le serveur fournissant la ressource, lequel peut le générer de nombreuses manières, notamment une version, une somme de contrôle, un hachage ou un horodatage. Un point de terminaison qui reçoit un entity-tag doit le traiter comme opaque et ne faire aucune supposition quant à son contenu ou sa structure (MUST). (Les points de terminaison qui génèrent un entity-tag sont encouragés à utiliser la représentation la plus compacte possible, en particulier à l'égard des clients et intermédiaires qui peuvent vouloir stocker plusieurs valeurs ETag.)
5.10.6.1. ETag comme option de réponse
L'option ETag dans une réponse fournit la valeur actuelle (c'est-à-dire après que la requête a été traitée) de l'entity-tag pour la "tagged representation". Si aucune option Location-* n'est présente, la tagged representation est la représentation sélectionnée (section 5.5.3) de la ressource cible. Si une ou plusieurs options Location-* sont présentes et qu'une URI de localisation est donc indiquée (section 5.10.7), la tagged representation est la représentation qui serait récupérée par une requête GET vers l'URI de localisation.
Une option de réponse ETag peut être incluse avec toute réponse pour laquelle il existe une tagged representation (par exemple, elle n'aurait pas de sens dans une réponse 4.04 ou 4.00). L'option ETag ne doit pas apparaître plus d'une fois dans une réponse (MUST NOT).
Il n'existe pas de valeur par défaut pour l'option ETag ; si elle n'est pas présente dans une réponse, le serveur ne fait aucune déclaration sur l'entity-tag de la tagged representation.
5.10.6.2. ETag comme option de requête
Dans une requête GET, un point de terminaison qui dispose d'une ou plusieurs représentations précédemment obtenues de la ressource et a obtenu avec celles-ci des options de réponse ETag peut spécifier une instance de l'option ETag pour une ou plusieurs de ces réponses stockées.
Un serveur peut émettre une réponse 2.03 Valid (section 5.9.1.3) à la place d'une réponse 2.05 Content si l'un des ETags donnés est l'entity-tag de la représentation actuelle, c'est-à-dire s'il est valide ; la réponse 2.03 Valid reprend alors cet ETag spécifique dans une option de réponse.
En pratique, un client peut déterminer si l'une des représentations stockées est actuelle (voir la section 5.6.2) sans avoir besoin de les transférer à nouveau.
L'option ETag peut apparaître zéro, une ou plusieurs fois dans une requête (MAY).
5.10.7. Location-Path et Location-Query
Les options Location-Path et Location-Query indiquent ensemble un URI relatif constitué soit d'un chemin absolu, soit d'une chaîne de requête, soit des deux. Une combinaison de ces options est incluse dans une réponse 2.01 (Created) pour indiquer l'emplacement de la ressource créée à la suite d'une requête POST (voir la section 5.8.2). L'emplacement est résolu relativement à l'URI de la requête.
Si une réponse comportant une ou plusieurs options Location-Path et/ou Location-Query traverse un cache qui interprète ces options et que l'URI implicite identifie une ou plusieurs réponses actuellement stockées, ces entrées doivent être marquées comme non fraîches (MUST).
Chaque option Location-Path spécifie un segment du chemin absolu vers la ressource, et chaque option Location-Query spécifie un argument paramétrant la ressource. Les options Location-Path et Location-Query peuvent contenir n'importe quelle séquence de caractères. Aucun encodage en pourcentage n'est effectué. La valeur d'une option Location-Path ne doit pas être "." ou ".." (MUST NOT).
Les étapes de construction de l'URI de localisation à partir des options sont analogues à la section 6.5, sauf que les cinq premières étapes sont ignorées et que le résultat est une référence d'URI relative, qui est ensuite interprétée relativement à l'URI de la requête. Notons que la référence d'URI relative construite de cette manière inclut toujours un chemin absolu (par exemple, omettre Location-Path mais fournir Location-Query signifie que la composante chemin de l'URI est "/").
Les options utilisées pour calculer la référence d'URI relative sont collectivement appelées options Location-. Au-delà de Location-Path et Location-Query, d'autres options Location- pourront être définies à l'avenir et se sont vu réserver les numéros d'option 128, 132, 136 et 140. Si l'un de ces numéros d'option réservés apparaît en plus de Location-Path et/ou Location-Query et n'est pas pris en charge, alors une erreur 4.02 (Bad Option) doit être renvoyée (MUST).
5.10.8. Options de requête conditionnelles
Les options de requête conditionnelles permettent à un client de demander au serveur d'effectuer la requête uniquement si certaines conditions spécifiées par l'option sont remplies.
Pour chacune de ces options, si la condition donnée n'est pas remplie, alors le serveur ne doit pas effectuer la méthode demandée (MUST NOT). À la place, le serveur doit répondre avec le Response Code 4.12 (Precondition Failed) (MUST).
Si la condition est remplie, le serveur effectue la méthode de requête comme si les options de requête conditionnelles n'étaient pas présentes.
Si la requête devait, sans les options de requête conditionnelles, aboutir à autre chose qu'un Response Code 2.xx ou 4.12, alors toute option de requête conditionnelle peut être ignorée (MAY).
5.10.8.1. If-Match
L'option If-Match peut être utilisée pour rendre une requête conditionnelle à l'existence ou à la valeur actuelle d'un ETag pour une ou plusieurs représentations de la ressource cible (MAY). If-Match est généralement utile pour les requêtes de mise à jour de ressources, telles que les requêtes PUT, comme moyen de se protéger contre les écrasements accidentels lorsque plusieurs clients agissent en parallèle sur la même ressource (c'est-à-dire le problème de la "mise à jour perdue" ou "lost update").
La valeur d'une option If-Match est soit un ETag, soit la chaîne vide. Une option If-Match avec un ETag correspond à une représentation ayant cet ETag exact. Une option If-Match avec une valeur vide correspond à toute représentation existante (c'est-à-dire qu'elle place la précondition sur l'existence de toute représentation actuelle pour la ressource cible).
L'option If-Match peut apparaître plusieurs fois. Si l'une des options correspond, alors la condition est remplie.
S'il y a une ou plusieurs options If-Match, mais qu'aucune des options ne correspond, alors la condition n'est pas remplie.
5.10.8.2. If-None-Match
L'option If-None-Match peut être utilisée pour rendre une requête conditionnelle à la non-existence de la ressource cible (MAY). If-None-Match est utile pour les requêtes de création de ressources, telles que les requêtes PUT, comme moyen de se protéger contre les écrasements accidentels lorsque plusieurs clients agissent en parallèle sur la même ressource. L'option If-None-Match ne transporte aucune valeur.
Si la ressource cible existe, alors la condition n'est pas remplie.
(Il n'est pas très utile de combiner les options If-Match et If-None-Match dans une seule requête, car la condition ne sera alors jamais remplie.)
5.10.9. Option Size1
L'option Size1 fournit des informations de taille sur la représentation de la ressource dans une requête. La valeur de l'option est un nombre entier d'octets. Son utilisation principale concerne les transferts par blocs (block-wise transfers) [BLOCK]. Dans la présente spécification, elle est utilisée dans les réponses 4.13 (section 5.9.2.9) pour indiquer la taille maximale d'entité de requête que le serveur est capable et disposé à traiter.