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

wip

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