summaryrefslogtreecommitdiff
path: root/content/calendarAutoconfig.js
diff options
context:
space:
mode:
Diffstat (limited to 'content/calendarAutoconfig.js')
-rw-r--r--content/calendarAutoconfig.js161
1 files changed, 161 insertions, 0 deletions
diff --git a/content/calendarAutoconfig.js b/content/calendarAutoconfig.js
new file mode 100644
index 0000000..8a683c0
--- /dev/null
+++ b/content/calendarAutoconfig.js
@@ -0,0 +1,161 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * (C) 2013 Guido Günther <agx@sigxcpu.org>
+ */
+
+Components.utils.import("resource://calendar/modules/calUtils.jsm");
+
+caCalendarAutoconfig = function (aDocument, aWindow)
+{
+ this._document = aDocument;
+ this._window = aWindow;
+
+ /* The user as uri */
+ this._uri = null;
+
+ /* The calendar server */
+ this._proto = null;
+ this._host = null;
+ this._path = null;
+}
+
+caCalendarAutoconfig.prototype = {
+ parse_uri: function (aUri)
+ {
+ /* Check if it's a valid URI */
+ try {
+ var uri = cal.makeURL(aUri);
+ } catch (ex) {
+ var msg = "Invalid uri " + aUri;
+ caError(msg + " " + ex);
+ throw msg;
+ }
+
+ if (uri.scheme != 'email') {
+ throw aUri + "not a email uri";
+ }
+ this._domain = aUri.split('@')[1];
+ },
+
+ /* Query DNS SRV and TXT records */
+ query_dns: function() {
+ var proto = 'tcp';
+ var service = this.type + 's';
+ /* Currently not possible using a xulrunner interface:
+ * #14328, #545866, #735967 */
+ var resolver = new caDNSResolver();
+
+ caDebug("Checking SRV records for " + [this._domain,
+ proto,
+ service,
+ ].join(" "));
+ var records = resolver.get_srv_records(service,
+ proto,
+ this._domain);
+ caDebug("Got service records: " + records);
+ if (records[0]) {
+ this._host = records[0];
+ this._proto = 'https://';
+ }
+
+ /*
+ * FIXME: check TXT records for path
+ * this._path = ...
+ */
+ },
+
+ detect_calendar: function(aUri)
+ {
+ this.parse_uri(aUri);
+ this._uri = aUri;
+ this.query_dns();
+
+ if (this._host == null) {
+ this._host = this._domain;
+ }
+ if (this._path == null) {
+ this._path = '/.well-known/' + this.type;
+ }
+ return this.check_calendar();
+ },
+
+ _register_calendar: function(aURL, calname) {
+ caDebug("Registering " + calname + " calendar for " + aURL);
+ var uri = cal.makeURL(aURL);
+ var newCal = cal.getCalendarManager().createCalendar('ics', uri);
+ newCal.name = calname;
+ cal.getCalendarManager().registerCalendar(newCal);
+ }
+};
+
+/* CalDAV */
+function caCaldavAutoconfig(document, window) {
+ /* FIXME: handle basic auth, parse dav properties after
+ * DAV:current-user-principal
+ * request.open("GET", url, true);
+ * FIXME: use principal-URL to detect "home" collections
+ * request.send(null);
+ */
+ this.type = 'caldav';
+}
+caCaldavAutoconfig.prototype = new caCalendarAutoconfig;
+caCaldavAutoconfig.prototype.check_calendar = function() {
+ return false;
+}
+
+function makeURI(aURL, aOriginCharset, aBaseURI) {
+ var ioService = Components.classes["@mozilla.org/network/io-service;1"]
+ .getService(Components.interfaces.nsIIOService);
+ return ioService.newURI(aURL, aOriginCharset, aBaseURI);
+}
+
+/* WebCal */
+function caWebcalAutoconfig(document, window) {
+ this.type = 'webcal';
+}
+caWebcalAutoconfig.prototype = new caCalendarAutoconfig;
+caWebcalAutoconfig.prototype.check_calendar = function() {
+ this._proto = this._proto || 'https://';
+
+ var url = this._proto + this._host + this._path;
+ var calName = this._uri;
+ caDebug("Looking for calendar at " + url);
+
+ var request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
+ .createInstance(Components.interfaces.nsIXMLHttpRequest);
+
+ request.onload = function (e) {
+ if (request.readyState === 4) {
+ if (request.status === 200) {
+ if (request.getResponseHeader('Content-Type') == 'text/calendar') {
+ this._register_calendar(url, calName);
+ } else {
+ caDebug("Not a calendar: " + request.getResponseHeader('Content-Type'));
+ /* FIXME: Check collection for .ics files */
+ }
+ } else {
+ caDebug(request.statusText);
+ }
+ }
+ }.bind(this);
+
+ request.onerror = function (e) {
+ caDebug("Calendar detection failed " + e);
+ };
+
+ request.open("GET", url, true);
+ request.send(null);
+}
+
+
+function do_calendarAutoconfig(aUri) {
+ caDebug(aUri);
+
+ caldav = new caCaldavAutoconfig(document, window);
+ if (! caldav.detect_calendar(aUri)) {
+ webcal = new caWebcalAutoconfig(document, window);
+ webcal.detect_calendar(aUri);
+ }
+}