diff options
Diffstat (limited to 'content/calendarAutoconfig.js')
-rw-r--r-- | content/calendarAutoconfig.js | 161 |
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); + } +} |