Opened 2 years ago

Closed 2 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: master
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 Changed 2 years ago by claudep

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to needsinfo
  • Status changed from new to closed

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

comment:2 Changed 2 years ago by anonymous

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 Changed 2 years ago by anonymous

  • Resolution needsinfo deleted
  • Status changed from closed to new

comment:4 Changed 2 years ago by claudep

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 Changed 2 years ago by anonymous

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 Changed 2 years ago by anonymous

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 Changed 2 years ago by claudep

  • Severity changed from Normal to Release blocker
  • Triage Stage changed from Unreviewed to Accepted

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 Changed 2 years ago by anonymous

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

comment:9 Changed 2 years ago by Claude Paroz <claude@…>

  • Resolution set to fixed
  • Status changed from new to closed

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