+ def shutdown(self, tru):
+ pass
+
+def _quote_html(html):
+ return html.replace("&", "&").replace("<", "<").replace(">", ">")
+
+class FixSendError:
+ #error_message_format = """ """
+ def send_error(self, code, message=None):
+ #overriden from BaseHTTPRequestHandler, we also send the content-length
+ try:
+ short, long = self.responses[code]
+ except KeyError:
+ short, long = '???', '???'
+ if message is None:
+ message = short
+ explain = long
+ self.log_error("code %d, message %s", code, message)
+ # using _quote_html to prevent Cross Site Scripting attacks (see bug #1100201)
+ content = (self.error_message_format %
+ {'code': code, 'message': _quote_html(message), 'explain': explain})
+ self.send_response(code, message)
+ self.send_header("Content-Type", self.error_content_type)
+ self.send_header('Connection', 'close')
+ self.send_header('Content-Length', len(content) or 0)
+ self.end_headers()
+ if hasattr(self, '_flush'):
+ self._flush()
+
+ if self.command != 'HEAD' and code >= 200 and code not in (204, 304):
+ self.wfile.write(content)
+
+class HttpOptions:
+ _HTTP_OPTIONS = {'Allow': ['OPTIONS' ] }
+
+ def do_OPTIONS(self):
+ """return the list of capabilities """
+
+ opts = self._HTTP_OPTIONS
+ nopts = self._prep_OPTIONS(opts)
+ if nopts:
+ opts = nopts
+
+ self.send_response(200)
+ self.send_header("Content-Length", 0)
+ if 'Microsoft' in self.headers.get('User-Agent', ''):
+ self.send_header('MS-Author-Via', 'DAV')
+ # Microsoft's webdav lib ass-umes that the server would
+ # be a FrontPage(tm) one, unless we send a non-standard
+ # header that we are not an elephant.
+ # http://www.ibm.com/developerworks/rational/library/2089.html
+
+ for key, value in opts.items():
+ if isinstance(value, basestring):
+ self.send_header(key, value)
+ elif isinstance(value, (tuple, list)):
+ self.send_header(key, ', '.join(value))
+ self.end_headers()
+
+ def _prep_OPTIONS(self, opts):
+ """Prepare the OPTIONS response, if needed
+
+ Sometimes, like in special DAV folders, the OPTIONS may contain
+ extra keywords, perhaps also dependant on the request url.
+ @param the options already. MUST be copied before being altered
+ @return the updated options.
+
+ """
+ return opts