Commit dc970796 authored by Bryton Lacquement's avatar Bryton Lacquement 🚪

wip

parent bf625f3a
......@@ -26,13 +26,26 @@
##############################################################################
from Products.ERP5Type.Timeout import wrap_call_object
from ZPublisher import Publish
from .WSGIPublisher import Success
call_object_orig = Publish.call_object
call_object = wrap_call_object(call_object_orig)
Publish.call_object = call_object
publish = Publish.__dict__['publish']
publish = Publish.publish
assert publish.__module__ == 'ZPublisher.Publish', repr(publish.__module__)
if publish.__name__ == 'new_publish': # already patched by Localizer/patches.py
publish = publish.__defaults__[1]
publish.__defaults__ = tuple(call_object if x is call_object_orig else x for x in publish.__defaults__)
mapply_orig = Publish.mapply
def mapply(*args, **kw):
try:
return mapply_orig(*args, **kw)
except Success as exc:
result, = exc.args or ('',)
return result
publish.__defaults__ = tuple(
call_object if x is call_object_orig else
mapply if x is mapply_orig else
x for x in publish.__defaults__)
......@@ -28,6 +28,7 @@ from six import text_type
from six.moves._thread import allocate_lock
import transaction
import zExceptions
from AccessControl.SecurityManagement import newSecurityManager
from AccessControl.SecurityManagement import noSecurityManager
from Acquisition import aq_acquire
......@@ -48,6 +49,7 @@ from zope.security.management import newInteraction
from Zope2.App.startup import validated_hook
from ZPublisher import pubevents, Retry
from ZPublisher.HTTPRequest import HTTPRequest
from ZPublisher.HTTPResponse import HTTPResponse
from ZPublisher.Iterators import IUnboundStreamIterator
from ZPublisher.mapply import mapply
from ZPublisher.WSGIPublisher import call_object as call_object_orig
......@@ -70,47 +72,40 @@ AC_LOGGER = logging.getLogger('event.AccessControl')
if 1: # upstream moved WSGIResponse to HTTPResponse.py
# According to PEP 333, WSGI applications and middleware are forbidden from
# using HTTP/1.1 "hop-by-hop" features or headers. This patch prevents Zope
# from sending 'Connection' and 'Transfer-Encoding' headers.
def finalize(self):
headers = self.headers
body = self.body
# <patch>
# There's a bug in 'App.ImageFile.index_html': when it returns a 304 status
# code, 'Content-Length' is equal to a nonzero value.
if self.status == 304:
headers.pop('content-length', None)
# Force the removal of "hop-by-hop" headers
# According to PEP 333, WSGI applications and middleware are forbidden
# from using HTTP/1.1 "hop-by-hop" features or headers.
headers.pop('Connection', None)
# </patch>
# set 204 (no content) status if 200 and response is empty
# and not streaming
if ('content-type' not in headers and
'content-length' not in headers and
not self._streaming and self.status == 200):
self.setStatus('nocontent')
if 'content-length' in headers:
# There's a bug in 'App.ImageFile.index_html': when it returns a 304
# status code, 'Content-Length' is equal to a nonzero value.
if self.status == 304:
del headers['content-length']
# set 204 (no content) status if 200 and response is empty and not
# streaming
elif ('content-type' not in headers and self.status == 200
and not self._streaming):
self.status = 204
# add content length if not streaming
content_length = headers.get('content-length')
return '%s %s' % (self.status, self.errmsg), self.listHeaders()
if content_length is None and not self._streaming:
self.setHeader('content-length', len(body))
WSGIResponse.finalize = finalize
# <patch>
# backport from Zope 4.0b1
# (see commit be5b14bd858da787c41a39e2533b0aabcd246fd5)
# </patch>
class Success(Exception):
"""
"""
zExceptions.Success = Success
return '%s %s' % (self.status, self.errmsg), self.listHeaders()
def write(self, data):
raise AttributeError(
"This method must not be used anymore and will be removed in the"
" future. Either return a stream iterator or raise"
" zExceptions.Success")
WSGIResponse.finalize = finalize
HTTPResponse.write = write
WSGIResponse.write = write
# From ZPublisher.utils
......@@ -335,15 +330,18 @@ def publish(request, module_info):
notify(pubevents.PubAfterTraversal(request))
recordMetaData(obj, request)
result = mapply(obj,
request.args,
request,
call_object,
1,
missing_name,
dont_publish_class,
request,
bind=1)
try:
result = mapply(obj,
request.args,
request,
call_object,
1,
missing_name,
dont_publish_class,
request,
bind=1)
except Success as exc:
result, = exc.args or ('',)
if result is not response:
response.setBody(result)
......@@ -388,11 +386,11 @@ def publish_module(environ, start_response,
path_info = path_info.decode('utf-8')
environ['PATH_INFO'] = path_info
with closing(BytesIO()) as stdout, closing(BytesIO()) as stderr:
if 1:
new_response = (
_response
if _response is not None
else _response_factory(stdout=stdout, stderr=stderr))
else _response_factory(stdout=None, stderr=None))
new_response._http_version = environ['SERVER_PROTOCOL'].split('/')[1]
new_response._server_version = environ.get('SERVER_SOFTWARE')
......@@ -430,9 +428,7 @@ def publish_module(environ, start_response,
IUnboundStreamIterator.providedBy(response.body):
result = response.body
else:
# If somebody used response.write, that data will be in the
# response.stdout BytesIO, so we put that before the body.
result = (response.stdout.getvalue(), response.body)
result = response.body,
for func in response.after_list:
func()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment