Beispiel #1
0
def sendStatusResponse(environ, start_response, e):
    """Start a WSGI response for a DAVError or status code.""" 
    status = getHttpStatusString(e)
    headers = [] 
#    if 'keep-alive' in environ.get('HTTP_CONNECTION', '').lower():
#        headers += [
#            ('Connection', 'keep-alive'),
#        ]

    if e in (HTTP_NOT_MODIFIED, HTTP_NO_CONTENT):
        # See paste.lint: these code don't have content
        start_response(status, [("Content-Length", "0"),
                                ("Date", getRfc1123Time()),
                                ] + headers)
        return [ "" ]
    
    if e in (HTTP_OK, HTTP_CREATED):
        e = DAVError(e)
    assert isinstance(e, DAVError)
    
    content_type, body = e.getResponsePage()            

    start_response(status, [("Content-Type", content_type), 
                            ("Date", getRfc1123Time()),
                            ("Content-Length", str(len(body))),
                            ] + headers) 
    assert type(body) is str # If not, Content-Length is wrong!
    return [ body ]
Beispiel #2
0
def sendStatusResponse(environ, start_response, e):
    """Start a WSGI response for a DAVError or status code."""
    status = getHttpStatusString(e)
    headers = []
    #    if 'keep-alive' in environ.get('HTTP_CONNECTION', '').lower():
    #        headers += [
    #            ('Connection', 'keep-alive'),
    #        ]

    if e in (HTTP_NOT_MODIFIED, HTTP_NO_CONTENT):
        # See paste.lint: these code don't have content
        start_response(status, [
            ("Content-Length", "0"),
            ("Date", getRfc1123Time()),
        ] + headers)
        return [b""]

    if e in (HTTP_OK, HTTP_CREATED):
        e = DAVError(e)
    assert isinstance(e, DAVError)

    content_type, body = e.getResponsePage()

    assert compat.is_bytes(body), body  # If not, Content-Length is wrong!
    start_response(status, [
        ("Content-Type", content_type),
        ("Date", getRfc1123Time()),
        ("Content-Length", str(len(body))),
    ] + headers)
    return [body]
Beispiel #3
0
    def __call__(self, environ, start_response):
        # Intercept start_response
        sub_app_start_response = util.SubAppStartResponse()

        try:
            try:
                # request_server app may be a generator (for example the GET handler)
                # So we must iterate - not return self._application(..)!
                # Otherwise the we could not catch exceptions here.
                response_started = False
                app_iter = self._application(environ, sub_app_start_response)
                for v in app_iter:
                    # Start response (the first time)
                    if not response_started:
                        # Success!
                        start_response(sub_app_start_response.status,
                                       sub_app_start_response.response_headers,
                                       sub_app_start_response.exc_info)
                    response_started = True

                    yield v

                # Close out iterator
                if hasattr(app_iter, "close"):
                    app_iter.close()

                # Start response (if it hasn't been done yet)
                if not response_started:
                    # Success!
                    start_response(sub_app_start_response.status,
                                   sub_app_start_response.response_headers,
                                   sub_app_start_response.exc_info)

                return
            except DAVError as e:
                _logger.debug("re-raising %s" % e)
                raise
            except Exception as e:
                # Caught a non-DAVError
                if self._catch_all_exceptions:
                    # Catch all exceptions to return as 500 Internal Error
                    traceback.print_exc(10, environ.get(
                        "wsgi.errors") or sys.stderr)
                    raise asDAVError(e)
                else:
                    util.warn("ErrorPrinter: caught Exception")
                    traceback.print_exc(10, sys.stderr)
                    raise
        except DAVError as e:
            _logger.debug("caught %s" % e)

            status = getHttpStatusString(e)
            # Dump internal errors to console
            if e.value == HTTP_INTERNAL_ERROR:
                print("ErrorPrinter: caught HTTPRequestException("
                    "HTTP_INTERNAL_ERROR)", file=sys.stdout)
                traceback.print_exc(10, environ.get(
                    "wsgi.errors") or sys.stdout)
                print("e.srcexception:\n%s" % e.srcexception, file=sys.stdout)
            elif e.value in (HTTP_NOT_MODIFIED, HTTP_NO_CONTENT):
                # util.log("ErrorPrinter: forcing empty error response for %s"
                #    % e.value)
                # See paste.lint: these code don't have content
                start_response(status, [("Content-Length", "0"),
                                        ("Date", util.getRfc1123Time()),
                                        ])
                yield b""
                return

            # If exception has pre-/post-condition: return as XML response,
            # else return as HTML
            content_type, body = e.getResponsePage()

            # TODO: provide exc_info=sys.exc_info()?
            start_response(status, [("Content-Type", content_type),
                                    ("Content-Length", str(len(body))),
                                    ("Date", util.getRfc1123Time()),
                                    ])
            yield body
            return
