Aller au contenu principal

2. Caractères (Characters)

Ce chapitre définit les jeux de caractères, les mécanismes d'encodage et les règles de traitement utilisés dans les URI.


Fondamentaux de l'encodage des caractères​

La syntaxe URI fournit une méthode pour encoder des données dans une séquence de caractères, probablement dans le but d'identifier une ressource.

Hiérarchie d'encodage:

Ressource → Caractères URI → Octets → Transmission/Stockage

Jeu de caractères: Les URI sont basés sur le jeu de caractères US-ASCII, composé de chiffres, de lettres et de quelques symboles graphiques


2.1. Encodage en pourcentage (Percent-Encoding)​

Objectif​

Un mécanisme d'encodage en pourcentage est utilisé pour représenter un octet de données dans un composant lorsque le caractère correspondant à cet octet est en dehors de l'ensemble autorisé ou est utilisé comme délimiteur.

Format d'encodage​

pct-encoded = "%" HEXDIG HEXDIG

Format: Un encodage en pourcentage consiste en un caractère pourcent "%" suivi de deux chiffres hexadécimaux représentant la valeur numérique de cet octet

Exemples​

CaractèreBinaireHexadécimalEncodage en pourcentage
Espace001000000x20%20
!001000010x21%21
#001000110x23%23
é (français)-0xC3A9%C3%A9

Règles de casse​

Équivalence: Les chiffres hexadécimaux majuscules 'A' à 'F' sont équivalents aux chiffres minuscules 'a' à 'f'

Normalisation: Deux URI qui ne diffèrent que par la casse des chiffres hexadécimaux utilisés dans les octets encodés en pourcentage sont équivalents

Recommandation: Les producteurs et normalisateurs d'URI devraient (SHOULD) utiliser des chiffres hexadécimaux majuscules pour tous les encodages en pourcentage

Recommandé: %2F %3A %5B
Non recommandé: %2f %3a %5b

2.2. Caractères réservés (Reserved Characters)​

Définition​

Les URI incluent des composants et sous-composants délimités par des caractères de l'ensemble "réservé". Ces caractères sont appelés "réservés" car ils peuvent (ou ne peuvent pas) être définis comme délimiteurs.

Ensemble de caractères réservés​

reserved    = gen-delims / sub-delims

gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"

sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="

Classification​

Délimiteurs généraux (gen-delims)​

CaractèreObjectifExemple
:Sépare le schéma et l'autoritéhttp:
/Séparateur de chemin/path/to/resource
?Séparateur de requête?key=value
#Séparateur de fragment#section
[ ]Limites d'adresse IPv6[2001:db8::1]
@Séparateur d'informations utilisateuruser@host

Sous-délimiteurs (sub-delims)​

CaractèreUtilisation courante
! $ ' ( ) *Séparation de sous-composants dans le chemin ou la requête
+Représentation alternative de l'espace
,Séparateur de liste
;Séparateur de paramètre
=Séparateur clé-valeur
&Séparateur de paramètre de requête

Règles d'encodage​

Gestion des conflits: Si les données d'un composant URI entrent en conflit avec l'objectif d'un caractère réservé en tant que délimiteur, alors les données en conflit doivent (MUST) être encodées en pourcentage avant la formation de l'URI

Exemples:

Chemin contenant le caractère "?":
Original: /path/file?.txt
Encodé: /path/file%3F.txt

