9. Canceling a Request
9 Canceling a Request
Dans la section précédente, nous avons discuté du comportement général de l'UA pour générer des requêtes de toutes les méthodes et traiter les réponses. Cette section traite d'une méthode générique appelée CANCEL.
Comme son nom l'indique, la requête CANCEL est utilisée par un client pour annuler une requête précédente qu'il a envoyée. Plus précisément, elle demande à un UAS d'arrêter de traiter la requête et de générer une réponse d'erreur à cette requête. CANCEL n'a aucun effet sur une requête pour laquelle le UAS a déjà renvoyé une réponse finale. Pour cette raison, il est utile pour annuler des requêtes susceptibles de prendre du temps à répondre. Pour cette raison, CANCEL s'applique le mieux aux requêtes INVITE qui peuvent mettre du temps à générer une réponse. Dans son utilisation, un UAS recevant un CANCEL pour un INVITE qui n'a pas encore envoyé de réponse finale « cesse de sonner » puis répond à l'INVITE avec une réponse d'erreur spécifique (487).
La requête CANCEL peut être construite et envoyée à la fois par un proxy et par un agent utilisateur client. La section 15 discute de quand un UAC annule une requête INVITE, et la section 16.10 discute de l'utilisation de CANCEL par le proxy.
Étant donné que le proxy avec état répond à CANCEL plutôt que de simplement relayer les réponses reçues d'éléments en aval, CANCEL est appelé une requête « saut par saut » (hop-by-hop) car il est répondu à chaque saut de proxy avec état.
9.1 Comportement du client
Une requête CANCEL ne DOIT PAS (SHOULD NOT) être envoyée pour annuler une requête autre que INVITE.
Les requêtes non-INVITE reçoivent une réponse immédiate, donc l'envoi d'un CANCEL pour une requête non-INVITE entraînerait toujours une condition de concurrence.
Les procédures suivantes sont utilisées pour construire une requête CANCEL. Les champs Request-URI, Call-ID, To, partie numérique de CSeq et From de la requête CANCEL DOIVENT (MUST) être identiques (y compris les balises) à ceux de la requête à annuler. Le CANCEL construit par le client ne DOIT (MUST) avoir qu'une seule valeur de champ d'en-tête Via correspondant à la première valeur Via de la requête annulée. En utilisant les mêmes valeurs pour ces champs d'en-tête, CANCEL peut être mis en correspondance avec la requête qu'il annule (la section 9.2 montre comment une telle correspondance est effectuée). Cependant, la partie méthode du champ d'en-tête CSeq DOIT (MUST) avoir la valeur CANCEL. Cela permet à la requête d'être identifiée et traitée comme sa propre transaction (voir section 17).
Si la requête à annuler contient un champ d'en-tête Route, la requête CANCEL DOIT (MUST) inclure la valeur de ce champ d'en-tête Route.
Cela est nécessaire pour permettre à un proxy sans état de router correctement la requête CANCEL.
Une requête CANCEL ne DOIT PAS (MUST NOT) contenir de champ d'en-tête Require ou Proxy-Require.
Une fois le CANCEL construit, le client DEVRAIT (SHOULD) vérifier s'il a reçu une réponse (provisoire ou finale) à la requête à annuler (appelée ici « requête originale »).
Si aucune réponse provisoire n'a été reçue, la requête CANCEL ne DOIT PAS (MUST NOT) être envoyée. Au contraire, le client DOIT (MUST) attendre l'arrivée d'une réponse provisoire avant d'envoyer la requête. Si la requête originale a déjà généré une réponse finale, le CANCEL est un no-op qui ne fait rien de substantiel, il ne DEVRAIT PAS (SHOULD NOT) être envoyé. Lorsque le client décide d'envoyer le CANCEL, il crée une transaction client pour le CANCEL et passe la requête CANCEL avec l'adresse de destination, le port et le transport. L'adresse de destination, le port et le transport du CANCEL DOIVENT (MUST) être identiques à ceux utilisés pour envoyer la requête originale.
Si l'envoi d'un CANCEL avait été autorisé avant de recevoir une réponse à la requête précédente, un serveur pourrait recevoir un CANCEL avant la requête originale.
Notez que les transactions correspondant à la requête originale et à la transaction CANCEL se terminent toutes deux indépendamment. Cependant, le UAC annulant une requête ne peut pas s'appuyer sur la réception d'une réponse 487 (Request Terminated) à la requête originale. Un UAS conforme à la RFC 2543 ne générerait pas une telle réponse. Si la réponse finale à la requête originale n'est pas reçue dans les 64*T1 secondes (T1 est défini à la section 17.1.1.1), le client DEVRAIT (SHOULD) considérer la transaction originale comme annulée et DEVRAIT (SHOULD) abandonner la transaction client traitant la requête originale.
9.2 Comportement du serveur
La méthode CANCEL demande au TU côté serveur d'annuler une transaction en attente. Le TU détermine la transaction à annuler en recevant la requête CANCEL puis en appliquant la procédure de correspondance de transaction de la section 17.2.3 en supposant que la méthode de requête est autre que CANCEL ou ACK. La transaction correspondante est celle qui est annulée.
Le traitement d'une requête CANCEL au niveau du serveur dépend du type de serveur. Un proxy sans état la relaie, un proxy avec état y répond, peut-être en générant certaines de ses propres requêtes CANCEL, et un UAS y répond. Reportez-vous à la section 16.10 pour le traitement de CANCEL par le proxy.
Le UAS traite d'abord la requête CANCEL selon le traitement UAS général décrit à la section 8.2. Cependant, comme la requête CANCEL est saut par saut et ne peut pas être retransmise, elle ne peut pas être contestée par le serveur pour obtenir des informations d'identification appropriées dans un champ d'en-tête Authorization. Notez également qu'aucun champ d'en-tête Require n'est inclus dans la requête CANCEL.
Si le UAS ne trouve pas de transaction correspondant au CANCEL selon les procédures ci-dessus, il DEVRAIT (SHOULD) répondre au CANCEL avec 481 (Call Leg/Transaction Does Not Exist). Si la transaction de la requête originale existe toujours, le comportement du UAS à la réception de la requête CANCEL dépend de si une réponse finale à la requête originale a déjà été envoyée. Si elle a été envoyée, la requête CANCEL n'a aucun effet sur le traitement de la requête originale, l'état de session, ou la réponse générée à la requête originale. Si le UAS n'a pas encore émis de réponse finale à la requête originale, son comportement dépend de la méthode de la requête originale. Si la requête originale était un INVITE, le UAS DEVRAIT (SHOULD) répondre immédiatement à l'INVITE avec 487 (Request Terminated). La requête CANCEL n'affecte pas le traitement des transactions avec d'autres méthodes définies dans cette spécification.
Quelle que soit la méthode de la requête originale, tant que le CANCEL correspond à une transaction existante, le UAS répond à la requête CANCEL elle-même avec une réponse 200 (OK). Cette réponse est construite selon les procédures de la section 8.2.6, et notez que le To tag de la réponse au CANCEL et le To tag de la réponse à la requête originale DEVRAIENT (SHOULD) être identiques. La réponse au CANCEL est passée à la transaction serveur pour envoi.