Skip to content

Commit

Permalink
Merge branch 'master' into fix-mkwsgiinstance
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Howitz committed Oct 23, 2018
2 parents f3c0689 + 0d6f6a4 commit 080e557
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 17 deletions.
8 changes: 8 additions & 0 deletions CHANGES.rst
Expand Up @@ -16,6 +16,14 @@ Bugfixes

- Fix `bin/mkwsgiinstance` on Python 3 when Zope was installed via ``pip``.

- Fix a bug with scopes in scripts with zconsole, which made it impossible to
reach global imports in the script within a function.

- Fix handling of non-ASCII characters in URLs on Python 2 introduced on 4.0b5.
(`#380 <https://github.com/zopefoundation/Zope/pull/380>`_)

- Fix zodbupdate conversion of ``OFS.Image.Pdata`` objects.


4.0b6 (2018-10-11)
------------------
Expand Down
4 changes: 4 additions & 0 deletions README.rst
Expand Up @@ -16,6 +16,10 @@
:target: https://pypi.org/project/Zope/
:alt: Supported Python versions

.. image:: https://requires.io/github/zopefoundation/Zope/requirements.svg?branch=master
:target: https://requires.io/github/zopefoundation/Zope/requirements/?branch=master
:alt: Requirements Status

.. contents::

Introduction
Expand Down
1 change: 1 addition & 0 deletions src/OFS/__init__.py
Expand Up @@ -9,6 +9,7 @@
'OFS.Image File title': 'utf-8',
'OFS.Image Image title': 'utf-8',
'OFS.Image Pdata title': 'utf-8',
'OFS.Image Pdata data': 'binary',
'OFS.OrderedFolder OrderedFolder title': 'utf-8',
'OFS.userfolder UserFolder title': 'utf-8',
}
7 changes: 2 additions & 5 deletions src/Products/SiteAccess/VirtualHostMonster.py
Expand Up @@ -14,6 +14,7 @@
from ZPublisher.BeforeTraverse import registerBeforeTraverse
from ZPublisher.BeforeTraverse import unregisterBeforeTraverse
from ZPublisher.BaseRequest import quote
from ZPublisher.HTTPRequest import splitport
from zExceptions import BadRequest


Expand Down Expand Up @@ -147,11 +148,7 @@ def __call__(self, client, request, response=None):
stack.pop()
protocol = stack.pop()
host = stack.pop()
if ':' in host:
host, port = host.split(':')
request.setServerURL(protocol, host, port)
else:
request.setServerURL(protocol, host)
request.setServerURL(protocol, *splitport(host))
path = list(stack)

# Find and convert VirtualHostRoot directive
Expand Down
60 changes: 60 additions & 0 deletions src/Products/SiteAccess/tests/testVirtualHostMonster.py
Expand Up @@ -139,6 +139,66 @@ def test(self, vaddr=vaddr, vr=vr, _vh=_vh, p=p, ubase=ubase):

setattr(VHMRegressions, 'testTraverse%s' % i, test)

class VHMPort(unittest.TestCase):

def setUp(self):
import transaction
from Testing.makerequest import makerequest
from Testing.ZopeTestCase.ZopeLite import app
transaction.begin()
self.app = makerequest(app())
if 'virtual_hosting' not in self.app.objectIds():
# If ZopeLite was imported, we have no default virtual
# host monster
from Products.SiteAccess.VirtualHostMonster \
import manage_addVirtualHostMonster
manage_addVirtualHostMonster(self.app, 'virtual_hosting')
self.app.manage_addFolder('folder')
self.app.folder.manage_addDTMLMethod('doc', '')
self.app.REQUEST.set('PARENTS', [self.app])
self.traverse = self.app.REQUEST.traverse

def tearDown(self):
import transaction
transaction.abort()
self.app._p_jar.close()

def testIPv4(self):
ob = self.traverse('/VirtualHostBase/http/www.mysite.com:80'
'/folder/')
self.assertEqual(self.app.REQUEST['ACTUAL_URL'],
'http://www.mysite.com/folder/')

def testIPv4Noport(self):
ob = self.traverse('/VirtualHostBase/http/www.mysite.com'
'/folder/')
self.assertEqual(self.app.REQUEST['ACTUAL_URL'],
'http://www.mysite.com/folder/')

def testPassedPortIPv4(self):
ob = self.traverse('/VirtualHostBase/http/www.mysite.com:81'
'/folder/')
self.assertEqual(self.app.REQUEST['ACTUAL_URL'],
'http://www.mysite.com:81/folder/')

def testIPv6(self):
ob = self.traverse('/VirtualHostBase/http/[::1]:80'
'/folder/')
self.assertEqual(self.app.REQUEST['ACTUAL_URL'],
'http://[::1]/folder/')

def testIPv6NoPort(self):
ob = self.traverse('/VirtualHostBase/http/[::1]'
'/folder/')
self.assertEqual(self.app.REQUEST['ACTUAL_URL'],
'http://[::1]/folder/')

