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 /************************************************************************** 28 TODO 29 ************************************************************************** 30 31 *************************************************************************/ 32 #include <ucbhelper/contentidentifier.hxx> 33 #include "webdavprovider.hxx" 34 #include "webdavcontent.hxx" 35 #include "webdavuseragent.hxx" 36 37 #include <osl/mutex.hxx> 38 #include <rtl/ustrbuf.hxx> 39 #include <comphelper/processfactory.hxx> 40 #include <com/sun/star/beans/NamedValue.hpp> 41 #include <com/sun/star/container/XNameAccess.hpp> 42 #include <apr_version.h> 43 #include <apu_version.h> 44 #include <serf.h> 45 46 using namespace com::sun::star; 47 using namespace http_dav_ucp; 48 49 50 rtl::OUString &WebDAVUserAgent::operator()() const 51 { 52 rtl::OUStringBuffer aBuffer; 53 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Apache " )); 54 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "$ooName/$ooSetupVersion" )); 55 #if OSL_DEBUG_LEVEL > 0 56 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " apr/" ) ); 57 aBuffer.appendAscii(apr_version_string()); 58 59 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " apr-util/" ) ); 60 aBuffer.appendAscii(apu_version_string()); 61 62 int major, minor, patch; 63 serf_lib_version(&major, &minor, &patch); 64 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " serf/" ) ); 65 aBuffer.append(major); 66 aBuffer.append( L'.' ); 67 aBuffer.append(minor); 68 aBuffer.append( L'.' ); 69 aBuffer.append(patch); 70 #endif 71 static rtl::OUString aUserAgent( aBuffer.makeStringAndClear() ); 72 return aUserAgent; 73 } 74 75 //========================================================================= 76 //========================================================================= 77 // 78 // ContentProvider Implementation. 79 // 80 //========================================================================= 81 //========================================================================= 82 83 ContentProvider::ContentProvider( 84 const uno::Reference< lang::XMultiServiceFactory >& rSMgr ) 85 : ::ucbhelper::ContentProviderImplHelper( rSMgr ), 86 m_xDAVSessionFactory( new DAVSessionFactory() ), 87 m_pProps( 0 ) 88 { 89 static bool bInit = false; 90 if ( bInit ) 91 return; 92 bInit = true; 93 try 94 { 95 uno::Reference< uno::XComponentContext > xContext( 96 ::comphelper::getProcessComponentContext() ); 97 uno::Reference< lang::XMultiServiceFactory > xConfigProvider( 98 xContext->getServiceManager()->createInstanceWithContext( 99 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 100 "com.sun.star.configuration.ConfigurationProvider")), xContext), 101 uno::UNO_QUERY_THROW ); 102 103 beans::NamedValue aNodePath; 104 aNodePath.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) ); 105 aNodePath.Value <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("/org.openoffice.Setup/Product")); 106 107 uno::Sequence< uno::Any > aArgs( 1 ); 108 aArgs[0] <<= aNodePath; 109 110 uno::Reference< container::XNameAccess > xConfigAccess( 111 xConfigProvider->createInstanceWithArguments( 112 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( 113 "com.sun.star.configuration.ConfigurationAccess")), aArgs), 114 uno::UNO_QUERY_THROW ); 115 116 rtl::OUString aVal; 117 xConfigAccess->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooName"))) >>= aVal; 118 119 rtl::OUString &aUserAgent = WebDAVUserAgent::get(); 120 sal_Int32 nIndex = aUserAgent.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "$ooName" ) ); 121 if ( !aVal.getLength() || nIndex == -1 ) 122 return; 123 aUserAgent = aUserAgent.replaceAt( nIndex, RTL_CONSTASCII_LENGTH( "$ooName" ), aVal ); 124 125 xConfigAccess->getByName(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ooSetupVersion"))) >>= aVal; 126 nIndex = aUserAgent.indexOfAsciiL( RTL_CONSTASCII_STRINGPARAM( "$ooSetupVersion" ) ); 127 if ( !aVal.getLength() || nIndex == -1 ) 128 return; 129 aUserAgent = aUserAgent.replaceAt( nIndex, RTL_CONSTASCII_LENGTH( "$ooSetupVersion" ), aVal ); 130 131 } 132 catch ( const uno::Exception &e ) 133 { 134 OSL_TRACE( "ContentProvider -caught exception! %s", 135 rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_UTF8 ).getStr() ); 136 (void) e; 137 } 138 } 139 140 //========================================================================= 141 // virtual 142 ContentProvider::~ContentProvider() 143 { 144 delete m_pProps; 145 } 146 147 //========================================================================= 148 // 149 // XInterface methods. 150 // 151 //========================================================================= 152 153 XINTERFACE_IMPL_3( ContentProvider, 154 lang::XTypeProvider, 155 lang::XServiceInfo, 156 ucb::XContentProvider ); 157 158 //========================================================================= 159 // 160 // XTypeProvider methods. 161 // 162 //========================================================================= 163 164 XTYPEPROVIDER_IMPL_3( ContentProvider, 165 lang::XTypeProvider, 166 lang::XServiceInfo, 167 ucb::XContentProvider ); 168 169 //========================================================================= 170 // 171 // XServiceInfo methods. 172 // 173 //========================================================================= 174 175 XSERVICEINFO_IMPL_1( ContentProvider, 176 rtl::OUString::createFromAscii( 177 "com.sun.star.comp.WebDAVContentProvider" ), 178 rtl::OUString::createFromAscii( 179 WEBDAV_CONTENT_PROVIDER_SERVICE_NAME ) ); 180 181 //========================================================================= 182 // 183 // Service factory implementation. 184 // 185 //========================================================================= 186 187 ONE_INSTANCE_SERVICE_FACTORY_IMPL( ContentProvider ); 188 189 //========================================================================= 190 // 191 // XContentProvider methods. 192 // 193 //========================================================================= 194 195 // virtual 196 uno::Reference< ucb::XContent > SAL_CALL 197 ContentProvider::queryContent( 198 const uno::Reference< 199 ucb::XContentIdentifier >& Identifier ) 200 throw( ucb::IllegalIdentifierException, 201 uno::RuntimeException ) 202 { 203 // Check URL scheme... 204 205 const rtl::OUString aScheme 206 = Identifier->getContentProviderScheme().toAsciiLowerCase(); 207 if ( !aScheme.equalsAsciiL( 208 RTL_CONSTASCII_STRINGPARAM( HTTP_URL_SCHEME ) ) && 209 !aScheme.equalsAsciiL( 210 RTL_CONSTASCII_STRINGPARAM( HTTPS_URL_SCHEME ) ) && 211 !aScheme.equalsAsciiL( 212 RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) && 213 !aScheme.equalsAsciiL( 214 RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) && 215 !aScheme.equalsAsciiL( 216 RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) ) 217 throw ucb::IllegalIdentifierException(); 218 219 // Normalize URL and create new Id, if nessacary. 220 rtl::OUString aURL = Identifier->getContentIdentifier(); 221 222 // At least: <scheme> + "://" 223 if ( aURL.getLength() < ( aScheme.getLength() + 3 ) ) 224 throw ucb::IllegalIdentifierException(); 225 226 if ( ( aURL.getStr()[ aScheme.getLength() ] != sal_Unicode( ':' ) ) || 227 ( aURL.getStr()[ aScheme.getLength() + 1 ] != sal_Unicode( '/' ) ) || 228 ( aURL.getStr()[ aScheme.getLength() + 2 ] != sal_Unicode( '/' ) ) ) 229 throw ucb::IllegalIdentifierException(); 230 231 uno::Reference< ucb::XContentIdentifier > xCanonicId; 232 233 bool bNewId = false; 234 if ( aScheme.equalsAsciiL( 235 RTL_CONSTASCII_STRINGPARAM( WEBDAV_URL_SCHEME ) ) ) 236 { 237 aURL = aURL.replaceAt( 0, 238 WEBDAV_URL_SCHEME_LENGTH, 239 rtl::OUString::createFromAscii( 240 HTTP_URL_SCHEME ) ); 241 bNewId = true; 242 } 243 else if ( aScheme.equalsAsciiL( 244 RTL_CONSTASCII_STRINGPARAM( DAV_URL_SCHEME ) ) ) 245 { 246 aURL = aURL.replaceAt( 0, 247 DAV_URL_SCHEME_LENGTH, 248 rtl::OUString::createFromAscii( 249 HTTP_URL_SCHEME ) ); 250 bNewId = true; 251 } 252 else if ( aScheme.equalsAsciiL( 253 RTL_CONSTASCII_STRINGPARAM( DAVS_URL_SCHEME ) ) ) 254 { 255 aURL = aURL.replaceAt( 0, 256 DAVS_URL_SCHEME_LENGTH, 257 rtl::OUString::createFromAscii( 258 HTTPS_URL_SCHEME ) ); 259 bNewId = true; 260 } 261 262 sal_Int32 nPos = aURL.lastIndexOf( '/' ); 263 if ( nPos != aURL.getLength() - 1 ) 264 { 265 // Find second slash in URL. 266 nPos = aURL.indexOf( '/', aURL.indexOf( '/' ) + 1 ); 267 if ( nPos == -1 ) 268 throw ucb::IllegalIdentifierException(); 269 270 nPos = aURL.indexOf( '/', nPos + 1 ); 271 if ( nPos == -1 ) 272 { 273 aURL += rtl::OUString::createFromAscii( "/" ); 274 bNewId = true; 275 } 276 } 277 278 if ( bNewId ) 279 xCanonicId = new ::ucbhelper::ContentIdentifier( m_xSMgr, aURL ); 280 else 281 xCanonicId = Identifier; 282 283 osl::MutexGuard aGuard( m_aMutex ); 284 285 // Check, if a content with given id already exists... 286 uno::Reference< ucb::XContent > xContent 287 = queryExistingContent( xCanonicId ).get(); 288 if ( xContent.is() ) 289 return xContent; 290 291 // Create a new content. 292 293 try 294 { 295 xContent = new ::http_dav_ucp::Content( 296 m_xSMgr, this, xCanonicId, m_xDAVSessionFactory ); 297 registerNewContent( xContent ); 298 } 299 catch ( ucb::ContentCreationException const & ) 300 { 301 throw ucb::IllegalIdentifierException(); 302 } 303 304 if ( !xContent->getIdentifier().is() ) 305 throw ucb::IllegalIdentifierException(); 306 307 return xContent; 308 } 309 310