#9180: Low-level cache interface incorrectly tries to typecast bytestring
--------------------------+-------------------------------------------------
 Reporter:  p             |       Owner:  nobody    
   Status:  new           |   Milestone:            
Component:  Cache system  |     Version:  1.0       
 Keywords:                |       Stage:  Unreviewed
Has_patch:  0             |  
--------------------------+-------------------------------------------------
 The low-level Django cache API encodes basestrings as UTF-8 when
 {{{set}}}ting, and decodes basestrings as Unicode when {{{get}}}ting.

 If you're trying to store a string of bytes in the cache -- for instance,
 the raw bytes of an image -- the set operation will possibly modify the
 data by encoding it, and the get operation will potentially raise a
 !DjangoUnicodeDecodeError if the codec can't decode bytes in the string.

 {{{
 #!python
 from django.core.cache import cache
 from django.utils.encoding import DjangoUnicodeDecodeError

 # The simplest possible GIF: a 43-byte, 1x1-pixel transparent image
 EMPTY_GIF_BYTES =
 
'GIF89a\x01\x00\x01\x00\xf0\x00\x00\xb0\x8cZ\x00\x00\x00!\xf9\x04\x00\x00\x00\x00\x00,\x00\x00\x00\x00\x01\x00\x01\x00\x00\x02\x02D\x01\x00;'

 cache.set('empty_gif', EMPTY_GIF_BYTES)

 try:
     cache.get('empty_gif')
 except DjangoUnicodeDecodeError:
     print 'Tried to decode GIF bytestring as a Unicode string'
 else:
     print 'Got the raw GIF bytestring'
 }}}

 A workaround is to create a one-tuple from the bytestring when storing,
 and when retrieving, returning the single element from the tuple.

 {{{
 #!python

 def raw_cache_set(key, value, timeout_seconds=None):
     cache.set(key, (value,), timeout_seconds=timeout_seconds)

 def raw_cache_get(key):
     value = cache.get(key)
     if value is not None:
         return value[0]

 raw_cache_set('empty_gif', EMPTY_GIF_BYTES)

 assert raw_cache_get('empty_gif') == EMPTY_GIF_BYTES
 }}}

 One possible fix would be to expose a {{{raw}}} keyword argument boolean
 to {{{cache.get}}}, {{{cache.set}}}, {{{cache.add}}}, {{{cache.get_many}}}
 that would conditionally skip any {{{smart_unicode}}} or other
 encoding/decoding logic when storing or retrieving from the cache.

-- 
Ticket URL: <http://code.djangoproject.com/ticket/9180>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to