GNOME Bugzilla – Bug 663844
[CalDAV] calendar-home-set/href may contain full URI
Last modified: 2012-11-08 11:52:24 UTC
Evolution 3.2.1 Downstream bug https://bugzilla.novell.com/show_bug.cgi?id=726837 When trying to browse an iCloud CalDAV account, Evolution reports it cannot resolve a hostname, although the connection and password check have already been performed successfully. Reproducible: Always Steps to Reproduce: 1. File -> New -> Calendar 2. Type: Caldav 3. URL: caldav://caldav.icloud.com 4. Check "Use secure connection" 5. Enter iCloud username (form foo@bar.com) 6. Click "Browse for calendar" 7. Enter valid password Actual Results: Error message: "Server returned unexpected data. 2 - Cannot resolve hostname (caldav.icloud.comhttps)" [sic] Expected Results: Evolution should show a list of calendars.
Works for me with 3.2.2. Obviously the "https" at the end of the "2 - Cannot resolve hostname (caldav.icloud.comhttps)" is a problem, but how that got there... Is it possible the URL above is not the same as in the UI? I see the main part of it is taken from there.
Closing this bug report as no further information has been provided. Please feel free to reopen this bug if you can provide the information asked for. Thanks!
Created attachment 224420 [details] CALDAV_DEBUG=all output
Hello, I'm also getting this error when trying to connect to iCloud with Evolution 3.4.4 I've attached the CALDAV_DEBUG=all output. Perhaps you can re-open this bug? Thank you! Avner
Hm. But your log doesn't indicate an error at all if I am not mistaken. What error do you get exactly? Could you provide a screenshot?
Hi, Yes I know. Sorry it's the only log I could find that seemed relevant... The error is exactly as described by the original reporter. I've also tried any different option/URL combination I could think of but no luck. Attaching screenshots Thanks, Avner
Hi, Yes I know. Sorry it's the only log I could find that seemed relevant... The error is exactly as described by the original reporter. I've also tried any different option/URL combination I could think of but no luck. When entering an incorrect password I get a proper authenticatoin error. Attaching screenshots Thanks, Avner
Created attachment 224421 [details] error screenshot
Created attachment 224422 [details] configuration screenshot
hm. indeed. That's interesting. Your log doesn't indicate an error at all. So yeah, I guess there is something wrong with the CalDAV code.
Please let me know if there is any other info I can provide. Thanks! Avner
Thanks for the update. I see what is going on. The reason is the calendar-home-set value. Evolution's code expects path there, like the current-user-principal value is (which is used as the second choice), but it contains full URI here. > <calendar-home-set xmlns='urn:ietf:params:xml:ns:caldav'> > <href xmlns='DAV:'>https://p03-caldav.icloud.com:443/289826577/calendars > /</href> > </calendar-home-set> As the RFC 4791 [1] defines the property as full-URL, not just path, then Evolution's code does it wrong. [1] http://tools.ietf.org/html/rfc4791#section-6.2.1
Created attachment 224505 [details] [review] evo patch for evolution; This is for git master/3.6.x, which allows also full uris in calendar-home-set/href. I'm wondering whether they will redirect you to the right machine when you use in configuration: caldav://caldav.icloud.com/289826577/calendars and you'll just confirm calendar properties (aka do not browse for the calendar). You should get your default calendar.
Thank you! Is it possible to make this patch also for Evolution 3.4.4? If not then I will try to build the latest version from git (using Gentoo so I'll have to mess around with some ebuilds). I've tried setting "caldav://caldav.icloud.com/289826577/calendars" and just confirming but then for some reason it had a problem authenticating. Avner
The patch should be applicable into 3.4.4 too, though the file is different, as it resides in plugins/caldav directory, same as the function names. Compiling 3.6.x is doable, but due to changes in architecture it'll drop all your evolution sources (and mail accounts) into the new format, making the system evolution a vanilla one.
Created commit b3e0c3c in evo master (3.7.1+) Created commit d731853 in evo gnome-3-6 (3.6.2+)
Thanks for the patch! I'm now able to manually define my calendar and view it using the config you have suggested: Server - p03-caldav.icloud.com Path - /289826577/calendars However, I'm still unable to find my calendar using the "Find Calendars" button. I get the error "Could not locate user's calendars". I'm attaching new screenshots and the new debug log
Also I forgot to mention that I've installed the newest evolution from the git's master branch.
Created attachment 227141 [details] Config screenshot - NEW
Created attachment 227142 [details] Error screenshot - NEW
Created attachment 227143 [details] Caldav debug log - NEW
Another update: I was able to get rid of the 404 response in the log by setting the path to: /289826577/principal/ before pressing on "Find Calendars". I got this idea from googling this page: https://bugzilla.mozilla.org/show_bug.cgi?id=695117 But sadly, even when 'calendar-home-set' is returned corretly, I still get the same "Could not locate" dialog. I'm attaching the new log
Created attachment 227146 [details] Caldav debug log NEW WITH PATH
I see both logs end in the same place, which is good. What is not good is the XML itself. It contains calendar-home-set element, even in the correct path, only the namespaces on the elements are not the one either the libxml can read, or libxml can search. If I use your XML, then I get the same error. I changed it from: <?xml version='1.0' encoding='UTF-8'?> <multistatus xmlns='DAV:'> <response> <href>/xxx/principal/</href> <propstat> <prop> <calendar-home-set xmlns='urn:ietf:params:xml:ns:caldav'> <href xmlns='DAV:'>https://server.com/xxx/calendars/</href> </calendar-home-set> <calendar-user-address-set xmlns='urn:ietf:params:xml:ns:caldav'> <href xmlns='DAV:'>/xxx/principal/</href> </calendar-user-address-set> </prop> <status>HTTP/1.1 200 OK</status> </propstat> </response> </multistatus> to this, which works as expected: <?xml version='1.0' encoding='UTF-8'?>\n" <D:multistatus xmlns:D='DAV:' xmlns:C='urn:ietf:params:xml:ns:caldav'> <D:response> <D:href>/xxx/principal/</D:href> <D:propstat> <D:prop> <C:calendar-home-set> <D:href>https://server.com/xxx/calendars/</D:href> </C:calendar-home-set> <C:calendar-user-address-set> <D:href>/xxx/principal/</D:href> </C:calendar-user-address-set> </D:prop> <D:status>HTTP/1.1 200 OK</D:status> </D:propstat> </D:response> </D:multistatus> I'll check with libxml folks, maybe this is a bug in there.
I see. Thanks for looking into it! Can you please change the bug status since it's not resolved yet?
Where is the code calling libxml2 and doing the XPath query ? What is the query it is doing ? Let's see with example 1, assuming you are looking for the uri elements in the "DAV:" namespace thinkpad:~/XML -> cat tst.xml <?xml version='1.0' encoding='UTF-8'?> <multistatus xmlns='DAV:'> <response> <href>/xxx/principal/</href> <propstat> <prop> <calendar-home-set xmlns='urn:ietf:params:xml:ns:caldav'> <href xmlns='DAV:'>https://server.com/xxx/calendars/</href> </calendar-home-set> <calendar-user-address-set xmlns='urn:ietf:params:xml:ns:caldav'> <href xmlns='DAV:'>/xxx/principal/</href> </calendar-user-address-set> </prop> <status>HTTP/1.1 200 OK</status> </propstat> </response> </multistatus> thinkpad:~/XML -> xmllint --shell tst.xml / > setns d=DAV: / > xpath //d:href Object is a Node Set : Set contains 3 nodes: 1 ELEMENT href 2 ELEMENT href default namespace href=DAV: 3 ELEMENT href default namespace href=DAV: / > seems to work just fine. d prefix for XPath is associated to the namespace. the XPath query using it work as expected and find the 3 href nodes independently of the location of their namespace declaration. thinkpad:~/XML -> cat tst2.xml <?xml version='1.0' encoding='UTF-8'?> <D:multistatus xmlns:D='DAV:' xmlns:C='urn:ietf:params:xml:ns:caldav'> <D:response> <D:href>/xxx/principal/</D:href> <D:propstat> <D:prop> <C:calendar-home-set> <D:href>https://server.com/xxx/calendars/</D:href> </C:calendar-home-set> <C:calendar-user-address-set> <D:href>/xxx/principal/</D:href> </C:calendar-user-address-set> </D:prop> <D:status>HTTP/1.1 200 OK</D:status> </D:propstat> </D:response> </D:multistatus> thinkpad:~/XML -> xmllint --shell tst2.xml / > setns d=DAV: / > xpath //d:href Object is a Node Set : Set contains 3 nodes: 1 ELEMENT D:href 2 ELEMENT D:href 3 ELEMENT D:href / > Works exactly the same in the second case. I don't know what kind of XPath Query Evo is doing, of how it handled the namespaces, but libxml2 XPath namespace handling should be fine because this has been tested over a decade especially with XSLT, if there was a bug there I would be quite surprized ! Daniel
(In reply to comment #26) > Where is the code calling libxml2 and doing the XPath query ? > What is the query it is doing ? It starts here: http://git.gnome.org/browse/evolution/tree/modules/cal-config-caldav/e-caldav-chooser.c#n928 Quite likely I'm doing something wrong since it was my first exposure to XPath.
Lines 953-955 xp_ctx = xmlXPathNewContext (doc); xmlXPathRegisterNs (xp_ctx, XC ("D"), XC (NS_WEBDAV)); xmlXPathRegisterNs (xp_ctx, XC ("C"), XC (NS_CALDAV)); look fine, they create the new context and register the two namespaces but the resulting XPath query is hidden in the guts of caldav_chooser_get_xpath_string() whose semantic seems to just assemble the query to get a string back assuming it gets a node set with a unique node back thinkpad:~/XML -> xmllint --shell tst.xml / > setns D=DAV: / > setns C=urn:ietf:params:xml:ns:caldav / > xpath /D:multistatus/D:response/D:propstat/D:prop/C:calendar-home-set/D:href Object is a Node Set : Set contains 1 nodes: 1 ELEMENT href default namespace href=DAV: / > xpath /D:multistatus/D:response/D:propstat/D:prop/D:principal-URL/D:href Object is a Node Set : NodeSet is NULL ! / > xpath /D:multistatus/D:response/D:propstat/D:prop/D:resourcetype/C:calendar Object is a Node Set : NodeSet is NULL ! / > xpath /D:multistatus/D:response/D:propstat/D:prop/D:current-user-principal/D:href Object is a Node Set : NodeSet is NULL ! / > that's libxml2 answer to the 4 XPath expression I suppose may be constructed in that function for the first XML thinkpad:~/XML -> xmllint --shell tst2.xml / > setns D=DAV: / > setns C=urn:ietf:params:xml:ns:caldav / > xpath /D:multistatus/D:response/D:propstat/D:prop/C:calendar-home-set/D:href Object is a Node Set : Set contains 1 nodes: 1 ELEMENT D:href / > xpath /D:multistatus/D:response/D:propstat/D:prop/D:principal-URL/D:href Object is a Node Set : NodeSet is NULL ! / > xpath /D:multistatus/D:response/D:propstat/D:prop/D:resourcetype/C:calendar Object is a Node Set : NodeSet is NULL ! / > xpath /D:multistatus/D:response/D:propstat/D:prop/D:current-user-principal/D:href Object is a Node Set : NodeSet is NULL ! / > that's libxml2 results for the same queries on the second document. The result are similar. So the play with the location of the namespace definitions has apparently no effect on libxml2 XPath as it should. Something *else* is going on, and a good gdb session should be able to tell where there is a difference in behaviour and what code introduce it. But based on my own testing I don't see why this would be libxml2 fault well unless my assumptions of the final XPath queries was wrong and you can provide me with an alternate set exposing the difference in behaviour. Daniel
The evolution code should succeed in the first XPath query: /D:multistatus/D:response/D:propstat/D:prop/C:calendar-home-set/D:href in both cases, though it fails in the case of original iCloud XML. Even unlikely, I thought the issue is with libxml2, because the only change I did was adding namespaces to XML elements and nothing else, which made it work. Nonetheless, if the xmllint works, then I'll debug further in evolution code. Thanks for testing it, Daniel.
Where is that iCloud XML ? if that's one of the two XML provided then by definition if xmllint xpath query works on it, then libxml2 XPath does indeed work with it. If that's a third version, pass it along or just duplicate the test I did. Your problem seems to be evolution code not succeeding at this query, but at the bottom, if libxml2 get a properly set XPath context with the right request as i have shown it does its work, Daniel
Created attachment 227234 [details] test.c I extracted relevant parts to a test.c, which can be compiled and run easily out of evolution. The current results are: Bad XML result:'[null]' Good XML result:'https://server.com/xxx/calendars/' while both should have return the same value. I see the caldav_chooser_get_xpath_string() does two things: a) it casts the path into 'string' b) while in gdb, the xp_obj is not NULL, but it doesn't contain the value (string value is an empty string), and if I'll not cast it, the value is: (gdb) p *xp_obj $1 = {type = XPATH_NODESET, nodesetval = 0x25e0f80, boolval = 0, floatval = 0, stringval = 0x0, user = 0x0, index = 0, user2 = 0x0, index2 = 0} (gdb) p *xp_obj->nodesetval $2 = {nodeNr = 0, nodeMax = 0, nodeTab = 0x0} which is suspicious, because the good xml has nodesetval non-null. Strange is that xmllint can read this correctly, I just verified. Is it possible that we are missing, or have some extra, flags in a call to xmlReadMemory()? There are currently defined: XML_PARSE_NONET | XML_PARSE_NOBLANKS | XML_PARSE_NSCLEAN | XML_PARSE_NOCDATA | XML_PARSE_COMPACT plus one I removed for debug purposes, XML_PARSE_NOWARNING.
(I missed comment #30 when attaching the test case): The iCloud XML is the provided test xml, the bad one. The good one has added explicit namespaces only. See the test.c for easier orientation.
For a start drop XML_PARSE_NOBLANKS and XML_PARSE_NSCLEAN. They modify the input document and you should *not* do this for XPath processing ! This is a violation of the XPath data model. NOCDATA is needed to merge text nodes and CDATA nodes as required by the XPath data model. NONET is a safety feature, and COMPACT should be fine. Daniel
Your example raised a bug in the NSCLEAN parser option, which really should not be used in a systematic fashion: http://git.gnome.org/browse/libxml2/commit/?id=711b15d545713b3a34a51ce8163d1162533647c9 I would not reassign the bug to libxml2 though, the NOBLANKS and NSCLEAN options should not be used to load the WebDAV/CalDAV data Daniel
Created attachment 227533 [details] [review] evo patch ][ for evolution; Thanks for the guidance, I dropped the two flags as you said and it does what it should now. I'm committing this to sources.
Created commit ac5d61b in evo master (3.7.2+) Created commit bcdb29a in evo gnome-3-6 (3.6.2+)
Great :-) Daniel
Thanks for all of the great work! Unfortunately..I've updated evolution from the git and I still get the same error message. Were you able to select a calendar on your pc? I'm attaching the log which looks pretty much the same. Thanks, Avner
Created attachment 227684 [details] Caldav debug log 3
I just tested this and it works with your XML as expected - in the test.c code. Are you sure the patch from comment #35 is applied in your sources and you compiled it as expected? In case you've compiled with debug symbols, you can try to run evolution in gdb and check what is happening, if you do that like this: $ gdb evolution --ex "b e-caldav-chooser.c:979" --ex r --ex n --ex "p calendar_home_set" which should stop at line calendar_home_set = caldav_chooser_get_xpath_string ( then it'll step after it and print the 'calendar_home_set' variable, which should be non-NULL, as it is in my test program. Then you can either "c" for continue or "n" to step further to see what will happen, but if you are seeing NULL for the variable, then there is still going something wrong. Please watch the messages from gdb itself, it warns if the source files don't match the executable (aka if you updated sources, but the rebuild didn't finish properly).
Hi, So I've tested with gdb and the value was indeed NULL , but - when looking at the source file it seems the patch wasn't applied even though I updated from the git. I will try to clean everything and reinstall and let you know how it turned out. Thanks! Avner