2. Caratteri (Characters)
Questo capitolo definisce i set di caratteri, i meccanismi di codifica e le regole di elaborazione utilizzati negli URI.
Fondamenti della codifica dei caratteri
La sintassi URI fornisce un metodo per codificare i dati in una sequenza di caratteri, probabilmente allo scopo di identificare una risorsa.
Gerarchia di codifica:
Risorsa → Caratteri URI → Ottetti → Trasmissione/Archiviazione
Set di caratteri: Gli URI si basano sul set di caratteri US-ASCII, composto da cifre, lettere e alcuni simboli grafici
2.1. Codifica percentuale (Percent-Encoding)
Scopo
Un meccanismo di codifica percentuale viene utilizzato per rappresentare un ottetto di dati in un componente quando il carattere corrispondente a quell'ottetto è al di fuori dell'insieme consentito o viene utilizzato come delimitatore.
Formato di codifica
pct-encoded = "%" HEXDIG HEXDIG
Formato: Una codifica percentuale consiste in un carattere di percentuale "%" seguito da due cifre esadecimali che rappresentano il valore numerico di quell'ottetto
Esempi
| Carattere | Binario | Esadecimale | Codifica Percentuale |
|---|---|---|---|
| Spazio | 00100000 | 0x20 | %20 |
| ! | 00100001 | 0x21 | %21 |
| # | 00100011 | 0x23 | %23 |
| è (italiano) | - | 0xC3A8 | %C3%A8 |
Regole di maiuscole/minuscole
Equivalenza: Le cifre esadecimali maiuscole da 'A' a 'F' sono equivalenti alle cifre minuscole da 'a' a 'f'
Normalizzazione: Due URI che differiscono solo per la maiuscola/minuscola delle cifre esadecimali utilizzate negli ottetti codificati in percentuale sono equivalenti
Raccomandazione: I produttori e normalizzatori di URI dovrebbero (SHOULD) utilizzare cifre esadecimali maiuscole per tutte le codifiche percentuali
Raccomandato: %2F %3A %5B
Non raccomandato: %2f %3a %5b
2.2. Caratteri riservati (Reserved Characters)
Definizione
Gli URI includono componenti e sottocomponenti delimitati da caratteri nell'insieme "riservato". Questi caratteri sono chiamati "riservati" perché possono (o non possono) essere definiti come delimitatori.
Set di caratteri riservati
reserved = gen-delims / sub-delims
gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
/ "*" / "+" / "," / ";" / "="
Classificazione
Delimitatori generali (gen-delims)
| Carattere | Scopo | Esempio |
|---|---|---|
| : | Separa schema e autorità | http: |
| / | Separatore di percorso | /path/to/resource |
| ? | Separatore di query | ?key=value |
| # | Separatore di frammento | #section |
| [ ] | Limiti indirizzo IPv6 | [2001:db8::1] |
| @ | Separatore informazioni utente | user@host |
Sotto-delimitatori (sub-delims)
| Carattere | Uso comune |
|---|---|
| ! $ ' ( ) * | Separazione sottocomponenti in percorso o query |
| + | Rappresentazione alternativa dello spazio |
| , | Separatore di lista |
| ; | Separatore di parametro |
| = | Separatore chiave-valore |
| & | Separatore parametro di query |
Regole di codifica
Gestione dei conflitti: Se i dati per un componente URI entrano in conflitto con lo scopo di un carattere riservato come delimitatore, allora i dati in conflitto devono (MUST) essere codificati in percentuale prima della formazione dell'URI
Esempi:
Percorso contenente il carattere "?":
Originale: /path/file?.txt
Codificato: /path/file%3F.txt
Query contenente il carattere "&":
Originale: ?name=Tom&Jerry
Corretto: ?name=Tom%26Jerry (se & non è un delimitatore)
Oppure: ?name=Tom&name=Jerry (se & è un delimitatore)
Equivalenza
Importante: Gli URI che differiscono nella sostituzione di un carattere riservato con il suo ottetto codificato in percentuale corrispondente NON sono equivalenti
http://example.com/path?key=value
http://example.com/path%3Fkey=value
Questi due URI NON sono equivalenti
2.3. Caratteri non riservati (Unreserved Characters)
Definizione
I caratteri consentiti in un URI ma che non hanno uno scopo riservato sono chiamati non riservati.
Set di caratteri non riservati
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
Include:
- ALPHA: Lettere maiuscole e minuscole (A-Z, a-z)
- DIGIT: Cifre decimali (0-9)
- -: Trattino
- .: Punto
- _: Underscore
- ~: Tilde
Regole di codifica
Equivalenza: Gli URI che differiscono nella sostituzione di un carattere non riservato con il suo ottetto US-ASCII codificato in percentuale corrispondente sono equivalenti
Normalizzazione: Gli ottetti codificati in percentuale corrispondenti a caratteri non riservati dovrebbero (SHOULD) essere decodificati
URI equivalenti:
http://example.com/~user
http://example.com/%7Euser
Normalizzato in:
http://example.com/~user
Intervallo di codifica percentuale
NON dovrebbe essere creato (SHOULD NOT):
- ALPHA:
%41-%5A(A-Z),%61-%7A(a-z) - DIGIT:
%30-%39(0-9) - Trattino:
%2D - Punto:
%2E - Underscore:
%5F - Tilde:
%7E
Dovrebbe essere decodificato: Quando queste codifiche vengono trovate in un URI, i normalizzatori dovrebbero (SHOULD) decodificarle nei loro caratteri non riservati corrispondenti
2.4. Quando codificare o decodificare (When to Encode or Decode)
Quando codificare
Produttori di URI:
- Durante la produzione dell'URI, devono (MUST) codificare in percentuale i caratteri non consentiti
- I caratteri riservati vengono lasciati non codificati solo quando utilizzati come delimitatori
- I caratteri non riservati non dovrebbero (SHOULD NOT) essere codificati
Esempi:
# Codifica del percorso
path = "/files/my document.pdf"
encoded = "/files/my%20document.pdf"
# Codifica della query
query = "?name=John Doe&age=30"
encoded = "?name=John%20Doe&age=30"
Quando decodificare
Consumatori di URI:
- Dopo l'analisi dell'URI, decodificare i componenti secondo necessità
- Non decodificare prematuramente (può cambiare la struttura dell'URI)
- Decodificare ogni componente una sola volta
Esempio pericoloso:
Originale: /path%2Fto%2Ffile
Decodifica prematura: /path/to/file (struttura del percorso modificata!)
Corretto: Analizzare prima, poi decodificare ogni segmento
Segmento 1: "path%2Fto%2Ffile" → Decodificare → "path/to/file"
Problema della doppia codifica
Dati originali: "100%"
Prima codifica: "100%25"
Seconda codifica errata: "100%2525"
Durante la decodifica:
"100%2525" → "100%25" → "100%"
2.5. Identificazione dei dati (Identifying Data)
Set di caratteri e codifica
Carattere vs Ottetto:
- Gli URI sono sequenze di caratteri
- I caratteri sono codificati come ottetti per trasmissione/archiviazione
- UTF-8 è la codifica dei caratteri raccomandata
Identificatori di risorse internazionalizzati (IRI)
Estensione IRI: RFC 3987 definisce gli IRI, che consentono l'uso di caratteri Unicode
Conversione:
IRI: http://例え.jp/引き出し
↓ Codificare in UTF-8 e codificare in percentuale
URI: http://xn--r8jz45g.jp/%E5%BC%95%E3%81%8D%E5%87%BA%E3%81%97
Migliori pratiche
Produzione URI:
- Codificare i caratteri non-ASCII usando UTF-8
- Codificare in percentuale gli ottetti risultanti
- Utilizzare cifre esadecimali maiuscole
- Non codificare i caratteri non riservati
Consumo URI:
- Analizzare per componente
- Decodificare le codifiche percentuali
- Interpretare gli ottetti usando UTF-8
- Gestire le codifiche non valide
Riferimento rapido set di caratteri
Classificazione completa dei caratteri
Caratteri URI
├── Non riservati (unreserved)
│ ├── ALPHA: A-Z, a-z
│ ├── DIGIT: 0-9
│ └── Simboli: - . _ ~
│
├── Riservati (reserved)
│ ├── Delimitatori generali (gen-delims): : / ? # [ ] @
│ └── Sotto-delimitatori (sub-delims): ! $ & ' ( ) * + , ; =
│
└── Codifica percentuale (pct-encoded): %HEXDIG HEXDIG
Albero decisionale di codifica
Il carattere deve apparire nell'URI?
├─ È un carattere non riservato? → Usare direttamente
├─ È un carattere riservato?
│ ├─ Usato come delimitatore? → Usare direttamente
│ └─ Usato come dati? → Codificare in percentuale
└─ Altro carattere? → Codificare in percentuale
Tabella di codifica dei caratteri comuni
| Carattere | Scopo | Codifica |
|---|---|---|
| Spazio | Separazione | %20 o + (nella query) |
| ! | Sotto-delimitatore | %21 (se necessaria codifica) |
| " | Virgolette | %22 |
| # | Delimitatore frammento | %23 (nei dati) |
| $ | Sotto-delimitatore | %24 (se necessaria codifica) |
| % | Marcatore di codifica | %25 |
| & | Separatore parametro | %26 (nei dati) |
| ' | Sotto-delimitatore | %27 (se necessaria codifica) |
| ( ) | Sotto-delimitatore | %28 %29 |
| + | Spazio/Sotto-delimitatore | %2B (nei dati) |
| , | Separatore lista | %2C (se necessaria codifica) |
| / | Separatore percorso | %2F (nei dati) |
| : | Separatore schema | %3A (nei dati) |
| ; | Separatore parametro | %3B (se necessaria codifica) |
| = | Separatore chiave-valore | %3D (se necessaria codifica) |
| ? | Separatore query | %3F (nei dati) |
| @ | Separatore info utente | %40 (nei dati) |
| [ ] | Limiti IPv6 | %5B %5D |
Raccomandazioni di implementazione
Implementazione della codifica
def percent_encode(text, safe=''):
"""Codificare il testo in percentuale"""
result = []
for char in text:
if char in safe or is_unreserved(char):
result.append(char)
else:
# Codificare in UTF-8 e codificare in percentuale
for byte in char.encode('utf-8'):
result.append(f'%{byte:02X}')
return ''.join(result)
def is_unreserved(char):
"""Verificare se il carattere è non riservato"""
return (char.isalnum() or
char in '-._~')
Implementazione della decodifica
def percent_decode(text):
"""Decodificare il testo in percentuale"""
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')
Capitolo successivo: 3. Componenti sintattici (Syntax Components) - Componenti strutturali degli URI