handlers.py 5.85 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
import os
import sys
from re import compile
from socket import gethostbyaddr

# top-level key handlers


# 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):
    if isinstance(value, str):
        os.environ[name] = value
    else:
        os.environ[name] = `value`

def debug_mode(value):
    value and _setenv('Z_DEBUG_MODE', '1')
    import Globals # to set value
24
    Globals.DevelopmentMode = bool(value)
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
    return value

def locale(value):
    import locale
    locale.setlocale(locale.LC_ALL, value)
    return value

def datetime_format(value):
    value and _setenv('DATETIME_FORMAT', value)
    return value

def automatically_quote_dtml_request_data(value):
    not value and _setenv('ZOPE_DTML_REQUEST_AUTOQUOTE', '0')
    return value

def maximum_number_of_session_objects(value):
    default = 1000
    value not in (None, default) and _setenv('ZSESSION_OBJECT_LIMIT', value)
    return value

def session_add_notify_script_path(value):
    value is not None and _setenv('ZSESSION_ADD_NOTIFY', value)
    return value

def session_delete_notify_script_path(value):
    value is not None and _setenv('ZSESSION_DEL_NOTIFY', value)
    return value

def session_timeout_minutes(value):
    default = 20
    value not in (None, default) and _setenv('ZSESSION_TIMEOUT_MINS', value)
    return value

def suppress_all_access_rules(value):
    value and _setenv('SUPPRESS_ACCESSRULE', value)
    return value

def suppress_all_site_roots(value):
    value and _setenv('SUPPRESS_SITEROOT', value)
    return value

def structured_text_header_level(value):
    value is not None and _setenv('STX_DEFAULT_LEVEL', value)
    return value

def rest_input_encoding(value):
    value and _setenv('REST_INPUT_ENCODING' , value)
    return value

def rest_output_encoding(value):
    value and _setenv('REST_OUTPUT_ENCODING' , value)
    return value

def rest_header_level(value):
    value and _setenv('REST_DEFAULT_LEVEL' , value)
    return value

def rest_language_code(value):
    value and _setenv('REST_LANGUAGE_CODE' , value)
    return value

def large_file_threshold(value):
    import ZServer
    ZServer.LARGE_FILE_THRESHOLD = value

def publisher_profile_file(value):
    value is not None and _setenv('PROFILE_PUBLISHER', value)
    from ZPublisher.Publish import install_profiling
    install_profiling(value)
    return value

def http_realm(value):
    value is not None and _setenv('Z_REALM', value)
    return value

def max_listen_sockets(value):
    import ZServer
    ZServer.CONNECTION_LIMIT = value

def cgi_maxlen(value):
    import cgi
    cgi.maxlen = value

def http_header_max_length(value):
    return value

def enable_ms_author_via(value):
    import webdav
    webdav.enable_ms_author_via = value

def enable_ms_public_header(value):
    import webdav
    webdav.enable_ms_public_header = value

# server handlers

def root_handler(config):
    """ Mutate the configuration with defaults and perform
    fixups of values that require knowledge about configuration
    values outside of their context.
    """

    # Set environment variables
128 129
    for k,v in config.environment.items():
        os.environ[k] = v
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174

    # Add directories to the pythonpath
    instancelib = os.path.join(config.instancehome, 'lib', 'python')
    if instancelib not in config.path:
        if os.path.isdir(instancelib):
            config.path.append(instancelib)
    path = config.path[:]
    path.reverse()
    for dir in path:
        sys.path.insert(0, dir)

    # Add any product directories not already in Products.__path__.
    # Directories are added in the order they are mentioned

    instanceprod = os.path.join(config.instancehome, 'Products')
    if instanceprod not in config.products:
        if os.path.isdir(instanceprod):
            config.products.append(instanceprod)

    import Products
    L = []
    for d in config.products + Products.__path__:
        if d not in L:
            L.append(d)
    Products.__path__[:] = L

    # Augment the set of MIME types:
    if config.mime_types:
        from zope.contenttype import add_files
        add_files(config.mime_types)

    # if no servers are defined, create default http server and ftp server
    if not config.servers:
        config.servers = []

    # prepare servers:
    for factory in config.servers:
        factory.prepare(config.ip_address or '',
                        config.dns_resolver,
                        "Zope2",
                        config.cgi_environment,
                        config.port_base)

    # set up trusted proxies
    if config.trusted_proxies:
175
        from ZPublisher import HTTPRequest
176 177 178 179
        # DM 2004-11-24: added host name mapping (such that examples in
        # conf file really have a chance to work
        mapped = []
        for name in config.trusted_proxies: mapped.extend(_name2Ips(name))
180 181 182 183 184 185
        HTTPRequest.trusted_proxies = tuple(mapped)
    
    # set the maximum number of ConflictError retries
    if config.max_conflict_retries:
        from ZPublisher import HTTPRequest
        HTTPRequest.retry_max_count = config.max_conflict_retries
186 187 188 189 190 191 192 193 194 195 196


def handleConfig(config, multihandler):
    handlers = {}
    for name, value in globals().items():
        if not name.startswith('_'):
            handlers[name] = value
    return multihandler(handlers)

# DM 2004-11-24: added
def _name2Ips(host, isIp_=compile(r'(\d+\.){3}').match):
197 198
    """Map a name *host* to the sequence of its ip addresses.

199 200 201
    use *host* itself (as sequence) if it already is an ip address.
    Thus, if only a specific interface on a host is trusted,
    identify it by its ip (and not the host name).
202 203 204
    """
    if isIp_(host):
        return [host]
205
    return gethostbyaddr(host)[2]