Opened 11 years ago

Closed 11 years ago

#20961 closed Bug (fixed)

response.write(img_buffer) does not work on Python 3

Reported by: epandurski@… Owned by: nobody
Component: Python 3 Version: dev
Severity: Release blocker Keywords:
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I have the following code in Python 2:

        response = HttpResponse(content_type='image/jpeg')
        response['Content-Encoding'] = 'identity'
        response['Content-Length'] = len(img_buffer)
        response['Cache-Control'] = "max-age=1209600"
        response.write(str(img_buffer))
        return response

I figured out that with Python 3 is should be:

        response = HttpResponse(content_type='image/jpeg')
        response['Content-Encoding'] = 'identity'
        response['Content-Length'] = len(img_buffer)
        response['Cache-Control'] = "max-age=1209600"
        response.write(img_buffer)  # I tried img_buffer.tobytes() too!!!
        return response

But I get this error:

http://dpaste.com/hold/1354227/

Change History (9)

comment:1 by Claude Paroz, 11 years ago

Resolution: needsinfo
Status: newclosed

Without knowing what exactly is img_buffer, we are unable to help.

comment:2 by anonymous, 11 years ago

Sorry. In my case "img_buffer" is memoryview object. But it does not actually matters, because it fails even with bytes. So you may consider img_buffer=b'123'.

I forgot to mention that this problem concerns 1.6b2 too.

comment:3 by anonymous, 11 years ago

Resolution: needsinfo
Status: closednew

comment:4 by Claude Paroz, 11 years ago

Unable to reproduce on my system (tested on 1.6 and master):

Python 3.2.3rc2 (default, Mar 21 2012, 05:47:04) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.http import HttpResponse
>>> img_buffer = b'123'
>>> response = HttpResponse(content_type='image/jpeg')
>>> response['Content-Encoding'] = 'identity'
>>> response['Content-Length'] = len(img_buffer)
>>> response['Cache-Control'] = "max-age=1209600"
>>> response.write(img_buffer)
>>> 
>>> buf = b'123'
>>> img_buffer = memoryview(buf)
>>> 
>>> response = HttpResponse(content_type='image/jpeg')
>>> response['Content-Encoding'] = 'identity'
>>> response['Content-Length'] = len(img_buffer)
>>> response['Cache-Control'] = "max-age=1209600"
>>> response.write(img_buffer)
>>> 

comment:5 by anonymous, 11 years ago

It seems that the problem shows somewhere in the django's request-handling chain. It seems that it is related somehow to the 'django.middleware.gzip.GZipMiddleware' middleware. When I remove it from my MIDDLEWARE_CLASSES, it breaks again but in a different way. I get 'A server error occurred. Please contact the administrator.' and see this traceback on the console:

Traceback (most recent call last):
  File "/usr/lib/python3.2/wsgiref/handlers.py", line 138, in run
    self.finish_response()
  File "/usr/lib/python3.2/wsgiref/handlers.py", line 178, in finish_response
    for data in self.result:
  File "/usr/local/lib/python3.2/dist-packages/django/http/response.py", line 292, in __next__
    return self.make_bytes(next(self._iterator))
  File "/usr/local/lib/python3.2/dist-packages/django/http/response.py", line 274, in make_bytes
    return bytes(value)
TypeError: string argument without an encoding

comment:6 by anonymous, 11 years ago

I found this (fixed) ticket that might be related (I am not sure, but at least the stack trace is the same):

https://code.djangoproject.com/ticket/20472

comment:7 by Claude Paroz, 11 years ago

Severity: NormalRelease blocker
Triage Stage: UnreviewedAccepted

I think I found the issue. Can you test that patch:

--- a/django/http/response.py
+++ b/django/http/response.py
@@ -317,7 +318,7 @@ class HttpResponse(HttpResponseBase):
 
     streaming = False
 
-    def __init__(self, content='', *args, **kwargs):
+    def __init__(self, content=b'', *args, **kwargs):
         super(HttpResponse, self).__init__(*args, **kwargs)
         # Content is a bytestring. See the `content` property methods.
         self.content = content

comment:8 by anonymous, 11 years ago

This patch seems to fix the issue (for my case at least). Thanks!

comment:9 by Claude Paroz <claude@…>, 11 years ago

Resolution: fixed
Status: newclosed

In f4e9804567ce45ef01f6613ce194e96d293ac04b:

Fixed #20961 -- Fixed HttpResponse default empty content

Thanks epandurski at gmail.com for the report.

Note: See TracTickets for help on using tickets.
Back to Top