def testIPv6PassedPort(self):
ob = self.traverse('/VirtualHostBase/http/[::1]:81'
'/folder/')
self.assertEqual(self.app.REQUEST['ACTUAL_URL'],
'http://[::1]:81/folder/')


class VHMAddingTests(unittest.TestCase):

Expand Down
10 changes: 4 additions & 6 deletions src/ZPublisher/WSGIPublisher.py
Expand Up @@ -241,16 +241,14 @@ def publish_module(environ, start_response,
result = ()

path_info = environ.get('PATH_INFO')
if path_info:
if path_info and PY3:
# The WSGI server automatically treats the PATH_INFO as latin-1 encoded
# bytestrings. Typically this is a false assumption as the browser
# delivers utf-8 encoded PATH_INFO. We, therefore, need to encode it
# again with latin-1 to get a utf-8 encoded bytestring. This is
# sufficient for Python 2.
# again with latin-1 to get a utf-8 encoded bytestring.
path_info = path_info.encode('latin-1')
if PY3:
# In Python 3 we need unicode here, so we decode the bytestring.
path_info = path_info.decode('utf-8')
# But in Python 3 we need text here, so we decode the bytestring.
path_info = path_info.decode('utf-8')

environ['PATH_INFO'] = path_info
with closing(BytesIO()) as stdout, closing(BytesIO()) as stderr:
Expand Down
23 changes: 22 additions & 1 deletion src/ZPublisher/tests/test_WSGIPublisher.py
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2009 Zope Foundation and Contributors.
Expand All @@ -10,6 +11,7 @@
# FOR A PARTICULAR PURPOSE
#
##############################################################################
import codecs
import io
import unittest

Expand All @@ -18,9 +20,12 @@
from zope.publisher.interfaces import INotFound
from zope.security.interfaces import IUnauthorized
from zope.security.interfaces import IForbidden
from six.moves.urllib_parse import quote

from ZPublisher.WSGIPublisher import get_module_info
from Testing.ZopeTestCase import FunctionalTestCase
from Testing.ZopeTestCase import ZopeTestCase
from ZPublisher.WSGIPublisher import get_module_info
import Testing.testbrowser


class WSGIResponseTests(unittest.TestCase):
Expand Down Expand Up @@ -543,6 +548,22 @@ def testHandleErrorsFalseBypassesExceptionResponse(self):
self._callFUT(environ, start_response, _publish)


class WSGIPublisherTests(FunctionalTestCase):

def test_can_handle_non_ascii_URLs(self):
from OFS.Image import manage_addFile
manage_addFile(self.app, 'täst', u'çöńtêñt'.encode('utf-8'))

browser = Testing.testbrowser.Browser()
browser.addHeader(
'Authorization',
'basic {}'.format(codecs.encode(
b'manager:manager_pass', 'base64').decode()))

browser.open('http://localhost/{}'.format(quote('täst')))
self.assertEqual(browser.contents.decode('utf-8'), u'çöńtêñt')


class TestLoadApp(unittest.TestCase):

def _getTarget(self):
Expand Down
14 changes: 12 additions & 2 deletions src/Zope2/utilities/tests/test_zconsole.py
Expand Up @@ -21,12 +21,20 @@

test_script = """
import sys
import OFS.PropertyManager
def print_info():
# This tests the availability of global variables and imports.
print(sys.argv[1:])
# 'PropertyManager'
print(OFS.PropertyManager.PropertyManager.__name__)
if __name__ == '__main__':
app.foo = '42'
print(app.foo)
print(sys.argv[1:])
print_info()
"""


Expand Down Expand Up @@ -75,5 +83,7 @@ def test_runscript(self):
finally:
sys.argv = self.stored_sys_argv
sys.stdout = self.stored_stdout
expected = "42\n['run', '{}', '{}', 'bar', 'baz']\n".format(self.zopeconf, script) # noqa: E501
expected = (
"42\n['run', '{}', '{}', 'bar', 'baz']\nPropertyManager\n").format(
self.zopeconf, script)
self.assertEqual(expected, got)
5 changes: 2 additions & 3 deletions src/Zope2/utilities/zconsole.py
Expand Up @@ -15,11 +15,10 @@ def runscript(zopeconf, script_name, *extra_args):
app.REQUEST['PARENTS'] = [app]
setRequest(app.REQUEST)
newSecurityManager(None, user)
scriptglobals = globals()
scriptglobals.update(__name__='__main__')
scriptglobals = {'__name__': '__main__', 'app': app}
with open(script_name) as script:
scriptcode = script.read()
exec(compile(scriptcode, script_name, 'exec'))
exec(compile(scriptcode, script_name, 'exec'), scriptglobals)


def debug(zopeconf):
Expand Down

0 comments on commit 080e557

Please sign in to comment.