Passa al contenuto principale

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

CarattereBinarioEsadecimaleCodifica Percentuale
Spazio001000000x20%20
!001000010x21%21
#001000110x23%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)

CarattereScopoEsempio
: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 utenteuser@host

Sotto-delimitatori (sub-delims)

CarattereUso 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:

  1. Durante la produzione dell'URI, devono (MUST) codificare in percentuale i caratteri non consentiti
  2. I caratteri riservati vengono lasciati non codificati solo quando utilizzati come delimitatori
  3. 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:

  1. Dopo l'analisi dell'URI, decodificare i componenti secondo necessità
  2. Non decodificare prematuramente (può cambiare la struttura dell'URI)
  3. 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:

  1. Codificare i caratteri non-ASCII usando UTF-8
  2. Codificare in percentuale gli ottetti risultanti
  3. Utilizzare cifre esadecimali maiuscole
  4. Non codificare i caratteri non riservati

Consumo URI:

  1. Analizzare per componente
  2. Decodificare le codifiche percentuali
  3. Interpretare gli ottetti usando UTF-8
  4. 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

CarattereScopoCodifica
SpazioSeparazione%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