http.cookies - Cookie HTTP
Scopo: Definisce classi per elaborare e creare intestazioni cookie HTTP
Il modulo http.cookies implementa un parser per cookie che è per la maggior parte conforme a RFC 2109. L'implementazione è leggermente meno rigorosa rispetto allo standard poichè MSIE 3.0x non supporta interamente lo standard.
Creare ed Impostare un Cookie
I cookie sono usati per gestire lo stato di una applicazione basata sul browser, e come tale in genere vengono impostati dal server per essere conservati e ritornati dal client. L'esempio più triviale per la creazione di un cookie imposta una singola coppia di chiave-valore.
# http_cookies_setheaders.py
from http import cookies
c = cookies.SimpleCookie()
c['ilmiocookie'] = 'valore_del_cookie'
print(c)
L'output è una intestazione valida Set-Cookie pronta per essere passata al client come parte della risposta HTTP:
$ python3 http_cookies_setheaders.py Set-Cookie: ilmiocookie=valore_del_cookie
Bocconcini
E' anche possibile controllare altri aspetti di un cookie tipo la scadenza, il percorso, il dominio. In effetti, tutti gli attribuiti per i cookie stabiliti dall'RFC possono essere gestiti tramite l'oggetto Morsel che rappresenta il valore del cookie.
# http_cookies_Morsel.py
from http import cookies
import datetime
def show_cookie(c):
print(c)
for key, morsel in c.items():
print()
print('chiave =', morsel.key)
print(' valore =', morsel.value)
print(' valore codificato =', morsel.coded_value)
for name in morsel.keys():
if morsel[name]:
print(' {} = {}'.format(name, morsel[name]))
c = cookies.SimpleCookie()
# Un cookie con un valore che deve essere codificato
# per essere inserito nell'intestazione
c['cookie_con_valore_codificato'] = '"cookie,valore;"'
c['cookie_con_valore_codificato']['comment'] = \
'Ha punteggiatura da gestire con codici di escape'
# Un cookie che si applica solo a parte di un sito
c['cookie_limitato'] = 'valore_cookie'
c['cookie_limitato']['path'] = '/sub/path'
c['cookie_limitato']['domain'] = 'PyMOTW'
c['cookie_limitato']['secure'] = True
# Un cookie che scade in 5 minuti
c['con_durata_massima'] = 'scade fra 5 minuti'
c['con_durata_massima']['max-age'] = 300 # secondi
# Un cookie che scade ad un determinato tempo
c['scade_ad_un_dato_tempo'] = 'valore_cookie'
time_to_live = datetime.timedelta(hours=1)
expires = (datetime.datetime(2009, 2, 14, 18, 30, 14) +
time_to_live)
# Formato data: Wdy, DD-Mon-YY HH:MM:SS GMT
expires_at_time = expires.strftime('%a, %d %b %Y %H:%M:%S')
c['scade_ad_un_dato_tempo']['expires'] = expires_at_time
show_cookie(c)
Questo esempio include due modi diversi per impostare la conservazione di cookie che scadono. Uno imposta max-age ad un numero di secondi, l'altro imposta expires alla data ed ora di scadenza nella quale il cookie deve essere eliminato.
$ python3 http_cookies_Morsel.py Set-Cookie: con_durata_massima="scade fra 5 minuti"; Max-Age=300 Set-Cookie: cookie_con_valore_codificato="\"cookie\054valore\073\""; Comment=Ha punteggiatura da gestire con codici di escape Set-Cookie: cookie_limitato=valore_cookie; Domain=PyMOTW; Path=/sub/path; Secure Set-Cookie: scade_ad_un_dato_tempo=valore_cookie; expires=Sat, 14 Feb 2009 19:30:14 chiave = cookie_con_valore_codificato valore = "cookie,valore;" valore codificato = "\"cookie\054valore\073\"" comment = Ha punteggiatura da gestire con codici di escape chiave = scade_ad_un_dato_tempo valore = valore_cookie valore codificato = valore_cookie expires = Sat, 14 Feb 2009 19:30:14 chiave = con_durata_massima valore = scade fra 5 minuti valore codificato = "scade fra 5 minuti" max-age = 300 chiave = cookie_limitato valore = valore_cookie valore codificato = valore_cookie secure = True path = /sub/path domain = PyMOTW
Gli oggetti Cookie e Morsel agiscono come dizionari. Morsel risponde ad un insieme fisso di chiavi.
- comment
- domain
- expires
- max-age
- path
- secure
- version
Le chiavi per una istanza di Cookie sono i nomi dei singoli cookie che vengono memorizzati. Quell'informazione è anche disponibile dall'attributo key di Morsel.
Valori codificati
L'intestazione dei cookie deve avere i valori codificati in modo che possano essere elaborati correttamente.
# http_cookies_coded_value.py
from http import cookies
c = cookies.SimpleCookie()
c['intero'] = 5
c['con_virgolette'] = 'Disse, "Ciao, Mondo!"'
for name in ['intero', 'con_virgolette']:
print(c[name].key)
print(' {}'.format(c[name]))
print(' value={!r}'.format(c[name].value))
print(' coded_value={!r}'.format(c[name].coded_value))
print()
Morsel.value è sempre il valore decodificato del cookie, mentre Morsel.coded_value è sempre la rappresentazione da usare per trasmettere il valore al client. Entrambi i valori sono sempre stringhe. I valori salvati in un cookie che non sono stringhe sono convertiti automaticamente.
$ python3 http_cookies_coded_value.py intero Set-Cookie: intero=5 value='5' coded_value='5' con_virgolette Set-Cookie: con_virgolette="Disse\054 \"Ciao\054 Mondo!\"" value='Disse, "Ciao, Mondo!"' coded_value='"Disse\\054 \\"Ciao\\054 Mondo!\\""'
Ricevere e Passare Intestazioni di Cookie
Una volta che le intestazioni in Set-Cookie sono ricevute dal client, esso restituirà al server quei cookie alle successive richieste usando una intestazione Cookie. Una stringa di intestazione Cookie che perviene può contenere parecchi valori di cookie, separati da punto e virgola (;).
Cookie: intero=5; con_virgolette="Disse, \"Ciao, Mondo!\""
A seconda del server web e del framework, i cookie sono disponibili direttamente dalle intestazioni oppure dalla variabile di ambiente HTTP_COOKIE.
# http_cookies_parse.py
from http import cookies
HTTP_COOKIE = '; '.join([
r'intero=5',
r'con_virgolette="Disse, \"Ciao, Mondo!\""',
])
print('Dal Costruttore:')
c = cookies.SimpleCookie(HTTP_COOKIE)
print(c)
print()
print('Da load():')
c = cookies.SimpleCookie()
c.load(HTTP_COOKIE)
print(c)
Per decodificarli, si passi la stringa senza il prefisso di intestazione a SimpleCookie quando lo si istanzia, oppure si usi il metodo load().
$ python3 http_cookies_parse.py Dal Costruttore: Set-Cookie: con_virgolette="Disse, \"Ciao, Mondo!\"" Set-Cookie: intero=5 Da load(): Set-Cookie: con_virgolette="Disse, \"Ciao, Mondo!\"" Set-Cookie: intero=5
Formati di Uscita Alternativi
A parte l'utilizzo dell'intestazione Set-Cookie, i server potrebbero passare del codice Javascript che aggiunge i cookie al client. SimpleCookie e Morsel forniscono un output come codice Javascript tramite il metodo js_output().
# http_cookies_js_output.py
from http import cookies
import textwrap
c = cookies.SimpleCookie()
c['ilmiocookie'] = 'valore del cookie'
c['altro_cookie'] = 'secondo valore'
js_text = c.js_output()
print(textwrap.dedent(js_text).lstrip())
Il risultato è un tag script completo con le istruzioni per impostare i cookie.
$ python3 http_cookies_js_output.py <script type="text/javascript"> <!-- begin hiding document.cookie = "altro_cookie=\"secondo valore\""; // end hiding --> </script> <script type="text/javascript"> <!-- begin hiding document.cookie = "ilmiocookie=\"valore del cookie\""; // end hiding --> </script>
Vedere anche:
- http.cookies
- La documentazione della libreria standard per questo modulo
- http.cookiejar
- Il modulo cookielib, per lavorare sui cookie lato client.
- RFC 2109
- Il meccanismo di gestione della stato in HTTP