PROPPATCH request: <propertyupdate xmlns='DAV:'><set><prop><test2 xmlns='xyz:'><name>Joe<abc:name xmlns:abc='abc:' ZZZ:attr='val' xmlns:ZZZ='def:'>Miller</abc:name></name>foo bar</test2></prop></set></propertyupdate> PROPFIND result: <?xml version="1.0" encoding="utf-8"?> <D:multistatus xmlns:D="DAV:"> <D:response xmlns:ns0="DAV:" xmlns:ns1="bar" xmlns:ns2="xyz:" xmlns:ns3="def:" xmlns:ns4="abc:" xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/"> <D:href>/test/</D:href> <D:propstat> <D:prop> <ns2:test2><ns0:name>Joe<ns8:name ns2:attr="val">Miller</ns8:name></ns0:name>foo bar</ns2:test2> <lp1:creationdate>2002-06-18T16:31:04Z</lp1:creationdate> <lp1:getlastmodified>Wed, 19 Jun 2002 07:55:23 GMT</lp1:getlastmodified> <lp1:getetag>"26548-0-c886786f"</lp1:getetag> <lp1:resourcetype><D:collection/></lp1:resourcetype> <D:supportedlock> <D:lockentry> <D:lockscope><D:exclusive/></D:lockscope> <D:locktype><D:write/></D:locktype> </D:lockentry> <D:lockentry> <D:lockscope><D:shared/></D:lockscope> <D:locktype><D:write/></D:locktype> </D:lockentry> </D:supportedlock> <D:lockdiscovery/> <D:getcontenttype>httpd/unix-directory</D:getcontenttype> </D:prop> <D:status>HTTP/1.1 200 OK</D:status> </D:propstat> </D:response> </D:multistatus> Note that in the result, the namespace prefix "ns8" is used, but it isn't declared, making the response non-ns-wellformed.
Here's the crux of the problem, modules/dav/main/props.c#dav_prop_exec does not pass the namespace to the store hook: err = (*propdb->db_hooks->store)(propdb->db, &name, ctx->prop, propdb->mapping); The function handling the "store" has no idea how to map the namespace id back to the name for deserialization. For the mod_dav_fs, it will have to store it in some normalized form on the backend. It should pass this namespace array, like: err = (*propdb->db_hooks->store)(propdb->db, propdb->ns_xlate, &name, ctx->prop, propdb->mapping); or probably better would be to pass an apr_xml_doc type instead of apr_xml_elem. 'course, this is going to break any backend to mod_dav, but it is critical to maintaining namespaces in property value tags. I've tested this exact change and it resolved an issue with our backend (a variant on Catacomb.)
Wouldn't it be sufficient to ensure that the property value written contains all namespace attributes that are required to round-trip the document fragment?
Yes, the problem is that the apr_xml_elem tree has namespace id's (integer index into the xlate map). In case there is confusion, the propdb->mapping array is used to map one id to another, propdb->ns_xlate maps an integer to a namespace URI.
Better would be to add the namespace array to the end of the parameters for backwards compatability. Here's the patches required to make this work: modules/dav/main/props.c: 1063c1063 < propdb->mapping); --- > propdb->mapping, propdb->ns_xlate); modules/dav/main/mod_dav.h: 1121c1121,1122 < dav_namespace_map *mapping); --- > dav_namespace_map *mapping, > apr_array_header_t *namespaces);
Note that this bug fix has been tested and found to work (and pass all of the Litmus property tests) with the Catacomb backend module.
No no... you mistake the propdb->mapping structure. That structure is under the control and definition of the provider. You can easily capture all of the URIs from that when map_namespaces is called. mod_dav_fs::map_namespaces takes the provided set of ELEM_NS -> URI mappings, folds in all unique URI values into its storage, and constructs an output "mapping" which maps ELEM_NS -> INTERNAL_NS, where INTERNAL_NS is a key into its own URI table. You can simply return the passed-in 'namespaces' variable as the result 'mapping'. The dav_namespace_map structure is opaque. In fact, this bug is a duplicate of issue 11637, which has been fixed. *** This bug has been marked as a duplicate of 11637 ***