Beispiel #4
0
def addPropertyResponse(multistatusEL, href, propList):
    """Append <response> element to <multistatus> element.

    <prop> node depends on the value type: 
      - str or unicode: add element with this content
      - None: add an empty element
      - etree.Element: add XML element as child 
      - DAVError: add an empty element to an own <propstatus> for this status code
    
    @param multistatusEL: etree.Element
    @param href: global URL of the resource, e.g. 'http://server:port/path'.
    @param propList: list of 2-tuples (name, value) 
    """
    # Split propList by status code and build a unique list of namespaces
    nsCount = 1
    nsDict = {}
    nsMap = {}
    propDict = {}
    
    for name, value in propList:
        status = "200 OK"
        if isinstance(value, DAVError):
            status = getHttpStatusString(value)
            # Always generate *empty* elements for props with error status
            value = None

        # Collect namespaces, so we can declare them in the <response> for 
        # compacter output
        ns, _ = splitNamespace(name)
        if ns!="DAV:" and not ns in nsDict and ns != "":
            nsDict[ns] = True
            nsMap["NS%s" % nsCount] = ns
            nsCount += 1

        propDict.setdefault(status, []).append( (name, value) )

    # <response>
    responseEL = makeSubElement(multistatusEL, "{DAV:}response", nsmap=nsMap) 
    
#    log("href value:%s" % (stringRepr(href)))
#    etree.SubElement(responseEL, "{DAV:}href").text = toUnicode(href)
    etree.SubElement(responseEL, "{DAV:}href").text = href
#    etree.SubElement(responseEL, "{DAV:}href").text = urllib.quote(href, safe="/" + "!*'()," + "$-_|.")
    
    
    # One <propstat> per status code
    for status in propDict:
        propstatEL = etree.SubElement(responseEL, "{DAV:}propstat")
        # List of <prop>
        propEL = etree.SubElement(propstatEL, "{DAV:}prop")
        for name, value in propDict[status]:
            if value is None:
                etree.SubElement(propEL, name)
            elif isinstance(value, etree._Element):
                propEL.append(value)
            else:
                # value must be string or unicode
#                log("%s value:%s" % (name, stringRepr(value)))
#                etree.SubElement(propEL, name).text = value
                etree.SubElement(propEL, name).text = toUnicode(value)
        # <status>
        etree.SubElement(propstatEL, "{DAV:}status").text = "HTTP/1.1 %s" % status
Beispiel #5
0
def addPropertyResponse(multistatusEL, href, propList):
    """Append <response> element to <multistatus> element.

    <prop> node depends on the value type:
      - str or unicode: add element with this content
      - None: add an empty element
      - etree.Element: add XML element as child
      - DAVError: add an empty element to an own <propstatus> for this status code

    @param multistatusEL: etree.Element
    @param href: global URL of the resource, e.g. 'http://server:port/path'.
    @param propList: list of 2-tuples (name, value)
    """
    # Split propList by status code and build a unique list of namespaces
    nsCount = 1
    nsDict = {}
    nsMap = {}
    propDict = {}

    for name, value in propList:
        status = "200 OK"
        if isinstance(value, DAVError):
            status = getHttpStatusString(value)
            # Always generate *empty* elements for props with error status
            value = None

        # Collect namespaces, so we can declare them in the <response> for
        # compacter output
        ns, _ = splitNamespace(name)
        if ns != "DAV:" and ns not in nsDict and ns != "":
            nsDict[ns] = True
            nsMap["NS%s" % nsCount] = ns
            nsCount += 1

        propDict.setdefault(status, []).append((name, value))

    # <response>
    responseEL = makeSubElement(multistatusEL, "{DAV:}response", nsmap=nsMap)

    #    log("href value:%s" % (stringRepr(href)))
    #    etree.SubElement(responseEL, "{DAV:}href").text = toUnicode(href)
    etree.SubElement(responseEL, "{DAV:}href").text = href
    #    etree.SubElement(responseEL, "{DAV:}href").text = compat.quote(href, safe="/" + "!*'(),"
    #       + "$-_|.")

    # One <propstat> per status code
    for status in propDict:
        propstatEL = etree.SubElement(responseEL, "{DAV:}propstat")
        # List of <prop>
        propEL = etree.SubElement(propstatEL, "{DAV:}prop")
        for name, value in propDict[status]:
            if value is None:
                etree.SubElement(propEL, name)
            elif isEtreeElement(value):
                propEL.append(value)
            else:
                # value must be string or unicode
                #                log("%s value:%s" % (name, stringRepr(value)))
                #                etree.SubElement(propEL, name).text = value
                etree.SubElement(propEL, name).text = toUnicode(value)
        # <status>
        etree.SubElement(propstatEL,
                         "{DAV:}status").text = "HTTP/1.1 %s" % status