⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 publisher.py

📁 Mod_python is an Apache module that embeds the Python interpreter within the server. With mod_python
💻 PY
📖 第 1 页 / 共 2 页
字号:
            elif func_code.co_argcount < len(func_code.co_varnames):                names = func_code.co_varnames[func_code.co_argcount:]                if name in names:                    i = list(names).index(name)            if i is not None:                return (1, func_code.co_consts[i+1])            return (0, None)        (found_auth, __auth__) = lookup('__auth__')        if found_auth and type(__auth__) == types.CodeType:            __auth__ = new.function(__auth__, func_globals)        (found_access, __access__) = lookup('__access__')        if found_access and type(__access__) == types.CodeType:            __access__ = new.function(__access__, func_globals)        (found_realm, __auth_realm__) = lookup('__auth_realm__')        if found_realm:            realm = __auth_realm__    else:        if hasattr(object, "__auth__"):            __auth__ = object.__auth__            found_auth = 1        if hasattr(object, "__access__"):            __access__ = object.__access__            found_access = 1    if found_auth or found_access:        # because ap_get_basic insists on making sure that AuthName and        # AuthType directives are specified and refuses to do anything        # otherwise (which is technically speaking a good thing), we        # have to do base64 decoding ourselves.        #        # to avoid needless header parsing, user and password are parsed        # once and the are received as arguments        if not user and req.headers_in.has_key("Authorization"):            try:                s = req.headers_in["Authorization"][6:]                s = base64.decodestring(s)                user, passwd = s.split(":", 1)            except:                raise apache.SERVER_RETURN, apache.HTTP_BAD_REQUEST    if found_auth:        if not user:            # note that Opera supposedly doesn't like spaces around "=" below            s = 'Basic realm="%s"' % realm            req.err_headers_out["WWW-Authenticate"] = s            raise apache.SERVER_RETURN, apache.HTTP_UNAUTHORIZED        if callable(__auth__):            rc = __auth__(req, user, passwd)        else:            if type(__auth__) is DictionaryType:                rc = __auth__.has_key(user) and __auth__[user] == passwd            else:                rc = __auth__                    if not rc:            s = 'Basic realm = "%s"' % realm            req.err_headers_out["WWW-Authenticate"] = s            raise apache.SERVER_RETURN, apache.HTTP_UNAUTHORIZED    if found_access:        if callable(__access__):            rc = __access__(req, user)        else:            if type(__access__) in (ListType, TupleType):                rc = user in __access__            else:                rc = __access__        if not rc:            raise apache.SERVER_RETURN, apache.HTTP_FORBIDDEN    return realm, user, passwd### Those are the traversal and publishing rules #### tp_rules is a dictionary, indexed by type, with tuple values.# The first item in the tuple is a boolean telling if the object can be traversed (default is True)# The second item in the tuple is a boolen telling if the object can be published (default is True)tp_rules = {}# by default, built-in types cannot be traversed, but can be publisheddefault_builtins_tp_rule = (False, True)for t in types.__dict__.values():    if isinstance(t, type):        tp_rules[t]=default_builtins_tp_rule# those are the exceptions to the previous rulestp_rules.update({    # Those are not traversable nor publishable    ModuleType          : (False, False),    BuiltinFunctionType : (False, False),        # This may change in the near future to (False, True)    ClassType           : (False, False),    TypeType            : (False, False),        # Publishing a generator may not seem to makes sense, because    # it can only be done once. However, we could get a brand new generator    # each time a new-style class property is accessed.    GeneratorType       : (False, True),        # Old-style instances are traversable    InstanceType        : (True, True),})# types which are not referenced in the tp_rules dictionary will be traversable# AND publishable default_tp_rule = (True, True)def resolve_object(req, obj, object_str, realm=None, user=None, passwd=None):    """    This function traverses the objects separated by .    (period) to find the last one we're looking for.    """    parts = object_str.split('.')    first_object = True            for obj_str in parts:        # path components starting with an underscore are forbidden        if obj_str[0]=='_':            req.log_error('Cannot traverse %s in %s because '                          'it starts with an underscore'                          % (obj_str, req.unparsed_uri), apache.APLOG_WARNING)            raise apache.SERVER_RETURN, apache.HTTP_FORBIDDEN        if first_object:            first_object = False        else:            # if we're not in the first object (which is the module)            # we're going to check whether be can traverse this type or not            rule = tp_rules.get(type(obj), default_tp_rule)            if not rule[0]:                req.log_error('Cannot traverse %s in %s because '                              '%s is not a traversable object'                              % (obj_str, req.unparsed_uri, obj), apache.APLOG_WARNING)                raise apache.SERVER_RETURN, apache.HTTP_FORBIDDEN                # we know it's OK to call getattr        # note that getattr can really call some code because        # of property objects (or attribute with __get__ special methods)...        try:            obj = getattr(obj, obj_str)        except AttributeError:            raise apache.SERVER_RETURN, apache.HTTP_NOT_FOUND        # we process the authentication for the object        realm, user, passwd = process_auth(req, obj, realm, user, passwd)        # we're going to check if the final object is publishable    rule = tp_rules.get(type(obj), default_tp_rule)    if not rule[1]:         req.log_error('Cannot publish %s in %s because '                       '%s is not publishable'                       % (obj_str, req.unparsed_uri, obj), apache.APLOG_WARNING)         raise apache.SERVER_RETURN, apache.HTTP_FORBIDDEN    return obj# This regular expression is used to test for the presence of an HTML header# tag, written in upper or lower case.re_html = re.compile(r"</HTML\s*>\s*$",re.I)re_charset = re.compile(r"charset\s*=\s*([^\s;]+)",re.I);def publish_object(req, object):    if callable(object):                # To publish callables, we call them an recursively publish the result        # of the call (as done by util.apply_fs_data)                req.form = util.FieldStorage(req, keep_blank_values=1)        return publish_object(req,util.apply_fs_data(object, req.form, req=req))# TODO : we removed this as of mod_python 3.2, let's see if we can put it back# in mod_python 3.3    #     elif hasattr(object,'__iter__'):#     #         # To publish iterables, we recursively publish each item#         # This way, generators can be published#         result = False#         for item in object:#             result |= publish_object(req,item)#         return result#             else:        if object is None:                        # Nothing to publish            return False                    elif isinstance(object,UnicodeType):                        # We've got an Unicode string to publish, so we have to encode            # it to bytes. We try to detect the character encoding            # from the Content-Type header            if req._content_type_set:                charset = re_charset.search(req.content_type)                if charset:                    charset = charset.group(1)                else:                    # If no character encoding was set, we use UTF8                    charset = 'UTF8'                    req.content_type += '; charset=UTF8'            else:                # If no character encoding was set, we use UTF8                charset = 'UTF8'                            result = object.encode(charset)        else:            charset = None            result = str(object)                    if not req._content_type_set:            # make an attempt to guess content-type            # we look for a </HTML in the last 100 characters.            # re.search works OK with a negative start index (it starts from 0            # in that case)            if re_html.search(result,len(result)-100):                req.content_type = 'text/html'            else:                req.content_type = 'text/plain'            if charset is not None:                req.content_type += '; charset=%s'%charset                # Write result even if req.method is 'HEAD' as Apache        # will discard the final output anyway. Truncating        # output here if req.method is 'HEAD' is likely the        # wrong thing to do as it may cause problems for any        # output filters. See MODPYTHON-105 for details. We        # also do not flush output as that will prohibit use        # of 'CONTENT_LENGTH' filter to add 'Content-Length'        # header automatically. See MODPYTHON-107 for details.        req.write(result, 0)        return True

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -