Skip to content

Commit

Permalink
The PUT views should return an empty bytes string.
Browse files Browse the repository at this point in the history
If they don't, on Python 3 we run afoul of the zope.publisher rule
that says that unicode response bodies need to have a content-type.
But since the put view never sets a content type (due to being a
redirect), we get a TypeError instead:

```
  File "/py35/zope/app/wsgi/testlayer.py", line 210, in http
    response = request.get_response(wsgi_app)
  File "/py35/webob/request.py", line 1316, in send
    application, catch_exc_info=False)
  File "/py35/webob/request.py", line 1283, in call_application
    output.extend(app_iter)
  File "/py35/zope/app/wsgi/testlayer.py", line 94, in __call__
    for entry in self.wsgi_stack(environ, application_start_response):
  File "/py35/zope/app/wsgi/testlayer.py", line 68, in __call__
    for entry in self.wsgi_stack(environ, start_response):
  File "/py35/zope/app/wsgi/__init__.py", line 65, in __call__
    request = publish(request, handle_errors=handle_errors)
  File "/py35/zope/publisher/publish.py", line 148, in publish
    response.setResult(result)
  File "/py35/zope/publisher/http.py", line 796, in setResult
    r, headers = self._implicitResult(r)
  File "/py35/zope/publisher/http.py", line 821, in _implicitResult
    if not unicode_mimetypes_re.match(ct):
TypeError: expected string or bytes-like object
```

Here, `ct` is the content-type header, and its None. Returning bytes
bypasses the issue.

This was discovered testing with zope.app.file.
  • Loading branch information
jamadden committed May 12, 2017
1 parent 9bffedd commit 6abbcca
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 7 deletions.
6 changes: 4 additions & 2 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
CHANGES
=======

4.1.0 (unreleased)
4.0.1 (unreleased)
------------------

- Nothing changed yet.
- The PUT views return an empty byte string instead of an empty native
string. On Python 3, the unicode native string leads to a TypeError
in zope.publisher.http.


4.0.0 (2016-08-08)
Expand Down
4 changes: 2 additions & 2 deletions src/zope/app/http/put.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def PUT(self):
request.response.setStatus(201)
request.response.setHeader(
'Location', zope.traversing.browser.absoluteURL(newfile, request))
return ''
return b''


class FilePUT(object):
Expand All @@ -111,4 +111,4 @@ def PUT(self):
length = int(self.request.get('CONTENT_LENGTH', -1))
adapter.write(body.read(length))

return ''
return b''
6 changes: 3 additions & 3 deletions src/zope/app/http/tests/test_put.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def test_bad_content_header(self):
null = zope.app.http.put.NullResource(container, 'spam')
put = zope.app.http.put.NullPUT(null, request)
self.assertEqual(getattr(container, 'spam', None), None)
self.assertEqual(put.PUT(), '')
self.assertEqual(put.PUT(), b'')
request.response.setResult('')

# Check HTTP Response
Expand Down Expand Up @@ -136,7 +136,7 @@ def test(self):
'CONTENT_LENGTH': str(len(content)),
})
put = zope.app.http.put.FilePUT(file, request)
self.assertEqual(put.PUT(), '')
self.assertEqual(put.PUT(), b'')
request.response.setResult('')
self.assertEqual(file.data, content)

Expand All @@ -153,7 +153,7 @@ def test_bad_content_header(self):
'HTTP_CONTENT_FOO': 'Bar',
})
put = zope.app.http.put.FilePUT(file, request)
self.assertEqual(put.PUT(), '')
self.assertEqual(put.PUT(), b'')
request.response.setResult('')
self.assertEqual(file.data, content)

Expand Down

0 comments on commit 6abbcca

Please sign in to comment.