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