summaryrefslogtreecommitdiff
path: root/addons/document_webdav
diff options
context:
space:
mode:
Diffstat (limited to 'addons/document_webdav')
-rw-r--r--addons/document_webdav/__openerp__.py5
-rw-r--r--addons/document_webdav/doc/well-known.rst29
-rw-r--r--addons/document_webdav/redirect.py108
-rw-r--r--addons/document_webdav/webdav_server.py25
4 files changed, 164 insertions, 3 deletions
diff --git a/addons/document_webdav/__openerp__.py b/addons/document_webdav/__openerp__.py
index 6c1e24d1e96..0fd21a41a17 100644
--- a/addons/document_webdav/__openerp__.py
+++ b/addons/document_webdav/__openerp__.py
@@ -30,7 +30,7 @@
{
"name" : "WebDAV server for Document Management",
- "version" : "2.2",
+ "version" : "2.3",
"author" : "OpenERP SA",
"category" : "Generic Modules/Others",
"website": "http://www.openerp.com",
@@ -49,6 +49,9 @@
; since the messages are routed to the python logging, with
; levels "debug" and "debug_rpc" respectively, you can leave
; these options on
+
+ Also implements IETF RFC 5785 for services discovery on a http server,
+ which needs explicit configuration in openerp-server.conf, too.
""",
"depends" : ["base", "document"],
"init_xml" : [],
diff --git a/addons/document_webdav/doc/well-known.rst b/addons/document_webdav/doc/well-known.rst
new file mode 100644
index 00000000000..ce7dbd7c9cf
--- /dev/null
+++ b/addons/document_webdav/doc/well-known.rst
@@ -0,0 +1,29 @@
+=================
+Well-known URIs
+=================
+
+In accordance to IETF RFC 5785 [1], we shall publish a few locations
+on the root of our http server, so that clients can discover our
+services (CalDAV, eg.).
+
+This module merely installs a special http request handler, that will
+redirect the URIs from "http://our-server:port/.well-known/xxx' to
+the correct path for each xxx service.
+
+Note that well-known URIs cannot have a database-specific behaviour,
+they are server-wide. So, we have to explicitly chose one of our databases
+to serve at them. By default, the database of the configuration file
+is chosen
+
+Example config:
+
+[http-well-known]
+num_services = 2
+db_name = openerp-main ; must define that for path_1 below
+service_1 = caldav
+path_1 = /webdav/%(db_name)s/Calendars/
+service_2 = foo
+path_2 = /other_db/static/Foo.html
+
+
+[1] http://www.rfc-editor.org/rfc/rfc5785.txt \ No newline at end of file
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
+
diff --git a/addons/document_webdav/webdav_server.py b/addons/document_webdav/webdav_server.py
index 5810978a6d5..f2a230858bf 100644
--- a/addons/document_webdav/webdav_server.py
+++ b/addons/document_webdav/webdav_server.py
@@ -1,5 +1,5 @@
# -*- encoding: utf-8 -*-
-
+############################################################################9
#
# Copyright P. Christeas <p_christ@hol.gr> 2008,2009
# Copyright OpenERP SA, 2010 (http://www.openerp.com )
@@ -14,7 +14,7 @@
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
+# 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,
@@ -43,6 +43,7 @@ import addons
from DAV.errors import DAV_Error, DAV_Forbidden, DAV_NotFound
from DAV.propfind import PROPFIND
# from DAV.constants import DAV_VERSION_1, DAV_VERSION_2
+from redirect import RedirectHTTPHandler
khtml_re = re.compile(r' KHTML/([0-9\.]+) ')
@@ -453,6 +454,26 @@ except Exception, e:
logger = netsvc.Logger()
logger.notifyChannel('webdav', netsvc.LOG_ERROR, 'Cannot launch webdav: %s' % e)
+
+def init_well_known():
+ reps = RedirectHTTPHandler.redirect_paths
+
+ num_svcs = config.get_misc('http-well-known', 'num_services', '0')
+
+ for nsv in range(1, int(num_svcs)+1):
+ uri = config.get_misc('http-well-known', 'service_%d' % nsv, False)
+ path = config.get_misc('http-well-known', 'path_%d' % nsv, False)
+ if not (uri and path):
+ continue
+ reps['/'+uri] = path
+
+ if int(num_svcs):
+ if http_server.reg_http_service(HTTPDir('/.well-known', RedirectHTTPHandler)):
+ logging.getLogger("web-services").info("Registered HTTP redirect handler at /.well-known" )
+
+
+init_well_known()
+
#eof