def lock_string(lockDict): """Return readable rep.""" if not lockDict: return "Lock: None" if lockDict["expire"] < 0: expire = "Infinite ({})".format(lockDict["expire"]) else: expire = "{} (in {} seconds)".format( util.get_log_time(lockDict["expire"]), lockDict["expire"] - time.time()) return "Lock(<{}..>, '{}', {}, {}, depth-{}, until {}".format( # first 4 significant token characters lockDict.get("token", "?" * 30)[18:22], lockDict.get("root"), lockDict.get("principal"), lockDict.get("scope"), lockDict.get("depth"), expire, )
def lock_string(lock_dict): """Return readable rep.""" if not lock_dict: return "Lock: None" if lock_dict["expire"] < 0: expire = "Infinite ({})".format(lock_dict["expire"]) else: expire = "{} (in {} seconds)".format( util.get_log_time(lock_dict["expire"]), lock_dict["expire"] - time.time() ) return "Lock(<{}..>, '{}', {}, {}, depth-{}, until {}".format( # first 4 significant token characters lock_dict.get("token", "?" * 30)[18:22], lock_dict.get("root"), lock_dict.get("principal"), lock_dict.get("scope"), lock_dict.get("depth"), expire, )
def _start_response_wrapper(status, response_headers, exc_info=None): # Postprocess response headers headerDict = {} for header, value in response_headers: if header.lower() in headerDict: _logger.error("Duplicate header in response: {}".format(header)) headerDict[header.lower()] = value # Check if we should close the connection after this request. # http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 forceCloseConnection = False currentContentLength = headerDict.get("content-length") statusCode = int(status.split(" ", 1)[0]) contentLengthRequired = ( environ["REQUEST_METHOD"] != "HEAD" and statusCode >= 200 and statusCode not in (204, 304) ) # _logger.info(environ["REQUEST_METHOD"], statusCode, contentLengthRequired) if contentLengthRequired and currentContentLength in (None, ""): # A typical case: a GET request on a virtual resource, for which # the provider doesn't know the length _logger.error( "Missing required Content-Length header in {}-response: closing connection".format( statusCode ) ) forceCloseConnection = True elif not type(currentContentLength) is str: _logger.error( "Invalid Content-Length header in response ({!r}): closing connection".format( headerDict.get("content-length") ) ) forceCloseConnection = True # HOTFIX for Vista and Windows 7 (GC issue 13, issue 23) # It seems that we must read *all* of the request body, otherwise # clients may miss the response. # For example Vista MiniRedir didn't understand a 401 response, # when trying an anonymous PUT of big files. As a consequence, it # doesn't retry with credentials and the file copy fails. # (XP is fine however). util.read_and_discard_input(environ) # Make sure the socket is not reused, unless we are 100% sure all # current input was consumed if util.get_content_length(environ) != 0 and not environ.get( "wsgidav.all_input_read" ): _logger.warn("Input stream not completely consumed: closing connection") forceCloseConnection = True if forceCloseConnection and headerDict.get("connection") != "close": _logger.warn("Adding 'Connection: close' header") response_headers.append(("Connection", "close")) # Log request if self.verbose >= 3: userInfo = environ.get("http_authenticator.username") if not userInfo: userInfo = "(anonymous)" extra = [] if "HTTP_DESTINATION" in environ: extra.append('dest="{}"'.format(environ.get("HTTP_DESTINATION"))) if environ.get("CONTENT_LENGTH", "") != "": extra.append("length={}".format(environ.get("CONTENT_LENGTH"))) if "HTTP_DEPTH" in environ: extra.append("depth={}".format(environ.get("HTTP_DEPTH"))) if "HTTP_RANGE" in environ: extra.append("range={}".format(environ.get("HTTP_RANGE"))) if "HTTP_OVERWRITE" in environ: extra.append("overwrite={}".format(environ.get("HTTP_OVERWRITE"))) if self.verbose >= 3 and "HTTP_EXPECT" in environ: extra.append('expect="{}"'.format(environ.get("HTTP_EXPECT"))) if self.verbose >= 4 and "HTTP_CONNECTION" in environ: extra.append( 'connection="{}"'.format(environ.get("HTTP_CONNECTION")) ) if self.verbose >= 4 and "HTTP_USER_AGENT" in environ: extra.append('agent="{}"'.format(environ.get("HTTP_USER_AGENT"))) if self.verbose >= 4 and "HTTP_TRANSFER_ENCODING" in environ: extra.append( "transfer-enc={}".format(environ.get("HTTP_TRANSFER_ENCODING")) ) if self.verbose >= 3: extra.append("elap={:.3f}sec".format(time.time() - start_time)) extra = ", ".join(extra) # This is the CherryPy format: # 127.0.0.1 - - [08/Jul/2009:17:25:23] "GET /loginPrompt?redirect=/renderActionList%3Frelation%3Dpersonal%26key%3D%26filter%3DprivateSchedule&reason=0 HTTP/1.1" 200 1944 "http://127.0.0.1:8002/command?id=CMD_Schedule" "Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1) Gecko/20090624 Firefox/3.5" # noqa _logger.info( '{addr} - {user} - [{time}] "{method} {path}" {extra} -> {status}'.format( addr=environ.get("REMOTE_ADDR", ""), user=userInfo, time=util.get_log_time(), method=environ.get("REQUEST_METHOD"), path=safe_re_encode( environ.get("PATH_INFO", ""), sys.stdout.encoding ), extra=extra, status=status, # response_headers.get(""), # response Content-Length # referer ) ) return start_response(status, response_headers, exc_info)
def _start_response_wrapper(status, response_headers, exc_info=None): # Postprocess response headers headerDict = {} for header, value in response_headers: if header.lower() in headerDict: _logger.error("Duplicate header in response: {}".format(header)) headerDict[header.lower()] = value # Check if we should close the connection after this request. # http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4 forceCloseConnection = False currentContentLength = headerDict.get("content-length") statusCode = int(status.split(" ", 1)[0]) contentLengthRequired = ( environ["REQUEST_METHOD"] != "HEAD" and statusCode >= 200 and statusCode not in (204, 304) ) # _logger.info(environ["REQUEST_METHOD"], statusCode, contentLengthRequired) if contentLengthRequired and currentContentLength in (None, ""): # A typical case: a GET request on a virtual resource, for which # the provider doesn't know the length _logger.error( "Missing required Content-Length header in {}-response: closing connection".format( statusCode ) ) forceCloseConnection = True elif not type(currentContentLength) is str: _logger.error( "Invalid Content-Length header in response ({!r}): closing connection".format( headerDict.get("content-length") ) ) forceCloseConnection = True # HOTFIX for Vista and Windows 7 (GC issue 13, issue 23) # It seems that we must read *all* of the request body, otherwise # clients may miss the response. # For example Vista MiniRedir didn't understand a 401 response, # when trying an anonymous PUT of big files. As a consequence, it # doesn't retry with credentials and the file copy fails. # (XP is fine however). util.read_and_discard_input(environ) # Make sure the socket is not reused, unless we are 100% sure all # current input was consumed if util.get_content_length(environ) != 0 and not environ.get( "wsgidav.all_input_read" ): _logger.warning( "Input stream not completely consumed: closing connection." ) forceCloseConnection = True if forceCloseConnection and headerDict.get("connection") != "close": _logger.warning("Adding 'Connection: close' header.") response_headers.append(("Connection", "close")) # Log request if self.verbose >= 3: userInfo = environ.get("wsgidav.auth.user_name") if not userInfo: userInfo = "(anonymous)" extra = [] if "HTTP_DESTINATION" in environ: extra.append('dest="{}"'.format(environ.get("HTTP_DESTINATION"))) if environ.get("CONTENT_LENGTH", "") != "": extra.append("length={}".format(environ.get("CONTENT_LENGTH"))) if "HTTP_DEPTH" in environ: extra.append("depth={}".format(environ.get("HTTP_DEPTH"))) if "HTTP_RANGE" in environ: extra.append("range={}".format(environ.get("HTTP_RANGE"))) if "HTTP_OVERWRITE" in environ: extra.append("overwrite={}".format(environ.get("HTTP_OVERWRITE"))) if self.verbose >= 3 and "HTTP_EXPECT" in environ: extra.append('expect="{}"'.format(environ.get("HTTP_EXPECT"))) if self.verbose >= 4 and "HTTP_CONNECTION" in environ: extra.append( 'connection="{}"'.format(environ.get("HTTP_CONNECTION")) ) if self.verbose >= 4 and "HTTP_USER_AGENT" in environ: extra.append('agent="{}"'.format(environ.get("HTTP_USER_AGENT"))) if self.verbose >= 4 and "HTTP_TRANSFER_ENCODING" in environ: extra.append( "transfer-enc={}".format(environ.get("HTTP_TRANSFER_ENCODING")) ) if self.verbose >= 3: extra.append("elap={:.3f}sec".format(time.time() - start_time)) extra = ", ".join(extra) # This is the CherryPy format: # 127.0.0.1 - - [08/Jul/2009:17:25:23] "GET /loginPrompt?redirect=/renderActionList%3Frelation%3Dpersonal%26key%3D%26filter%3DprivateSchedule&reason=0 HTTP/1.1" 200 1944 "http://127.0.0.1:8002/command?id=CMD_Schedule" "Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1) Gecko/20090624 Firefox/3.5" # noqa _logger.info( '{addr} - {user} - [{time}] "{method} {path}" {extra} -> {status}'.format( addr=environ.get("REMOTE_ADDR", ""), user=userInfo, time=util.get_log_time(), method=environ.get("REQUEST_METHOD"), path=safe_re_encode( environ.get("PATH_INFO", ""), sys.stdout.encoding if sys.stdout.encoding else "utf-8", ), extra=extra, status=status, # response_headers.get(""), # response Content-Length # referer ) ) return start_response(status, response_headers, exc_info)