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 60 void DAVProperties::createSerfPropName( const rtl::OUString & rFullName, 61 SerfPropName & 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 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 189 bool DAVProperties::isUCBDeadProperty( const SerfPropName & rName ) 190 { 191 return ( rName.nspace && 192 ( rtl_str_compareIgnoreAsciiCase( 193 rName.nspace, "http://ucb.openoffice.org/dav/props/" ) 194 == 0 ) ); 195 } 196 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