diff options
Diffstat (limited to 'addons/document_webdav/redirect.py')
| -rw-r--r-- | addons/document_webdav/redirect.py | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/addons/document_webdav/redirect.py b/addons/document_webdav/redirect.py new file mode 100644 index 00000000000..71af3271ab7 --- /dev/null +++ b/addons/document_webdav/redirect.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2010 OpenERP s.a. (<http://openerp.com>). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + + +import logging +import urlparse +from service.websrv_lib import FixSendError, HTTPHandler, HttpOptions +from service.http_server import HttpLogHandler + +class RedirectHTTPHandler(HttpLogHandler, FixSendError, HttpOptions, HTTPHandler): + _logger = logging.getLogger('httpd.well-known') + _HTTP_OPTIONS = { 'Allow': ['OPTIONS', 'GET', 'HEAD', 'PROPFIND'] } + redirect_paths = {} + + def __init__(self,request, client_address, server): + HTTPHandler.__init__(self,request,client_address,server) + + def send_head(self): + """Common code for GET and HEAD commands. + + It will either send the correct redirect (Location) response + or a 404. + """ + + if self.path.endswith('/'): + self.path = self.path[:-1] + + if not self.path: + # Return an empty page + self.send_response(200) + self.send_header("Content-Length", 0) + self.end_headers() + return None + + redir_path = self._find_redirect() + if redir_path is False: + self.send_error(404, "File not found") + return None + elif redir_path is None: + return None + + server_proto = getattr(self.server, 'proto', 'http').lower() + addr, port = self.server.server_name, self.server.server_port + try: + addr, port = self.request.getsockname() + except Exception, e: + self.log_error("Cannot calculate own address:" , e) + + if self.headers.has_key('Host'): + uparts = list(urlparse.urlparse("%s://%s:%d"% (server_proto, addr,port))) + uparts[1] = self.headers['Host'] + baseuri = urlparse.urlunparse(uparts) + else: + baseuri = "%s://%s:%d"% (server_proto, addr, port ) + + + location = baseuri + redir_path + # relative uri: location = self.redirect_paths[self.path] + + self.send_response(301) + self.send_header("Location", location) + self.send_header("Content-Length", 0) + self.end_headers() + # Do we need a Cache-content: header here? + self._logger.debug("redirecting %s to %s", self.path, redir_path) + return None + + def do_PROPFIND(self): + self._get_ignore_body() + return self.do_HEAD() + + def _find_redirect(self): + """ Locate self.path among the redirects we can handle + @return The new path, False for 404 or None for already sent error + """ + return self.redirect_paths.get(self.path, False) + + def _get_ignore_body(self): + if not self.headers.has_key("content-length"): + return + max_chunk_size = 10*1024*1024 + size_remaining = int(self.headers["content-length"]) + got = '' + while size_remaining: + chunk_size = min(size_remaining, max_chunk_size) + got = self.rfile.read(chunk_size) + size_remaining -= len(got) + +#eof + |
