Commit 8e52f973 authored by Hanno Schlichting's avatar Hanno Schlichting

Add new `Zope2.Startup.config` module to hold configuration.

This avoids various import dependencies between the Startup code
and ZServer/webdav.
parent eec9a477
...@@ -21,6 +21,8 @@ Features Added ...@@ -21,6 +21,8 @@ Features Added
Restructuring Restructuring
+++++++++++++ +++++++++++++
- Add new `Zope2.Startup.config` module to hold configuration.
- Remove `Control_Panel` `/DebugInfo` and `/DavLocks`. - Remove `Control_Panel` `/DebugInfo` and `/DavLocks`.
- Remove profiling support via `publisher-profile-file` directive. - Remove profiling support via `publisher-profile-file` directive.
......
...@@ -28,8 +28,8 @@ def shutdown(exit_code,fast = 0): ...@@ -28,8 +28,8 @@ def shutdown(exit_code,fast = 0):
global _shutdown_timeout global _shutdown_timeout
if _shutdown_phase == 0: if _shutdown_phase == 0:
# Thread safety? proably no need to care # Thread safety? proably no need to care
import ZServer from Zope2.Startup import config
ZServer.exit_code = exit_code config.ZSERVER_EXIT_CODE = exit_code
_shutdown_phase = 1 _shutdown_phase = 1
if fast: if fast:
# Someone wants us to shutdown fast. This is hooked into SIGTERM - so # Someone wants us to shutdown fast. This is hooked into SIGTERM - so
......
...@@ -23,7 +23,7 @@ dummyLOG = StringIO() ...@@ -23,7 +23,7 @@ dummyLOG = StringIO()
def setNumberOfThreads(number_of_threads): def setNumberOfThreads(number_of_threads):
'''Sets number of ZServer threads.''' '''Sets number of ZServer threads.'''
try: try:
from ZServer.PubCore import setNumberOfThreads from Zope2.Startup.config import setNumberOfThreads
setNumberOfThreads(number_of_threads) setNumberOfThreads(number_of_threads)
except ImportError: except ImportError:
pass pass
......
...@@ -560,12 +560,13 @@ class HTTPResponse(BaseResponse): ...@@ -560,12 +560,13 @@ class HTTPResponse(BaseResponse):
# The following two methods are part of a private protocol with the # The following two methods are part of a private protocol with the
# publisher for handling fatal import errors and TTW shutdown requests. # publisher for handling fatal import errors and TTW shutdown requests.
_shutdown_flag = None _shutdown_flag = None
def _requestShutdown(self, exitCode=0): def _requestShutdown(self, exitCode=0):
""" Request that the server shut down with exitCode after fulfilling """ Request that the server shut down with exitCode after fulfilling
the current request. the current request.
""" """
import ZServer from Zope2.Startup import config
ZServer.exit_code = exitCode config.ZSERVER_EXIT_CODE = exitCode
self._shutdown_flag = 1 self._shutdown_flag = 1
def _shutdownRequested(self): def _shutdownRequested(self):
...@@ -573,7 +574,6 @@ class HTTPResponse(BaseResponse): ...@@ -573,7 +574,6 @@ class HTTPResponse(BaseResponse):
""" """
return self._shutdown_flag is not None return self._shutdown_flag is not None
def _encode_unicode(self,body, def _encode_unicode(self,body,
charset_re=re.compile( charset_re=re.compile(
r'(?:application|text)/[-+0-9a-z]+\s*;\s*' + r'(?:application|text)/[-+0-9a-z]+\s*;\s*' +
......
...@@ -88,10 +88,10 @@ def get_http_header_max_length(): ...@@ -88,10 +88,10 @@ def get_http_header_max_length():
class zhttp_collector: class zhttp_collector:
def __init__(self, handler, request, size): def __init__(self, handler, request, size):
from ZServer import LARGE_FILE_THRESHOLD from Zope2.Startup.config import ZSERVER_LARGE_FILE_THRESHOLD
self.handler = handler self.handler = handler
self.request = request self.request = request
if size > LARGE_FILE_THRESHOLD: if size > ZSERVER_LARGE_FILE_THRESHOLD:
# write large upload data to a file # write large upload data to a file
from tempfile import TemporaryFile from tempfile import TemporaryFile
self.data = TemporaryFile('w+b') self.data = TemporaryFile('w+b')
......
...@@ -44,6 +44,8 @@ from ZPublisher.HTTPRequest import HTTPRequest ...@@ -44,6 +44,8 @@ from ZPublisher.HTTPRequest import HTTPRequest
from Producers import ShutdownProducer, LoggingProducer, CallbackProducer from Producers import ShutdownProducer, LoggingProducer, CallbackProducer
import DebugLogger import DebugLogger
from Zope2.Startup import config
from cStringIO import StringIO from cStringIO import StringIO
from tempfile import TemporaryFile from tempfile import TemporaryFile
import socket, string, os, sys, time import socket, string, os, sys, time
...@@ -388,9 +390,11 @@ class PCGIPipe: ...@@ -388,9 +390,11 @@ class PCGIPipe:
lambda t=('E', id(self._channel)): apply(DebugLogger.log,t)), 0) lambda t=('E', id(self._channel)): apply(DebugLogger.log,t)), 0)
if self._shutdown: if self._shutdown:
try: r=self._shutdown[0] try:
except: r=0 r = self._shutdown[0]
ZServer.exit_code=r except:
r = 0
config.ZSERVER_EXIT_CODE = r
self._channel.push(ShutdownProducer(), 0) self._channel.push(ShutdownProducer(), 0)
Wakeup(lambda: asyncore.close_all()) Wakeup(lambda: asyncore.close_all())
else: else:
......
...@@ -11,22 +11,19 @@ ...@@ -11,22 +11,19 @@
# #
############################################################################## ##############################################################################
import ZRendezvous from Zope2.Startup.config import ( # NOQA
setNumberOfThreads,
ZSERVER_THREADS as _n,
)
from ZServer.PubCore import ZRendezvous
_handle = None
_handle=None
_n=1
def handle(*args, **kw): def handle(*args, **kw):
global _handle global _handle
if _handle is None: _handle=ZRendezvous.ZRendevous(_n).handle if _handle is None:
_handle = ZRendezvous.ZRendevous(_n).handle
return apply(_handle, args, kw)
def setNumberOfThreads(n): return _handle(*args, **kw)
"""This function will self-destruct in 4 statements.
"""
global _n
_n=n
global setNumberOfThreads
del setNumberOfThreads
...@@ -11,26 +11,18 @@ ...@@ -11,26 +11,18 @@
# #
############################################################################## ##############################################################################
import sys
import utils import utils
######################################################### from Zope2.Startup.config import ( # NOQA
### declarations used by external packages ZSERVER_CONNECTION_LIMIT as CONNECTION_LIMIT,
ZSERVER_EXIT_CODE as exit_code,
# the exit code used to exit a Zope process cleanly ZSERVER_LARGE_FILE_THRESHOLD as LARGE_FILE_THRESHOLD,
exit_code = 0 setNumberOfThreads,
)
# the ZServer version number # the ZServer version number
ZSERVER_VERSION = '1.1' ZSERVER_VERSION = '1.1'
# the maximum number of incoming connections to ZServer
CONNECTION_LIMIT = 1000 # may be reset by max_listen_sockets handler in Zope
# request bigger than this size get saved into a
# temporary file instead of being read completely into memory
LARGE_FILE_THRESHOLD = 1 << 19 # may be reset by large_file_threshold
# handler in Zope
# the Zope version string # the Zope version string
ZOPE_VERSION = utils.getZopeVersion() ZOPE_VERSION = utils.getZopeVersion()
...@@ -42,17 +34,11 @@ from HTTPServer import zhttp_server, zhttp_handler ...@@ -42,17 +34,11 @@ from HTTPServer import zhttp_server, zhttp_handler
from PCGIServer import PCGIServer from PCGIServer import PCGIServer
from FCGIServer import FCGIServer from FCGIServer import FCGIServer
from FTPServer import FTPServer from FTPServer import FTPServer
from PubCore import setNumberOfThreads
from medusa.monitor import secure_monitor_server from medusa.monitor import secure_monitor_server
### end declarations
##########################################################
# we need to patch asyncore's dispatcher class with a new # we need to patch asyncore's dispatcher class with a new
# log_info method so we see medusa messages in the zLOG log # log_info method so we see medusa messages in the zLOG log
utils.patchAsyncoreLogger() utils.patchAsyncoreLogger()
# we need to patch the 'service name' of the medusa syslog logger # we need to patch the 'service name' of the medusa syslog logger
utils.patchSyslogServiceName() utils.patchSyslogServiceName()
...@@ -48,7 +48,8 @@ from urllib import unquote ...@@ -48,7 +48,8 @@ from urllib import unquote
# The ZConfig machinery may sets this attribute on initialization # The ZConfig machinery may sets this attribute on initialization
# if any trusted-proxies # if any trusted-proxies
trusted_proxies = [] from Zope2.Startup.config import TRUSTED_PROXIES as trusted_proxies # NOQA
class http_request: class http_request:
......
...@@ -26,6 +26,8 @@ from ZConfig.components.logger import loghandler ...@@ -26,6 +26,8 @@ from ZConfig.components.logger import loghandler
from zope.event import notify from zope.event import notify
from zope.processlifetime import ProcessStarting from zope.processlifetime import ProcessStarting
import Zope2.Startup.config
try: try:
IO_ERRORS = (IOError, WindowsError) IO_ERRORS = (IOError, WindowsError)
except NameError: except NameError:
...@@ -35,6 +37,7 @@ except NameError: ...@@ -35,6 +37,7 @@ except NameError:
logger = logging.getLogger("Zope") logger = logging.getLogger("Zope")
started = False started = False
def get_starter(): def get_starter():
if sys.platform[:3].lower() == "win": if sys.platform[:3].lower() == "win":
return WindowsZopeStarter() return WindowsZopeStarter()
...@@ -105,10 +108,10 @@ class ZopeStarter: ...@@ -105,10 +108,10 @@ class ZopeStarter:
try: try:
from App.config import getConfiguration from App.config import getConfiguration
config = getConfiguration() config = getConfiguration()
import ZServer
import Lifetime import Lifetime
Lifetime.loop() Lifetime.loop()
sys.exit(ZServer.exit_code) from Zope2.Startup.config import ZSERVER_EXIT_CODE
sys.exit(ZSERVER_EXIT_CODE)
finally: finally:
self.shutdown() self.shutdown()
...@@ -137,10 +140,11 @@ class ZopeStarter: ...@@ -137,10 +140,11 @@ class ZopeStarter:
ZPublisher.Publish.set_default_authentication_realm( ZPublisher.Publish.set_default_authentication_realm(
self.cfg.http_realm) self.cfg.http_realm)
if self.cfg.trusted_proxies: if self.cfg.trusted_proxies:
# DM 2004-11-24: added host name mapping (such that examples in conf file really have a chance to work
mapped = [] mapped = []
for name in self.cfg.trusted_proxies: mapped.extend(_name2Ips(name)) for name in self.cfg.trusted_proxies:
mapped.extend(_name2Ips(name))
ZPublisher.HTTPRequest.trusted_proxies = tuple(mapped) ZPublisher.HTTPRequest.trusted_proxies = tuple(mapped)
Zope2.Startup.config.TRUSTED_PROXIES = tuple(mapped)
def setupSecurityOptions(self): def setupSecurityOptions(self):
import AccessControl import AccessControl
...@@ -183,9 +187,9 @@ class ZopeStarter: ...@@ -183,9 +187,9 @@ class ZopeStarter:
def setupZServer(self): def setupZServer(self):
# Increase the number of threads # Increase the number of threads
import ZServer Zope2.Startup.config.setNumberOfThreads(self.cfg.zserver_threads)
ZServer.setNumberOfThreads(self.cfg.zserver_threads) Zope2.Startup.config.ZSERVER_CONNECTION_LIMIT = \
ZServer.CONNECTION_LIMIT = self.cfg.max_listen_sockets self.cfg.max_listen_sockets
def serverListen(self): def serverListen(self):
for server in self.cfg.servers: for server in self.cfg.servers:
......
##############################################################################
#
# Copyright (c) 2002 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
TRUSTED_PROXIES = []
ZSERVER_CONNECTION_LIMIT = 1000
ZSERVER_ENABLE_MS_PUBLIC_HEADER = False
ZSERVER_EXIT_CODE = 0
ZSERVER_LARGE_FILE_THRESHOLD = 524288
ZSERVER_THREADS = 1
def setNumberOfThreads(n):
"""This function will self-destruct in 4 statements.
"""
global ZSERVER_THREADS
ZSERVER_THREADS = n
global setNumberOfThreads
del setNumberOfThreads
import os import os
import re
import sys import sys
from re import compile
from socket import gethostbyaddr from socket import gethostbyaddr
# top-level key handlers from Zope2.Startup import config
# XXX I suspect there are still problems here. In most cases, if the
# value is not set from the config file, or if the value is the
# default, the corresponding envvar is not unset, which is needed to
# ensure that the environment variables and the configuration values
# reflect a coherant configuration.
def _setenv(name, value): def _setenv(name, value):
if isinstance(value, str): if isinstance(value, str):
os.environ[name] = value os.environ[name] = value
else: else:
os.environ[name] = `value` os.environ[name] = repr(value)
def debug_mode(value): def debug_mode(value):
value and _setenv('Z_DEBUG_MODE', '1') value and _setenv('Z_DEBUG_MODE', '1')
return value return value
def locale(value): def locale(value):
import locale import locale
locale.setlocale(locale.LC_ALL, value) locale.setlocale(locale.LC_ALL, value)
return value return value
def datetime_format(value): def datetime_format(value):
value and _setenv('DATETIME_FORMAT', value) value and _setenv('DATETIME_FORMAT', value)
return value return value
def automatically_quote_dtml_request_data(value): def automatically_quote_dtml_request_data(value):
not value and _setenv('ZOPE_DTML_REQUEST_AUTOQUOTE', '0') not value and _setenv('ZOPE_DTML_REQUEST_AUTOQUOTE', '0')
return value return value
def maximum_number_of_session_objects(value): def maximum_number_of_session_objects(value):
default = 1000 default = 1000
value not in (None, default) and _setenv('ZSESSION_OBJECT_LIMIT', value) value not in (None, default) and _setenv('ZSESSION_OBJECT_LIMIT', value)
return value return value
def session_add_notify_script_path(value): def session_add_notify_script_path(value):
value is not None and _setenv('ZSESSION_ADD_NOTIFY', value) value is not None and _setenv('ZSESSION_ADD_NOTIFY', value)
return value return value
def session_delete_notify_script_path(value): def session_delete_notify_script_path(value):
value is not None and _setenv('ZSESSION_DEL_NOTIFY', value) value is not None and _setenv('ZSESSION_DEL_NOTIFY', value)
return value return value
def session_timeout_minutes(value): def session_timeout_minutes(value):
default = 20 default = 20
value not in (None, default) and _setenv('ZSESSION_TIMEOUT_MINS', value) value not in (None, default) and _setenv('ZSESSION_TIMEOUT_MINS', value)
return value return value
def large_file_threshold(value): def large_file_threshold(value):
import ZServer config.ZSERVER_LARGE_FILE_THRESHOLD = value
ZServer.LARGE_FILE_THRESHOLD = value
def http_realm(value): def http_realm(value):
value is not None and _setenv('Z_REALM', value) value is not None and _setenv('Z_REALM', value)
return value return value
def max_listen_sockets(value): def max_listen_sockets(value):
import ZServer config.ZSERVER_CONNECTION_LIMIT = value
ZServer.CONNECTION_LIMIT = value
def cgi_maxlen(value): def cgi_maxlen(value):
import cgi import cgi
cgi.maxlen = value cgi.maxlen = value
def http_header_max_length(value): def http_header_max_length(value):
return value return value
def enable_ms_public_header(value): def enable_ms_public_header(value):
import webdav config.ZSERVER_ENABLE_MS_PUBLIC_HEADER = value
webdav.enable_ms_public_header = value
# server handlers
def root_handler(config): def root_handler(cfg):
""" Mutate the configuration with defaults and perform """ Mutate the configuration with defaults and perform
fixups of values that require knowledge about configuration fixups of values that require knowledge about configuration
values outside of their context. values outside of their context.
""" """
# Set environment variables # Set environment variables
for k,v in config.environment.items(): for k, v in cfg.environment.items():
os.environ[k] = v os.environ[k] = v
# Add directories to the pythonpath # Add directories to the pythonpath
instancelib = os.path.join(config.instancehome, 'lib', 'python') instancelib = os.path.join(cfg.instancehome, 'lib', 'python')
if instancelib not in config.path: if instancelib not in cfg.path:
if os.path.isdir(instancelib): if os.path.isdir(instancelib):
config.path.append(instancelib) cfg.path.append(instancelib)
path = config.path[:] path = cfg.path[:]
path.reverse() path.reverse()
for dir in path: for dir in path:
sys.path.insert(0, dir) sys.path.insert(0, dir)
...@@ -101,56 +105,55 @@ def root_handler(config): ...@@ -101,56 +105,55 @@ def root_handler(config):
# Add any product directories not already in Products.__path__. # Add any product directories not already in Products.__path__.
# Directories are added in the order they are mentioned # Directories are added in the order they are mentioned
instanceprod = os.path.join(config.instancehome, 'Products') instanceprod = os.path.join(cfg.instancehome, 'Products')
if instanceprod not in config.products: if instanceprod not in cfg.products:
if os.path.isdir(instanceprod): if os.path.isdir(instanceprod):
config.products.append(instanceprod) cfg.products.append(instanceprod)
import Products import Products
L = [] L = []
for d in config.products + Products.__path__: for d in cfg.products + Products.__path__:
if d not in L: if d not in L:
L.append(d) L.append(d)
Products.__path__[:] = L Products.__path__[:] = L
# if no servers are defined, create default http server and ftp server # if no servers are defined, create default http server and ftp server
if not config.servers: if not cfg.servers:
config.servers = [] cfg.servers = []
# prepare servers: # prepare servers:
for factory in config.servers: for factory in cfg.servers:
factory.prepare(config.ip_address or '', factory.prepare(cfg.ip_address or '',
config.dns_resolver, cfg.dns_resolver,
"Zope2", "Zope2",
config.cgi_environment, cfg.cgi_environment,
config.port_base) cfg.port_base)
# set up trusted proxies # set up trusted proxies
if config.trusted_proxies: if cfg.trusted_proxies:
from ZPublisher import HTTPRequest
from ZServer.medusa import http_server
# DM 2004-11-24: added host name mapping (such that examples in
# conf file really have a chance to work
mapped = [] mapped = []
for name in config.trusted_proxies: mapped.extend(_name2Ips(name)) for name in cfg.trusted_proxies:
mapped.extend(_name2Ips(name))
config.TRUSTED_PROXIES = tuple(mapped)
from ZPublisher import HTTPRequest
HTTPRequest.trusted_proxies = tuple(mapped) HTTPRequest.trusted_proxies = tuple(mapped)
http_server.trusted_proxies = tuple(mapped)
# set the maximum number of ConflictError retries # set the maximum number of ConflictError retries
if config.max_conflict_retries: if cfg.max_conflict_retries:
from ZPublisher import HTTPRequest from ZPublisher import HTTPRequest
HTTPRequest.retry_max_count = config.max_conflict_retries HTTPRequest.retry_max_count = cfg.max_conflict_retries
def handleConfig(config, multihandler): def handleConfig(cfg, multihandler):
handlers = {} handlers = {}
for name, value in globals().items(): for name, value in globals().items():
if not name.startswith('_'): if not name.startswith('_'):
handlers[name] = value handlers[name] = value
return multihandler(handlers) return multihandler(handlers)
# DM 2004-11-24: added
def _name2Ips(host, isIp_=compile(r'(\d+\.){3}').match): def _name2Ips(host, isIp_=re.compile(r'(\d+\.){3}').match):
"""Map a name *host* to the sequence of its ip addresses. """Map a name *host* to the sequence of its ip addresses.
use *host* itself (as sequence) if it already is an ip address. use *host* itself (as sequence) if it already is an ip address.
......
...@@ -179,8 +179,8 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase): ...@@ -179,8 +179,8 @@ class ZopeStarterTestCase(LoggingTestHelper, unittest.TestCase):
zserver-threads 10""") zserver-threads 10""")
starter = self.get_starter(conf) starter = self.get_starter(conf)
starter.setupZServer() starter.setupZServer()
from ZServer.PubCore import _n from Zope2.Startup.config import ZSERVER_THREADS
self.assertEqual(_n, 10) self.assertEqual(ZSERVER_THREADS, 10)
def testSetupServers(self): def testSetupServers(self):
# We generate a random port number to test against, so that multiple # We generate a random port number to test against, so that multiple
......
...@@ -105,26 +105,26 @@ class StartupTestCase(unittest.TestCase): ...@@ -105,26 +105,26 @@ class StartupTestCase(unittest.TestCase):
self.assertEqual(items, [("FEARFACTORY", "rocks"), ("NSYNC","doesnt")]) self.assertEqual(items, [("FEARFACTORY", "rocks"), ("NSYNC","doesnt")])
def test_ms_public_header(self): def test_ms_public_header(self):
import webdav from Zope2.Startup import config
from Zope2.Startup.handlers import handleConfig from Zope2.Startup.handlers import handleConfig
default_setting = webdav.enable_ms_public_header default_setting = config.ZSERVER_ENABLE_MS_PUBLIC_HEADER
try: try:
conf, handler = self.load_config_text("""\ conf, handler = self.load_config_text("""\
instancehome <<INSTANCE_HOME>> instancehome <<INSTANCE_HOME>>
enable-ms-public-header true enable-ms-public-header true
""") """)
handleConfig(None, handler) handleConfig(None, handler)
self.assert_(webdav.enable_ms_public_header == True) self.assertTrue(config.ZSERVER_ENABLE_MS_PUBLIC_HEADER)
conf, handler = self.load_config_text("""\ conf, handler = self.load_config_text("""\
instancehome <<INSTANCE_HOME>> instancehome <<INSTANCE_HOME>>
enable-ms-public-header false enable-ms-public-header false
""") """)
handleConfig(None, handler) handleConfig(None, handler)
self.assert_(webdav.enable_ms_public_header == False) self.assertFalse(config.ZSERVER_ENABLE_MS_PUBLIC_HEADER)
finally: finally:
webdav.enable_ms_public_header = default_setting config.ZSERVER_ENABLE_MS_PUBLIC_HEADER = default_setting
def test_path(self): def test_path(self):
p1 = tempfile.mktemp() p1 = tempfile.mktemp()
......
...@@ -105,7 +105,7 @@ class NullResource(Persistent, Implicit, Resource): ...@@ -105,7 +105,7 @@ class NullResource(Persistent, Implicit, Resource):
def PUT(self, REQUEST, RESPONSE): def PUT(self, REQUEST, RESPONSE):
"""Create a new non-collection resource. """Create a new non-collection resource.
""" """
from ZServer import LARGE_FILE_THRESHOLD from Zope2.Startup.config import ZSERVER_LARGE_FILE_THRESHOLD
self.dav__init(REQUEST, RESPONSE) self.dav__init(REQUEST, RESPONSE)
...@@ -125,8 +125,9 @@ class NullResource(Persistent, Implicit, Resource): ...@@ -125,8 +125,9 @@ class NullResource(Persistent, Implicit, Resource):
raise PreconditionFailed raise PreconditionFailed
# SDS: Only use BODY if the file size is smaller than # SDS: Only use BODY if the file size is smaller than
# LARGE_FILE_THRESHOLD, otherwise read LARGE_FILE_THRESHOLD # ZSERVER_LARGE_FILE_THRESHOLD, otherwise read
# bytes from the file which should be enough to trigger # ZSERVER_LARGE_FILE_THRESHOLD bytes from the file
# which should be enough to trigger
# content_type detection, and possibly enough for CMF's # content_type detection, and possibly enough for CMF's
# content_type_registry too. # content_type_registry too.
# #
...@@ -142,7 +143,8 @@ class NullResource(Persistent, Implicit, Resource): ...@@ -142,7 +143,8 @@ class NullResource(Persistent, Implicit, Resource):
# REQUEST['BODYFILE'] directly and try as much as possible not # REQUEST['BODYFILE'] directly and try as much as possible not
# to read the whole file into memory. # to read the whole file into memory.
if int(REQUEST.get('CONTENT_LENGTH') or 0) > LARGE_FILE_THRESHOLD: if (int(REQUEST.get('CONTENT_LENGTH') or 0) >
ZSERVER_LARGE_FILE_THRESHOLD):
file = REQUEST['BODYFILE'] file = REQUEST['BODYFILE']
body = file.read(LARGE_FILE_THRESHOLD) body = file.read(LARGE_FILE_THRESHOLD)
file.seek(0) file.seek(0)
......
...@@ -40,6 +40,7 @@ from zExceptions import Forbidden ...@@ -40,6 +40,7 @@ from zExceptions import Forbidden
from zExceptions import MethodNotAllowed from zExceptions import MethodNotAllowed
from zExceptions import NotFound from zExceptions import NotFound
from zExceptions import Unauthorized from zExceptions import Unauthorized
import Zope2.Startup.config
from ZPublisher.HTTPRangeSupport import HTTPRangeInterface from ZPublisher.HTTPRangeSupport import HTTPRangeInterface
from zope.interface import implements from zope.interface import implements
...@@ -235,7 +236,7 @@ class Resource(Base, LockableItem): ...@@ -235,7 +236,7 @@ class Resource(Base, LockableItem):
# Microsoft Web Folders compatibility, only enabled if # Microsoft Web Folders compatibility, only enabled if
# User-Agent matches. # User-Agent matches.
if ms_dav_agent.match(REQUEST.get_header('User-Agent', '')): if ms_dav_agent.match(REQUEST.get_header('User-Agent', '')):
if webdav.enable_ms_public_header: if Zope2.Startup.config.ZSERVER_ENABLE_MS_PUBLIC_HEADER:
RESPONSE.setHeader('Public', ', '.join(self.__http_methods__)) RESPONSE.setHeader('Public', ', '.join(self.__http_methods__))
RESPONSE.setStatus(200) RESPONSE.setStatus(200)
......
...@@ -35,4 +35,6 @@ ...@@ -35,4 +35,6 @@
Jensen, "HTTP Extensions for Distributed Authoring - WebDAV." RFC 2518. Jensen, "HTTP Extensions for Distributed Authoring - WebDAV." RFC 2518.
Microsoft, U.C. Irvine, Netscape, Novell. February, 1999.""" Microsoft, U.C. Irvine, Netscape, Novell. February, 1999."""
enable_ms_public_header = False from Zope2.Startup.config import ( # NOQA
ZSERVER_ENABLE_MS_PUBLIC_HEADER as enable_ms_public_header,
)
...@@ -5,9 +5,9 @@ from AccessControl.SecurityManagement import noSecurityManager ...@@ -5,9 +5,9 @@ from AccessControl.SecurityManagement import noSecurityManager
from AccessControl.SecurityManager import setSecurityPolicy from AccessControl.SecurityManager import setSecurityPolicy
from Acquisition import Implicit from Acquisition import Implicit
MS_DAV_AGENT = "Microsoft Data Access Internet Publishing Provider DAV" MS_DAV_AGENT = "Microsoft Data Access Internet Publishing Provider DAV"
def make_request_response(environ=None): def make_request_response(environ=None):
from StringIO import StringIO from StringIO import StringIO
from ZPublisher.HTTPRequest import HTTPRequest from ZPublisher.HTTPRequest import HTTPRequest
...@@ -106,16 +106,16 @@ class TestResource(unittest.TestCase): ...@@ -106,16 +106,16 @@ class TestResource(unittest.TestCase):
verifyClass(IWriteLock, self._getTargetClass()) verifyClass(IWriteLock, self._getTargetClass())
def test_ms_public_header(self): def test_ms_public_header(self):
import webdav from Zope2.Startup import config
default_settings = webdav.enable_ms_public_header default_settings = config.ZSERVER_ENABLE_MS_PUBLIC_HEADER
try: try:
req, resp = make_request_response() req, resp = make_request_response()
resource = self._makeOne() resource = self._makeOne()
resource.OPTIONS(req, resp) resource.OPTIONS(req, resp)
self.assert_(not resp.headers.has_key('public')) self.assert_(not resp.headers.has_key('public'))
webdav.enable_ms_public_header = True config.ZSERVER_ENABLE_MS_PUBLIC_HEADER = True
req, resp = make_request_response() req, resp = make_request_response()
resource = self._makeOne() resource = self._makeOne()
resource.OPTIONS(req, resp) resource.OPTIONS(req, resp)
...@@ -131,7 +131,7 @@ class TestResource(unittest.TestCase): ...@@ -131,7 +131,7 @@ class TestResource(unittest.TestCase):
self.assert_(resp.headers['public'] == resp.headers['allow']) self.assert_(resp.headers['public'] == resp.headers['allow'])
finally: finally:
webdav.enable_ms_public_header = default_settings config.ZSERVER_ENABLE_MS_PUBLIC_HEADER = default_settings
def test_MOVE_self_locked(self): def test_MOVE_self_locked(self):
""" """
......
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