【山大智云开发日志】seafdav分析(7)

本文介绍了WsgiDAV项目中的核心文件_version.py,展示了如何通过预发布和最终版本号标识,并重点讲解了compat.py中的Python 2/3兼容工具函数。此外,还涵盖了WSGI环境变量转换和错误处理机制。
摘要由CSDN通过智能技术生成

2021SC@SDUSC

经过几周的代码学习,已经完成了大部分代码的分析,还剩下一些零散的文件。

_version.py主要是描述了当前的WsgiDAV版本号。

例子

预发布版(alpha, beta,候选版本):

“3.0.0a1”、“3.0.0b1”、“3.0.0rc1”

最终版本:

“3.0.0”

发展版(将3.0.0标记为“使用”)。不发布):

“3.0.0.dev1”

注意:

安装pywin32时,MSI版本的编号必须为a.b.c ?

“3.0.0a4”似乎在这种情况下不工作。

compat.py:支持Python 2和Python 3的工具函数。

对于python2:

if PY2:

    from base64 import decodestring as base64_decodebytes
    from base64 import encodestring as base64_encodebytes
    from cgi import escape as html_escape

    def is_basestring(s):
        """Return True for any string type (for str/unicode on Py2 and bytes/str on Py3)."""
        return isinstance(s, basestring)

    def is_bytes(s):
        """Return True for bytestrings (for str on Py2 and bytes on Py3)."""
        return isinstance(s, str)

    def is_native(s):
        """Return True for native strings (for str on Py2 and Py3)."""
        return isinstance(s, str)

    def is_unicode(s):
        """Return True for unicode strings (for unicode on Py2 and str on Py3)."""
        return isinstance(s, unicode)

    def to_bytes(s, encoding="utf8"):
        """Convert unicode (text strings) to binary data (str on Py2 and bytes on Py3)."""
        if type(s) is unicode:
            s = s.encode(encoding)
        elif type(s) is not str:
            s = str(s)
        return s

    to_native = to_bytes
    """Convert data to native str type (bytestring on Py2 and unicode on Py3)."""

    def to_unicode(s, encoding="utf8"):
        """Convert data to unicode text (unicode on Py2 and str on Py3)."""
        if type(s) is not unicode:
            s = unicode(s, encoding)
        return s

处理python3的情况

 # Python 3

    from base64 import decodebytes as base64_decodebytes
    from base64 import encodebytes as base64_encodebytes
    from html import escape as html_escape

    def is_basestring(s):
        """Return True for any string type (for str/unicode on Py2 and bytes/str on Py3)."""
        return isinstance(s, (str, bytes))

    def is_bytes(s):
        """Return True for bytestrings (for str on Py2 and bytes on Py3)."""
        return isinstance(s, bytes)

    def is_native(s):
        """Return True for native strings (for str on Py2 and Py3)."""
        return isinstance(s, str)

    def is_unicode(s):
        """Return True for unicode strings (for unicode on Py2 and str on Py3)."""
        return isinstance(s, str)

    def to_bytes(s, encoding="utf8"):
        """Convert a text string (unicode) to bytestring (str on Py2 and bytes on Py3)."""
        if type(s) is not bytes:
            s = bytes(s, encoding)
        return s

    def to_native(s, encoding="utf8"):
        """Convert data to native str type (bytestring on Py2 and unicode on Py3)."""
        if type(s) is bytes:
            s = str(s, encoding)
        elif type(s) is not str:
            s = str(s)
        return s

    to_unicode = to_native
    """Convert binary data to unicode (text strings) on Python 2 and 3."""

对WSGI进行支持。

将环境变量转换为WSGI 'bytes-as-unicode'字符串

def unicode_to_wsgi(u):
    # Taken from PEP3333; the server should already have performed this, when
    # passing environ to the WSGI application
    return u.encode(_filesystemencoding, "surrogateescape").decode("iso-8859-1")

将本机字符串转换为WSGI / HTTP兼容的字节串

def wsgi_to_bytes(s):
    """Convert a native string to a WSGI / HTTP compatible byte string."""
    # Taken from PEP3333
    return s.encode("iso-8859-1")

dav_error.py:实现用于通知WebDAV和HTTP错误的DAVError类。分为DAVErrorCondition、DAVError两个类。

DAVError:通用错误类,用于标记HTTP和WEBDAV错误.

关键代码

