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