Requête contenant le caractère "&":
Original: ?name=Tom&Jerry
Correct: ?name=Tom%26Jerry (si & n'est pas un délimiteur)
Ou: ?name=Tom&name=Jerry (si & est un délimiteur)

Équivalence​

Important: Les URI qui diffèrent dans le remplacement d'un caractère réservé par son octet encodé en pourcentage correspondant ne sont PAS équivalents

http://example.com/path?key=value
http://example.com/path%3Fkey=value

Ces deux URI ne sont PAS équivalents

2.3. Caractères non réservés (Unreserved Characters)​

Définition​

Les caractères autorisés dans un URI mais n'ayant pas d'objectif réservé sont appelés non réservés.

Ensemble de caractères non réservés​

unreserved  = ALPHA / DIGIT / "-" / "." / "_" / "~"

Comprend:

  • ALPHA: Lettres majuscules et minuscules (A-Z, a-z)
  • DIGIT: Chiffres décimaux (0-9)
  • -: Tiret
  • .: Point
  • _: Trait de soulignement
  • ~: Tilde

Règles d'encodage​

Équivalence: Les URI qui diffèrent dans le remplacement d'un caractère non réservé par son octet US-ASCII encodé en pourcentage correspondant sont équivalents

Normalisation: Les octets encodés en pourcentage correspondant à des caractères non réservés devraient (SHOULD) être décodés

URI équivalents:
http://example.com/~user
http://example.com/%7Euser

Normalisé en:
http://example.com/~user

Plage d'encodage en pourcentage​

Ne devrait PAS être créé (SHOULD NOT):

  • ALPHA: %41-%5A (A-Z), %61-%7A (a-z)
  • DIGIT: %30-%39 (0-9)
  • Tiret: %2D
  • Point: %2E
  • Trait de soulignement: %5F
  • Tilde: %7E

Devrait être décodé: Lorsque ces encodages sont trouvés dans un URI, les normalisateurs devraient (SHOULD) les décoder en leurs caractères non réservés correspondants


2.4. Quand encoder ou décoder (When to Encode or Decode)​

Quand encoder​

Producteurs d'URI:

  1. Lors de la production de l'URI, doivent (MUST) encoder en pourcentage les caractères non autorisés
  2. Les caractères réservés ne sont laissés non encodés que lorsqu'ils sont utilisés comme délimiteurs
  3. Les caractères non réservés ne devraient pas (SHOULD NOT) être encodés

Exemples:

# Encodage du chemin
path = "/files/my document.pdf"
encoded = "/files/my%20document.pdf"

# Encodage de la requête
query = "?name=John Doe&age=30"
encoded = "?name=John%20Doe&age=30"

Quand décoder​

Consommateurs d'URI:

  1. Après l'analyse de l'URI, décoder les composants selon les besoins
  2. Ne pas décoder prématurément (peut changer la structure de l'URI)
  3. Décoder chaque composant une seule fois

Exemple dangereux:

Original: /path%2Fto%2Ffile
Décodage prématuré: /path/to/file (structure du chemin modifiée!)

Correct: Analyser d'abord, puis décoder chaque segment
Segment 1: "path%2Fto%2Ffile" → Décoder → "path/to/file"

Problème de double encodage​

Données originales: "100%"
Premier encodage: "100%25"
Deuxième encodage erroné: "100%2525"

Lors du décodage:
"100%2525" → "100%25" → "100%"

2.5. Identification des données (Identifying Data)​

Jeux de caractères et encodage​

Caractère vs Octet:

  • Les URI sont des séquences de caractères
  • Les caractères sont encodés en octets pour la transmission/le stockage
  • UTF-8 est l'encodage de caractères recommandé

Identificateurs de ressources internationalisés (IRI)​

Extension IRI: RFC 3987 définit les IRI, qui permettent l'utilisation de caractères Unicode

Conversion:

IRI: http://例え.jp/引き出し
↓ Encoder en UTF-8 et encoder en pourcentage
URI: http://xn--r8jz45g.jp/%E5%BC%95%E3%81%8D%E5%87%BA%E3%81%97

Meilleures pratiques​

Production d'URI:

  1. Encoder les caractères non-ASCII en UTF-8
  2. Encoder en pourcentage les octets résultants
  3. Utiliser des chiffres hexadécimaux majuscules
  4. Ne pas encoder les caractères non réservés

Consommation d'URI:

  1. Analyser par composant
  2. Décoder les encodages en pourcentage
  3. Interpréter les octets en utilisant UTF-8
  4. Gérer les encodages invalides

Référence rapide des jeux de caractères​

Classification complète des caractères​

Caractères URI
├── Non réservés (unreserved)
│ ├── ALPHA: A-Z, a-z
│ ├── DIGIT: 0-9
│ └── Symboles: - . _ ~
│
├── Réservés (reserved)
│ ├── Délimiteurs généraux (gen-delims): : / ? # [ ] @
│ └── Sous-délimiteurs (sub-delims): ! $ & ' ( ) * + , ; =
│
└── Encodé en pourcentage (pct-encoded): %HEXDIG HEXDIG

Arbre de décision d'encodage​

Le caractère doit apparaître dans l'URI?
├─ Est un caractère non réservé? → Utiliser directement
├─ Est un caractère réservé?
│ ├─ Utilisé comme délimiteur? → Utiliser directement
│ └─ Utilisé comme données? → Encoder en pourcentage
└─ Autre caractère? → Encoder en pourcentage

Table d'encodage des caractères courants​

CaractèreObjectifEncodage
EspaceSéparation%20 ou + (dans la requête)
!Sous-délimiteur%21 (si encodage nécessaire)
"Guillemet%22
#Délimiteur de fragment%23 (dans les données)
$Sous-délimiteur%24 (si encodage nécessaire)
%Marqueur d'encodage%25
&Séparateur de paramètre%26 (dans les données)
'Sous-délimiteur%27 (si encodage nécessaire)
( )Sous-délimiteur%28 %29
+Espace/Sous-délimiteur%2B (dans les données)
,Séparateur de liste%2C (si encodage nécessaire)
/Séparateur de chemin%2F (dans les données)
:Séparateur de schéma%3A (dans les données)
;Séparateur de paramètre%3B (si encodage nécessaire)
=Séparateur clé-valeur%3D (si encodage nécessaire)
?Séparateur de requête%3F (dans les données)
@Séparateur d'info utilisateur%40 (dans les données)
[ ]Limites IPv6%5B %5D

Recommandations d'implémentation​

Implémentation de l'encodage​

def percent_encode(text, safe=''):
"""Encoder le texte en pourcentage"""
result = []
for char in text:
if char in safe or is_unreserved(char):
result.append(char)
else:
# Encoder en UTF-8 et encoder en pourcentage
for byte in char.encode('utf-8'):
result.append(f'%\{byte:02X}')
return ''.join(result)

def is_unreserved(char):
"""Vérifier si le caractère est non réservé"""
return (char.isalnum() or
char in '-._~')

Implémentation du décodage​

def percent_decode(text):
"""Décoder le texte en pourcentage"""
result = bytearray()
i = 0
while i < len(text):
if text[i] == '%' and i + 2 < len(text):
try:
byte = int(text[i+1:i+3], 16)
result.append(byte)
i += 3
except ValueError:
result.extend(text[i].encode('utf-8'))
i += 1
else:
result.extend(text[i].encode('utf-8'))
i += 1
return result.decode('utf-8', errors='replace')

Chapitre suivant: 3. Composants syntaxiques (Syntax Components) - Composants structurels des URI