Bug 14969

Summary: roundtrip of namespaces in mixed property content broken
Product: Apache httpd-2 Reporter: Julian Reschke <julian.reschke>
Component: mod_davAssignee: Apache HTTPD Bugs Mailing List <bugs>
Status: RESOLVED DUPLICATE    
Severity: normal CC: Christopher.D.Knight, gstein
Priority: P3    
Version: 2.0.45   
Target Milestone: ---   
Hardware: PC   
OS: All   

Description Julian Reschke 2002-11-29 19:53:51 UTC
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.
Comment 1 Chris Knight 2003-03-28 23:26:35 UTC
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.)
Comment 2 Julian Reschke 2003-03-29 09:19:29 UTC
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?
Comment 3 Chris Knight 2003-03-30 13:38:04 UTC
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.
Comment 4 Chris Knight 2003-04-09 16:37:44 UTC
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);
Comment 5 Chris Knight 2003-04-18 17:57:36 UTC
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.
Comment 6 Greg Stein 2003-06-04 10:27:47 UTC
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 ***