返回可读的字符串。

    def get_user_info(self):
        """Return readable string."""
        if self.value in ERROR_DESCRIPTIONS:
            s = "{}".format(ERROR_DESCRIPTIONS[self.value])
        else:
            s = "{}".format(self.value)

        if self.context_info:
            s += ": {}".format(self.context_info)
        elif self.value in ERROR_RESPONSES:
            s += ": {}".format(ERROR_RESPONSES[self.value])

        if self.src_exception:
            s += "\n    Source exception: '{}'".format(self.src_exception)

        if self.err_condition:
            s += "\n    Error condition: '{}'".format(self.err_condition)
        return s

返回一个元组(内容类型,响应页面)。

    def get_response_page(self):
        """Return a tuple (content-type, response page)."""
        # If it has pre- or post-condition: return as XML response
        if self.err_condition:
            return ("application/xml", compat.to_bytes(self.err_condition.as_string()))

        # Else return as HTML
        status = get_http_status_string(self)
        html = []
        html.append(
            "<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN' "
            "'http://www.w3.org/TR/html4/strict.dtd'>"
        )
        html.append("<html><head>")
        html.append(
            "  <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>"
        )
        html.append("  <title>{}</title>".format(status))
        html.append("</head><body>")
        html.append("  <h1>{}</h1>".format(status))
        html.append("  <p>{}</p>".format(compat.html_escape(self.get_user_info())))
        html.append("<hr/>")
        html.append(
            "<a href='https://github.com/mar10/wsgidav/'>WsgiDAV/{}</a> - {}".format(
                __version__, compat.html_escape(str(datetime.datetime.now()), "utf-8")
            )
        )
        html.append("</body></html>")
        html = "\n".join(html)
        return ("text/html", compat.to_bytes(html))

除去这两个类,还有一些函数也十分重要。

返回HTTP响应代码为整数,例如204

def get_http_status_code(v):
    """Return HTTP response code as integer, e.g. 204."""
    if hasattr(v, "value"):
        return int(v.value)  # v is a DAVError
    else:
        return int(v)

返回HTTP响应字符串,例如204 ->('204无内容')。返回字符串总是包含描述性文本,以满足Apache mod_dav。' v ':状态码或DAVError

def get_http_status_string(v):
    code = get_http_status_code(v)
    try:
        return ERROR_DESCRIPTIONS[code]
    except KeyError:
        return "{} Status".format(code)

将任何非daverror异常转换为HTTP_INTERNAL_ERROR


def as_DAVError(e):
    if isinstance(e, DAVError):
        return e
    elif isinstance(e, Exception):
        # traceback.print_exc()
        return DAVError(HTTP_INTERNAL_ERROR, src_exception=e)
    else:
        return DAVError(HTTP_INTERNAL_ERROR, "{}".format(e))

debug_filter.py:

用于调试的WSGI中间件(可选)。此模块将请求和响应信息转储到控制台(具体取决于此)在当前的调试配置。

初始化:

定义HTTP方法和石蕊测试,这应该打开详细模式

(目前硬编码)。

为每个请求:

增加' ' environ['verbose'] ' '的值,如果请求应该被调试。同时转储请求和响应的头部和主体。然后将请求传递给下一个中间件。

这些配置设置被评估:

*详细*

这也被其他模块使用。这个过滤器添加了额外的信息。取决于值。

* debug_methods *

在处理某些请求方法时,将详细度提高到3。这个选项

当``verbose < 2``时被忽略。

配置::

debug_methods = ["PROPPATCH", "PROPFIND", "GET", "HEAD", "DELET E",

" put ", " copy ", " move ", " lock ", " unlock ",

* debug_litmus *

提高冗长到3,而处理石蕊测试,包含某些

子字符串。当``verbose < 2``时,此选项将被忽略。

配置::

Debug_litmus = ["notowner_modify", "props: 16",]

文件中只包含WsgiDavDebugFilter一个类。

主要代码:

    def __init__(self, wsgidav_app, next_app, config):
        super(WsgiDavDebugFilter, self).__init__(wsgidav_app, next_app, config)
        self._config = config
        # self.out = sys.stdout
        self.passedLitmus = {}
        # These methods boost verbose=2 to verbose=3
        self.debug_methods = config.get("debug_methods", [])
        # Litmus tests containing these string boost verbose=2 to verbose=3
        self.debug_litmus = config.get("debug_litmus", [])
        # Exit server, as soon as this litmus test has finished
        self.break_after_litmus = [
            # "locks: 15",
        ]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值