1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_webdav.hxx"
26
27 #include <string.h>
28 #include "DAVProperties.hxx"
29 #include <rtl/ustrbuf.hxx>
30
31 using namespace http_dav_ucp;
32
33 const ::rtl::OUString DAVProperties::CREATIONDATE =
34 ::rtl::OUString::createFromAscii( "DAV:creationdate" );
35 const ::rtl::OUString DAVProperties::DISPLAYNAME =
36 ::rtl::OUString::createFromAscii( "DAV:displayname" );
37 const ::rtl::OUString DAVProperties::GETCONTENTLANGUAGE =
38 ::rtl::OUString::createFromAscii( "DAV:getcontentlanguage" );
39 const ::rtl::OUString DAVProperties::GETCONTENTLENGTH =
40 ::rtl::OUString::createFromAscii( "DAV:getcontentlength" );
41 const ::rtl::OUString DAVProperties::GETCONTENTTYPE =
42 ::rtl::OUString::createFromAscii( "DAV:getcontenttype" );
43 const ::rtl::OUString DAVProperties::GETETAG =
44 ::rtl::OUString::createFromAscii( "DAV:getetag" );
45 const ::rtl::OUString DAVProperties::GETLASTMODIFIED =
46 ::rtl::OUString::createFromAscii( "DAV:getlastmodified" );
47 const ::rtl::OUString DAVProperties::LOCKDISCOVERY =
48 ::rtl::OUString::createFromAscii( "DAV:lockdiscovery" );
49 const ::rtl::OUString DAVProperties::RESOURCETYPE =
50 ::rtl::OUString::createFromAscii( "DAV:resourcetype" );
51 const ::rtl::OUString DAVProperties::SUPPORTEDLOCK =
52 ::rtl::OUString::createFromAscii( "DAV:supportedlock" );
53
54 const ::rtl::OUString DAVProperties::EXECUTABLE =
55 ::rtl::OUString::createFromAscii(
56 "http://apache.org/dav/props/executable" );
57
58 // -------------------------------------------------------------------
59 // static
createCurlPropName(const rtl::OUString & rFullName,CurlPropName & rName)60 void DAVProperties::createCurlPropName( const rtl::OUString & rFullName,
61 CurlPropName & rName )
62 {
63 if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM( "DAV:" ) ) == 0 )
64 {
65 rName.nspace = "DAV:";
66 rName.name
67 = strdup( rtl::OUStringToOString(
68 rFullName.copy( RTL_CONSTASCII_LENGTH( "DAV:" ) ),
69 RTL_TEXTENCODING_UTF8 ).getStr() );
70 }
71 else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
72 "http://apache.org/dav/props/" ) ) == 0 )
73 {
74 rName.nspace = "http://apache.org/dav/props/";
75 rName.name
76 = strdup( rtl::OUStringToOString(
77 rFullName.copy(
78 RTL_CONSTASCII_LENGTH(
79 "http://apache.org/dav/props/" ) ),
80 RTL_TEXTENCODING_UTF8 ).getStr() );
81 }
82 else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
83 "http://ucb.openoffice.org/dav/props/" ) ) == 0 )
84 {
85 rName.nspace = "http://ucb.openoffice.org/dav/props/";
86 rName.name
87 = strdup( rtl::OUStringToOString(
88 rFullName.copy(
89 RTL_CONSTASCII_LENGTH(
90 "http://ucb.openoffice.org/dav/props/" ) ),
91 RTL_TEXTENCODING_UTF8 ).getStr() );
92 }
93 else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
94 "<prop:" ) ) == 0 )
95 {
96 // Support for 3rd party namespaces/props
97
98 rtl::OString aFullName
99 = rtl::OUStringToOString( rFullName, RTL_TEXTENCODING_UTF8 );
100
101 // Format: <prop:the_propname xmlns:prop="the_namespace">
102
103 sal_Int32 nStart = RTL_CONSTASCII_LENGTH( "<prop:" );
104 sal_Int32 nLen = aFullName.indexOf( ' ' ) - nStart;
105 rName.name = strdup( aFullName.copy( nStart, nLen ).getStr() );
106
107 nStart = aFullName.indexOf( '=', nStart + nLen ) + 2; // after ="
108 nLen = aFullName.getLength() - RTL_CONSTASCII_LENGTH( "\">" ) - nStart;
109 rName.nspace = strdup( aFullName.copy( nStart, nLen ).getStr() );
110 }
111 else
112 {
113 // Add our namespace to our own properties.
114 rName.nspace = "http://ucb.openoffice.org/dav/props/";
115 rName.name
116 = strdup( rtl::OUStringToOString( rFullName,
117 RTL_TEXTENCODING_UTF8 ).getStr() );
118 }
119 }
120
121 // -------------------------------------------------------------------
122 // static
createUCBPropName(const char * nspace,const char * name,rtl::OUString & rFullName)123 void DAVProperties::createUCBPropName( const char * nspace,
124 const char * name,
125 rtl::OUString & rFullName )
126 {
127 rtl::OUString aNameSpace
128 = rtl::OStringToOUString( nspace, RTL_TEXTENCODING_UTF8 );
129 rtl::OUString aName
130 = rtl::OStringToOUString( name, RTL_TEXTENCODING_UTF8 );
131
132 if ( !aNameSpace.getLength() )
133 {
134 // Some servers send XML without proper namespaces. Assume "DAV:"
135 // in this case, if name is a well-known dav property name.
136 // Although this is not 100% correct, it solves many problems.
137
138 if ( DAVProperties::RESOURCETYPE.matchIgnoreAsciiCase( aName, 4 ) ||
139 DAVProperties::SUPPORTEDLOCK.matchIgnoreAsciiCase( aName, 4 ) ||
140 DAVProperties::LOCKDISCOVERY.matchIgnoreAsciiCase( aName, 4 ) ||
141 DAVProperties::CREATIONDATE.matchIgnoreAsciiCase( aName, 4 ) ||
142 DAVProperties::DISPLAYNAME.matchIgnoreAsciiCase( aName, 4 ) ||
143 DAVProperties::GETCONTENTLANGUAGE.matchIgnoreAsciiCase( aName, 4 ) ||
144 DAVProperties::GETCONTENTLENGTH.matchIgnoreAsciiCase( aName, 4 ) ||
145 DAVProperties::GETCONTENTTYPE.matchIgnoreAsciiCase( aName, 4 ) ||
146 DAVProperties::GETETAG.matchIgnoreAsciiCase( aName, 4 ) ||
147 DAVProperties::GETLASTMODIFIED.matchIgnoreAsciiCase( aName, 4 ) )
148 {
149 aNameSpace = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DAV:" ) );
150 }
151 }
152
153 // Note: Concatenating strings BEFORE comparing against known namespaces
154 // is important. See RFC 2815 ( 23.4.2 Meaning of Qualified Names ).
155 rFullName = aNameSpace;
156 rFullName += aName;
157
158 if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
159 "DAV:" ) ) == 0 )
160 {
161 // Okay, Just concat strings.
162 }
163 else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
164 "http://apache.org/dav/props/" ) ) == 0 )
165 {
166 // Okay, Just concat strings.
167 }
168 else if ( rFullName.compareToAscii( RTL_CONSTASCII_STRINGPARAM(
169 "http://ucb.openoffice.org/dav/props/" ) ) == 0 )
170 {
171 // Remove namespace from our own properties.
172 rFullName = rFullName.copy(
173 RTL_CONSTASCII_LENGTH(
174 "http://ucb.openoffice.org/dav/props/" ) );
175 }
176 else
177 {
178 // Create property name that encodes, namespace and name ( XML ).
179 rFullName = rtl::OUString::createFromAscii( "<prop:" );
180 rFullName += aName;
181 rFullName += rtl::OUString::createFromAscii( " xmlns:prop=\"" );
182 rFullName += aNameSpace;
183 rFullName += rtl::OUString::createFromAscii( "\">" );
184 }
185 }
186
187 // -------------------------------------------------------------------
188 // static
isUCBDeadProperty(const CurlPropName & rName)189 bool DAVProperties::isUCBDeadProperty( const CurlPropName & rName )
190 {
191 return ( rName.nspace &&
192 ( rtl_str_compareIgnoreAsciiCase(
193 rName.nspace, "http://ucb.openoffice.org/dav/props/" )
194 == 0 ) );
195 }
196
isUCBSpecialProperty(const rtl::OUString & rFullName,rtl::OUString & rParsedName)197 bool DAVProperties::isUCBSpecialProperty(const rtl::OUString& rFullName, rtl::OUString& rParsedName)
198 {
199 sal_Int32 nLen = rFullName.getLength();
200 if ( nLen <= 0 ||
201 !rFullName.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "<prop:" ) ) ||
202 !rFullName.endsWithAsciiL( RTL_CONSTASCII_STRINGPARAM( "\">" ) ) )
203 return false;
204
205 sal_Int32 nStart = RTL_CONSTASCII_LENGTH( "<prop:" );
206 sal_Int32 nEnd = rFullName.indexOf( sal_Unicode( ' ' ), nStart );
207 if ( nEnd == -1 )
208 return false;
209
210 rtl::OUString sPropName = rFullName.copy( nStart, nEnd - nStart );
211 if ( !sPropName.getLength() )
212 return false;
213
214 // TODO skip whitespaces?
215 if ( !rFullName.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( "xmlns:prop=\"" ), ++nEnd ) )
216 return false;
217
218 nStart = nEnd + RTL_CONSTASCII_LENGTH( "xmlns:prop=\"" );
219 nEnd = rFullName.indexOf( sal_Unicode( '"' ), nStart );
220 if ( nEnd != nLen - RTL_CONSTASCII_LENGTH( "\">" ) )
221 return false;
222
223 rtl::OUString sNamesp = rFullName.copy( nStart, nEnd - nStart );
224 if ( !( nLen = sNamesp.getLength() ) )
225 return false;
226
227 rtl::OUStringBuffer aBuff( sNamesp );
228 if ( sNamesp[nLen - 1] != '/' )
229 aBuff.append( sal_Unicode( '/' ) );
230 aBuff.append( sPropName );
231 rParsedName = aBuff.makeStringAndClear();
232
233 return rParsedName.getLength();
234 }
235