[Tickets #12773] Re: Thunderbird lightning caldav serial event time failure with summer/wintertime change
noreply at bugs.horde.org
noreply at bugs.horde.org
Wed Mar 5 23:27:04 UTC 2014
DO NOT REPLY TO THIS MESSAGE. THIS EMAIL ADDRESS IS NOT MONITORED.
Ticket URL: http://bugs.horde.org/ticket/12773
------------------------------------------------------------------------------
Ticket | 12773
Updated By | benrose at math.princeton.edu
Summary | Thunderbird lightning caldav serial event time failure
| with summer/wintertime change
Queue | Kronolith
Version | 4.1.3
Type | Bug
State | Not A Bug
Priority | 1. Low
Milestone |
Patch |
Owners |
------------------------------------------------------------------------------
benrose at math.princeton.edu (2014-03-05 23:27) wrote:
So I have a workaround... but not quite a fix yet.
I started knowing that something is wonky with sending UTC in DTSTART
and DTEND. Google wasn't doing that in their iCal. Also Google was
sending a VTIMEZONE section. Investigating the RFC for iCal formats.It
says:
-----
The "VTIMEZONE" calendar component MUST be present if the iCalendar
object contains an RRULE that generates dates on both sides of a time
zone shift (e.g. both in Standard Time and Daylight Saving Time)
unless the iCalendar object intends to convey a floating time (See the
section "4.1.10.11 Time" for proper interpretation of floating time).
It can be present if the iCalendar object does not contain such a
RRULE. In addition, if a RRULE is present, there MUST be valid time
zone information for all recurrence instances.
-----
So I added a VTIMEZONE section to my file I posted earlier, horde's
output.ics. That didn't work. I took that back out, and then just
changed the dates in DTSTART and DTEND to include a TZID definition
like in google's ics file. Upon importing this ICS file, it worked
properly! Clearly the answer is to be using "floating times" as the
RFC suggests, i.e. not UTC which changes relative to timezones with
observe DST.
Of course, I'm sure Horde wasn't violating RFC on purpose. So I
started looking in the Horde code where DTSTART and DTEND are parsed.
I found this of interest in kronolith/lib/Event.php:
// For certain recur types, we must output in the event's timezone
// so that the BYDAY values do not get out of sync with the UTC
// date-time. See Bug: 11339
if ($this->recurs()) {
switch ($this->recurrence->getRecurType()) {
case Horde_Date_Recurrence::RECUR_WEEKLY:
case Horde_Date_Recurrence::RECUR_YEARLY_WEEKDAY:
case Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY:
if (!$this->timezone) {
$this->timezone = date_default_timezone_get();
}
}
}
Clearly Horde is trying to set a timezone to stay in RFC compliance
for recurring events. But the TZID parameter was not being sent in the
DTSTART and DTEND parameters in the ICS download. Skip down to:
if ($this->timezone) {
try {
$tz = $GLOBALS['injector']->getInstance('Horde_Timezone');
$vEvents[] = $tz->getZone($this->timezone)->toVtimezone();
$params['TZID'] = $this->timezone;
} catch (Horde_Exception $e) {
}
}
where execution was actually ending in an exception. The line that was
failing was:
$vEvents[] = $tz->getZone($this->timezone)->toVtimezone();
which I just found by inserting some syslog lines here and there until
I narrowed down the failure. So then inside toVtimezone() I added some
more debug, but it was never being executed. So I looked in
pear/php/Horde/Timezone.php to see what was failing. It was the
function getZone being called above before passing to toVtimezone():
public function getZone($zone)
{
if (!$this->_zones) {
$this->_extractAndParse();
}
$alias = isset($this->_links[$zone]) ? $this->_links[$zone] : $zone;
if (!isset($this->_zones[$alias])) {
throw new Horde_Timezone_Exception(sprintf('Timezone %s
not found', $zone));
}
$this->_zones[$alias]->setTzid($alias);
return $this->_zones[$alias];
}
I found that
$this->_extractAndParse();
was the line failing. Looking there, I found what was failing:
protected function _extractAndParse()
{
....
if (!$this->_tmpfile) {
$this->_download();
}
It was the _download() call failing. Well, turns out _download is
trying to pull from $conf['timezone']['location'] which is defined in
kronolith/config/conf.php as ftp://ftp.iana.org/tz/tzdata-latest.tar.gz'
So I found that if you've got SELinux enforcing (which you should),
you'll need to make sure you enable httpd_can_network_connect so that
kronolith can download this data from the iana ftp server. You'll also
need to open iptables/firewall/network access to ftp.iana.org if you
lock that down. Once I did this, Horde was sending ICS properly again,
every recurring event had their DTSTART and DTEND parameters with a
TZID specification. Hooray!
However, for those of us more security-minded, I'd like to *not* have
httpd_can_network_connect enabled. I'd like to be able to load this
file in outside of CGI. So I downloaded the file manually and set the
following in kronolith/config/conf.php:
$conf['timezone']['location'] = 'file:///var/www/horde/tzdata-latest.tar.gz';
But now the code in _download in pear/php/Horde/Timezone.php failed around:
try {
if ($url['scheme'] == 'ftp') {
$vfs = new Horde_Vfs_Ftp(array('hostspec' => $url['host'],
'username' => 'anonymous',
'password' => 'anonymous'));
} else {
$vfs = new Horde_Vfs_File();
}
$this->_tmpfile = $vfs->readFile(dirname($url['path']),
basename($url['path']));
} catch (Horde_Vfs_Exception $e) {
throw new Horde_Timezone_Exception($e);
}
At the point:
$vfs = new Horde_Vfs_File();
Should this perhaps be:
$vfs = new Horde_Vfs_File(array('vfsroot' =>
Horde::getTempDir()));
as a proper construction?
More information about the bugs
mailing list