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 ]
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]
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
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
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