xref: /trunk/main/ucb/source/ucp/webdav/CurlSession.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
151ba086bSDamjan Jovanovic /**************************************************************
251ba086bSDamjan Jovanovic  *
351ba086bSDamjan Jovanovic  * Licensed to the Apache Software Foundation (ASF) under one
451ba086bSDamjan Jovanovic  * or more contributor license agreements.  See the NOTICE file
551ba086bSDamjan Jovanovic  * distributed with this work for additional information
651ba086bSDamjan Jovanovic  * regarding copyright ownership.  The ASF licenses this file
751ba086bSDamjan Jovanovic  * to you under the Apache License, Version 2.0 (the
851ba086bSDamjan Jovanovic  * "License"); you may not use this file except in compliance
951ba086bSDamjan Jovanovic  * with the License.  You may obtain a copy of the License at
1051ba086bSDamjan Jovanovic  *
1151ba086bSDamjan Jovanovic  *   http://www.apache.org/licenses/LICENSE-2.0
1251ba086bSDamjan Jovanovic  *
1351ba086bSDamjan Jovanovic  * Unless required by applicable law or agreed to in writing,
1451ba086bSDamjan Jovanovic  * software distributed under the License is distributed on an
1551ba086bSDamjan Jovanovic  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
1651ba086bSDamjan Jovanovic  * KIND, either express or implied.  See the License for the
1751ba086bSDamjan Jovanovic  * specific language governing permissions and limitations
1851ba086bSDamjan Jovanovic  * under the License.
1951ba086bSDamjan Jovanovic  *
2051ba086bSDamjan Jovanovic  *************************************************************/
2151ba086bSDamjan Jovanovic 
2251ba086bSDamjan Jovanovic 
2351ba086bSDamjan Jovanovic 
2451ba086bSDamjan Jovanovic // MARKER(update_precomp.py): autogen include statement, do not remove
2551ba086bSDamjan Jovanovic #include "precompiled_webdav.hxx"
2651ba086bSDamjan Jovanovic 
2751ba086bSDamjan Jovanovic #include <hash_map>
2851ba086bSDamjan Jovanovic #include <vector>
2951ba086bSDamjan Jovanovic #include <string.h>
3051ba086bSDamjan Jovanovic #include <rtl/string.h>
3151ba086bSDamjan Jovanovic #include <rtl/strbuf.hxx>
3251ba086bSDamjan Jovanovic #include <rtl/ustrbuf.hxx>
3351ba086bSDamjan Jovanovic #include <osl/time.h>
3451ba086bSDamjan Jovanovic #include "comphelper/sequence.hxx"
3551ba086bSDamjan Jovanovic #include "ucbhelper/simplecertificatevalidationrequest.hxx"
3651ba086bSDamjan Jovanovic 
3751ba086bSDamjan Jovanovic #include "DAVAuthListener.hxx"
3851ba086bSDamjan Jovanovic #include "CurlTypes.hxx"
3951ba086bSDamjan Jovanovic #include "CurlSession.hxx"
4051ba086bSDamjan Jovanovic #include "LockRequest.hxx"
4151ba086bSDamjan Jovanovic #include "PropfindRequest.hxx"
4251ba086bSDamjan Jovanovic #include "ProppatchRequest.hxx"
4351ba086bSDamjan Jovanovic #include "CurlInputStream.hxx"
4451ba086bSDamjan Jovanovic #include "UCBDeadPropertyValue.hxx"
4551ba086bSDamjan Jovanovic #include "webdavuseragent.hxx"
4651ba086bSDamjan Jovanovic #include "webdavresponseparser.hxx"
4751ba086bSDamjan Jovanovic #include "webdavprovider.hxx"
4851ba086bSDamjan Jovanovic 
4951ba086bSDamjan Jovanovic 
5051ba086bSDamjan Jovanovic #include <com/sun/star/logging/LogLevel.hpp>
5151ba086bSDamjan Jovanovic #include <com/sun/star/security/XCertificate.hpp>
5251ba086bSDamjan Jovanovic #include <com/sun/star/security/CertificateValidity.hpp>
5351ba086bSDamjan Jovanovic #include <com/sun/star/security/CertificateContainerStatus.hpp>
5451ba086bSDamjan Jovanovic #include <com/sun/star/security/CertAltNameEntry.hpp>
5551ba086bSDamjan Jovanovic #include <com/sun/star/security/XSanExtension.hpp>
5651ba086bSDamjan Jovanovic #include <com/sun/star/ucb/Lock.hpp>
5751ba086bSDamjan Jovanovic #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
5851ba086bSDamjan Jovanovic 
5951ba086bSDamjan Jovanovic using namespace com::sun::star;
6051ba086bSDamjan Jovanovic using namespace com::sun::star::logging;
6151ba086bSDamjan Jovanovic using namespace http_dav_ucp;
6251ba086bSDamjan Jovanovic 
6351ba086bSDamjan Jovanovic #define OID_SUBJECT_ALTERNATIVE_NAME "2.5.29.17"
6451ba086bSDamjan Jovanovic 
6551ba086bSDamjan Jovanovic struct CredentialsData
6651ba086bSDamjan Jovanovic {
CredentialsDataCredentialsData6751ba086bSDamjan Jovanovic     CredentialsData( CurlSession *curlSession, CurlRequest &curlRequest, const DAVRequestEnvironment &requestEnvironment )
6851ba086bSDamjan Jovanovic     : session( curlSession)
6951ba086bSDamjan Jovanovic     , request( curlRequest )
7051ba086bSDamjan Jovanovic     , env( requestEnvironment )
7151ba086bSDamjan Jovanovic     {}
7251ba086bSDamjan Jovanovic 
7351ba086bSDamjan Jovanovic     CurlSession *session;
7451ba086bSDamjan Jovanovic     CurlRequest &request;
7551ba086bSDamjan Jovanovic     const DAVRequestEnvironment &env;
7651ba086bSDamjan Jovanovic };
7751ba086bSDamjan Jovanovic 
7851ba086bSDamjan Jovanovic // -------------------------------------------------------------------
7951ba086bSDamjan Jovanovic // static members!
8051ba086bSDamjan Jovanovic CurlLockStore CurlSession::m_aCurlLockStore;
8151ba086bSDamjan Jovanovic 
8251ba086bSDamjan Jovanovic 
8351ba086bSDamjan Jovanovic // -------------------------------------------------------------------
8451ba086bSDamjan Jovanovic // Constructor
8551ba086bSDamjan Jovanovic // -------------------------------------------------------------------
CurlSession(const rtl::Reference<DAVSessionFactory> & rSessionFactory,const rtl::OUString & inUri,const ucbhelper::InternetProxyDecider & rProxyDecider)8651ba086bSDamjan Jovanovic CurlSession::CurlSession(
8751ba086bSDamjan Jovanovic         const rtl::Reference< DAVSessionFactory > & rSessionFactory,
8851ba086bSDamjan Jovanovic         const rtl::OUString& inUri,
8951ba086bSDamjan Jovanovic         const ucbhelper::InternetProxyDecider & rProxyDecider )
9051ba086bSDamjan Jovanovic     throw ( DAVException )
9151ba086bSDamjan Jovanovic     : DAVSession( rSessionFactory )
9251ba086bSDamjan Jovanovic     , m_aMutex()
9351ba086bSDamjan Jovanovic     , m_aContext( m_xFactory->getServiceFactory() )
9451ba086bSDamjan Jovanovic     , m_aLogger( m_aContext.getUNOContext(), WEBDAV_CONTENT_PROVIDER_SERVICE_NAME )
9551ba086bSDamjan Jovanovic     , m_aUri( inUri )
9651ba086bSDamjan Jovanovic     , m_aProxyName()
9751ba086bSDamjan Jovanovic     , m_nProxyPort( 0 )
9851ba086bSDamjan Jovanovic     , m_aServerHeaderField()
9951ba086bSDamjan Jovanovic     , m_pCurl( 0 )
10051ba086bSDamjan Jovanovic     , m_bUseChunkedEncoding( false )
10151ba086bSDamjan Jovanovic     , m_bTransferEncodingSwitched( false )
10251ba086bSDamjan Jovanovic     , m_rProxyDecider( rProxyDecider )
10351ba086bSDamjan Jovanovic     , m_aEnv()
10451ba086bSDamjan Jovanovic {
10551ba086bSDamjan Jovanovic     m_pCurl = curl_easy_init();
10651ba086bSDamjan Jovanovic 
10751ba086bSDamjan Jovanovic     curl_easy_setopt( m_pCurl, CURLOPT_HTTPAUTH, CURLAUTH_ANY );
10851ba086bSDamjan Jovanovic     curl_easy_setopt( m_pCurl, CURLOPT_PROXYAUTH, CURLAUTH_ANY );
10951ba086bSDamjan Jovanovic 
11051ba086bSDamjan Jovanovic     curl_easy_setopt( m_pCurl, CURLOPT_SSL_CTX_FUNCTION, Curl_SSLContextCallback );
11151ba086bSDamjan Jovanovic     curl_easy_setopt( m_pCurl, CURLOPT_SSL_CTX_DATA, this );
11251ba086bSDamjan Jovanovic 
113*5e3c51cfSlinsong8208     // If a certificate's common name / alt name doesn't match the hostname we are
11488ba7bc9SDamjan Jovanovic     // connecting to, Curl will refuse to connect. Disable this, as we do that check
11588ba7bc9SDamjan Jovanovic     // ourselves, and give the user the option of connecting anyway.
11688ba7bc9SDamjan Jovanovic     //
11788ba7bc9SDamjan Jovanovic     // Note also, how "man CURLOPT_SSL_VERIFYHOST" tells us that setting 0 here
11888ba7bc9SDamjan Jovanovic     // disables SNI, which is bad news, some servers require SNI. However reading Curl
11988ba7bc9SDamjan Jovanovic     // 8.6.0's Curl_ssl_peer_init() in file lib/vtls/vtls.c shows that SNI is sent
12088ba7bc9SDamjan Jovanovic     // regardless, as long as we are connecting to a domain name, NOT an IP address.
12188ba7bc9SDamjan Jovanovic     // Tests confirm this. For OpenSSL anyway - other Curl crypto providers are stricter...
12288ba7bc9SDamjan Jovanovic     curl_easy_setopt( m_pCurl, CURLOPT_SSL_VERIFYHOST, 0 );
12388ba7bc9SDamjan Jovanovic 
12451ba086bSDamjan Jovanovic     if ( m_aLogger.getLogLevel() == LogLevel::FINEST )
12551ba086bSDamjan Jovanovic     {
12651ba086bSDamjan Jovanovic         curl_easy_setopt( m_pCurl, CURLOPT_DEBUGFUNCTION, Curl_DebugCallback );
12751ba086bSDamjan Jovanovic         curl_easy_setopt( m_pCurl, CURLOPT_DEBUGDATA, this );
12851ba086bSDamjan Jovanovic         curl_easy_setopt( m_pCurl, CURLOPT_VERBOSE, 1L);
12951ba086bSDamjan Jovanovic     }
130f7b97bf7SDamjan Jovanovic 
131f7b97bf7SDamjan Jovanovic     // Create a certificate container.
132f7b97bf7SDamjan Jovanovic     if( !m_aContext.createComponent( "com.sun.star.security.CertificateContainer", m_xCertificateContainer ) )
133f7b97bf7SDamjan Jovanovic         throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii( "Failed to create com.sun.star.security.CertificateContainer" ) );
134f7b97bf7SDamjan Jovanovic     uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
135f7b97bf7SDamjan Jovanovic     if( !m_aContext.createComponent( "com.sun.star.xml.crypto.SEInitializer", xSEInitializer ) )
136f7b97bf7SDamjan Jovanovic         throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii( "Failed to create com.sun.star.xml.crypto.SEInitializer" ) );
137f7b97bf7SDamjan Jovanovic     m_xSecurityContext = xSEInitializer->createSecurityContext( rtl::OUString() );
138f7b97bf7SDamjan Jovanovic     if( m_xSecurityContext.is() )
139f7b97bf7SDamjan Jovanovic         m_xSecurityEnv = m_xSecurityContext->getSecurityEnvironment();
140f7b97bf7SDamjan Jovanovic     if ( ! m_xSecurityContext.is() || ! m_xSecurityEnv.is())
141f7b97bf7SDamjan Jovanovic         throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii( "Failure creating security services for certificate verification" ) );
142f7b97bf7SDamjan Jovanovic 
143f7b97bf7SDamjan Jovanovic     // Populate one nonsense certificate, which we won't ever really use, just to get Curl to initialize:
144f7b97bf7SDamjan Jovanovic     struct curl_blob blob;
145f7b97bf7SDamjan Jovanovic     blob.data = (void*)
146f7b97bf7SDamjan Jovanovic         "-----BEGIN CERTIFICATE-----\n"
147f7b97bf7SDamjan Jovanovic         "MIIC/zCCAeegAwIBAgIUQYFHL3Bv7alQBtXQWy9SXGusm5YwDQYJKoZIhvcNAQEL\n"
148f7b97bf7SDamjan Jovanovic         "BQAwDzENMAsGA1UEAwwEVEVTVDAeFw0yNDA0MjExNzU3MzdaFw0yNDA0MjIxNzU3\n"
149f7b97bf7SDamjan Jovanovic         "MzdaMA8xDTALBgNVBAMMBFRFU1QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n"
150f7b97bf7SDamjan Jovanovic         "AoIBAQCZSXla2TE7GU6xOfie5uilpRf7KQflWcQRgwTCFhk0yzbsSPJYdqbuUqfx\n"
151f7b97bf7SDamjan Jovanovic         "k0pV9Sx8GIkvc7jKQBwS79T15qn6dAZOF40x/k2jEMq150oc/80+dqeNP2jWvxv7\n"
152f7b97bf7SDamjan Jovanovic         "FjgBKSiuGUaHldy6XU3NhrA9G1Ys2/yHQRXER1NTeknEzPiPlobRUk1sNR2Prc5r\n"
153f7b97bf7SDamjan Jovanovic         "0u6cdUWGhbDOKDV9jjvA/14jmaAK+vUqrzzAdiOHVrkglA5oyBKX0BUokRCa8jID\n"
154f7b97bf7SDamjan Jovanovic         "34tH9zeuvozA3xXCi8l9to+HOgT/n7LAGeOSnNPeSHC/xkwumt/rJ05tL9DXg6Ud\n"
155f7b97bf7SDamjan Jovanovic         "3Pjf8KZM+FWJsjoJkcwBR0P2Qh3FAgMBAAGjUzBRMB0GA1UdDgQWBBR7pCl5msAz\n"
156f7b97bf7SDamjan Jovanovic         "rGApirAQ+/tFuHl5kDAfBgNVHSMEGDAWgBR7pCl5msAzrGApirAQ+/tFuHl5kDAP\n"
157f7b97bf7SDamjan Jovanovic         "BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBDJ1S51MKlafDAfFbU\n"
158f7b97bf7SDamjan Jovanovic         "DJcxw3JNHn+VxQuaQQpeeqLIn3rgKHRBV9eOTYHf8AMoCYdQfPs1z45vqBmcyrDw\n"
159f7b97bf7SDamjan Jovanovic         "LoXL6vlUbSLUuYFyfCaFup3bbh2lLozsLcD6bcvV07amX6V3u0ZOKpwqhg+k/IJd\n"
160f7b97bf7SDamjan Jovanovic         "cPVM8jYAnNZZYD6rMHWnW5ZgMFSzSj3Jyyaov/3zwixvFZdViBG+R2RmJZVgMiFP\n"
161f7b97bf7SDamjan Jovanovic         "PNxY3USKiHqdwZIszf3G63Ku0EYtFf3KN8YpoqSMDCDfjL0NhJOtkBUs5HL+4XfK\n"
162f7b97bf7SDamjan Jovanovic         "hToBqJojDMLFRdVIhPQX1LoPd92CUwhueIrYTikScAqY2TIwXpPH0kBjfrVDus8s\n"
163f7b97bf7SDamjan Jovanovic         "vPAk\n"
164f7b97bf7SDamjan Jovanovic         "-----END CERTIFICATE-----";
165f7b97bf7SDamjan Jovanovic     blob.len = strlen( (char*) blob.data ) + 1;
166f7b97bf7SDamjan Jovanovic     blob.flags = CURL_BLOB_COPY;
167f7b97bf7SDamjan Jovanovic     CURLcode rc;
168f7b97bf7SDamjan Jovanovic     rc = curl_easy_setopt( m_pCurl, CURLOPT_CAINFO_BLOB, &blob );
169f7b97bf7SDamjan Jovanovic     if( rc != CURLE_OK )
170f7b97bf7SDamjan Jovanovic         throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii("Error initializing Curl certificate" ) );
171f7b97bf7SDamjan Jovanovic 
17251ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "CurlSession::CurlSession with URL $1$",
17351ba086bSDamjan Jovanovic         rtl::OUStringToOString( inUri, RTL_TEXTENCODING_UTF8 ).getStr() );
17451ba086bSDamjan Jovanovic }
17551ba086bSDamjan Jovanovic 
17651ba086bSDamjan Jovanovic // -------------------------------------------------------------------
17751ba086bSDamjan Jovanovic // Destructor
17851ba086bSDamjan Jovanovic // -------------------------------------------------------------------
~CurlSession()17951ba086bSDamjan Jovanovic CurlSession::~CurlSession( )
18051ba086bSDamjan Jovanovic {
18151ba086bSDamjan Jovanovic     if ( m_pCurl )
18251ba086bSDamjan Jovanovic     {
18351ba086bSDamjan Jovanovic         curl_easy_cleanup( m_pCurl );
18451ba086bSDamjan Jovanovic         m_pCurl = 0;
18551ba086bSDamjan Jovanovic         m_aLogger.log( LogLevel::INFO, "CurlSession::~CurlSession: closed curl session");
18651ba086bSDamjan Jovanovic     }
18751ba086bSDamjan Jovanovic }
18851ba086bSDamjan Jovanovic 
18951ba086bSDamjan Jovanovic // -------------------------------------------------------------------
Init(const DAVRequestEnvironment & rEnv)19051ba086bSDamjan Jovanovic void CurlSession::Init( const DAVRequestEnvironment & rEnv )
19151ba086bSDamjan Jovanovic   throw ( DAVException )
19251ba086bSDamjan Jovanovic {
19351ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
19451ba086bSDamjan Jovanovic     m_aEnv = rEnv;
19551ba086bSDamjan Jovanovic     Init();
19651ba086bSDamjan Jovanovic }
19751ba086bSDamjan Jovanovic 
19851ba086bSDamjan Jovanovic // -------------------------------------------------------------------
Init()19951ba086bSDamjan Jovanovic void CurlSession::Init()
20051ba086bSDamjan Jovanovic     throw ( DAVException )
20151ba086bSDamjan Jovanovic {
20251ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
20351ba086bSDamjan Jovanovic 
20451ba086bSDamjan Jovanovic     const sal_Char *url = rtl::OUStringToOString( m_aUri.GetURI(), RTL_TEXTENCODING_UTF8 ).getStr();
20551ba086bSDamjan Jovanovic     CURLcode rc;
20651ba086bSDamjan Jovanovic     rc = curl_easy_setopt( m_pCurl, CURLOPT_URL, url );
20751ba086bSDamjan Jovanovic     if ( rc != CURLE_OK  )
20851ba086bSDamjan Jovanovic         throw DAVException( DAVException::DAV_SESSION_CREATE,
20951ba086bSDamjan Jovanovic                             CurlUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) );
21051ba086bSDamjan Jovanovic 
21151ba086bSDamjan Jovanovic     const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
21251ba086bSDamjan Jovanovic     if ( ( rProxyCfg.aName != m_aProxyName )
21351ba086bSDamjan Jovanovic         || ( rProxyCfg.nPort != m_nProxyPort ) )
21451ba086bSDamjan Jovanovic     {
21551ba086bSDamjan Jovanovic         m_aProxyName = rProxyCfg.aName;
21651ba086bSDamjan Jovanovic         m_nProxyPort = rProxyCfg.nPort;
21751ba086bSDamjan Jovanovic         if ( !m_aProxyName.isEmpty() )
21851ba086bSDamjan Jovanovic         {
21951ba086bSDamjan Jovanovic             m_aLogger.log( LogLevel::INFO, "Using $1$ proxy server at $2$:$3$",
22051ba086bSDamjan Jovanovic                 m_aUri.GetScheme(), m_aProxyName, m_nProxyPort );
22151ba086bSDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_PROXY, rtl::OUStringToOString( m_aProxyName, RTL_TEXTENCODING_UTF8 ).getStr() );
22251ba086bSDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_PROXYPORT, (long)m_nProxyPort );
22351ba086bSDamjan Jovanovic             if ( m_aUri.GetScheme().equalsAscii( "https" ) )
22451ba086bSDamjan Jovanovic                 curl_easy_setopt( m_pCurl, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS );
22551ba086bSDamjan Jovanovic             else
22651ba086bSDamjan Jovanovic                 curl_easy_setopt( m_pCurl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP );
22751ba086bSDamjan Jovanovic             // no other proxy types are implemented by AOO
22851ba086bSDamjan Jovanovic         }
22951ba086bSDamjan Jovanovic         else
23051ba086bSDamjan Jovanovic         {
23151ba086bSDamjan Jovanovic             // Empty string as opposed to NULL, means don't use the default curl proxy.
23251ba086bSDamjan Jovanovic             m_aLogger.log( LogLevel::INFO, "Not using a proxy server" );
23351ba086bSDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_PROXY, "" );
23451ba086bSDamjan Jovanovic         }
23551ba086bSDamjan Jovanovic         // if we change the proxy settings, clear the credentials for the previous proxy too
23651ba086bSDamjan Jovanovic         curl_easy_setopt( m_pCurl, CURLOPT_PROXYUSERNAME, "" );
23751ba086bSDamjan Jovanovic         curl_easy_setopt( m_pCurl, CURLOPT_PROXYPASSWORD, "" );
23851ba086bSDamjan Jovanovic     }
23951ba086bSDamjan Jovanovic }
24051ba086bSDamjan Jovanovic 
isSSLNeeded()24151ba086bSDamjan Jovanovic bool CurlSession::isSSLNeeded()
24251ba086bSDamjan Jovanovic {
24351ba086bSDamjan Jovanovic     return m_aUri.GetScheme().equalsIgnoreAsciiCase( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "https" ) ) );
24451ba086bSDamjan Jovanovic }
24551ba086bSDamjan Jovanovic 
24651ba086bSDamjan Jovanovic // -------------------------------------------------------------------
24751ba086bSDamjan Jovanovic // helper function
24851ba086bSDamjan Jovanovic // it composes the uri for lockstore registration
composeCurrentUri(const rtl::OUString & inPath)24951ba086bSDamjan Jovanovic rtl::OUString CurlSession::composeCurrentUri(const rtl::OUString & inPath)
25051ba086bSDamjan Jovanovic {
25151ba086bSDamjan Jovanovic     rtl::OUString aScheme( m_aUri.GetScheme() );
25251ba086bSDamjan Jovanovic     rtl::OUStringBuffer aBuf( aScheme );
25351ba086bSDamjan Jovanovic     aBuf.appendAscii( "://" );
25451ba086bSDamjan Jovanovic     if ( m_aUri.GetUserName().getLength() > 0 )
25551ba086bSDamjan Jovanovic     {
25651ba086bSDamjan Jovanovic         aBuf.append( m_aUri.GetUserName() );
25751ba086bSDamjan Jovanovic         if ( m_aUri.GetPassword().getLength() > 0 )
25851ba086bSDamjan Jovanovic         {
25951ba086bSDamjan Jovanovic             aBuf.appendAscii( ":" );
26051ba086bSDamjan Jovanovic             aBuf.append( m_aUri.GetPassword() );
26151ba086bSDamjan Jovanovic         }
26251ba086bSDamjan Jovanovic         aBuf.appendAscii( "@" );
26351ba086bSDamjan Jovanovic     }
26451ba086bSDamjan Jovanovic     // Is host a numeric IPv6 address?
26551ba086bSDamjan Jovanovic     if ( ( m_aUri.GetHost().indexOf( ':' ) != -1 ) &&
26651ba086bSDamjan Jovanovic          ( m_aUri.GetHost()[ 0 ] != sal_Unicode( '[' ) ) )
26751ba086bSDamjan Jovanovic     {
26851ba086bSDamjan Jovanovic         aBuf.appendAscii( "[" );
26951ba086bSDamjan Jovanovic         aBuf.append( m_aUri.GetHost() );
27051ba086bSDamjan Jovanovic         aBuf.appendAscii( "]" );
27151ba086bSDamjan Jovanovic     }
27251ba086bSDamjan Jovanovic     else
27351ba086bSDamjan Jovanovic     {
27451ba086bSDamjan Jovanovic         aBuf.append( m_aUri.GetHost() );
27551ba086bSDamjan Jovanovic     }
27651ba086bSDamjan Jovanovic 
27751ba086bSDamjan Jovanovic     // append port, but only, if not default port.
27851ba086bSDamjan Jovanovic     bool bAppendPort = true;
27951ba086bSDamjan Jovanovic     sal_Int32 aPort = m_aUri.GetPort();
28051ba086bSDamjan Jovanovic     switch ( aPort )
28151ba086bSDamjan Jovanovic     {
28251ba086bSDamjan Jovanovic     case DEFAULT_HTTP_PORT:
28351ba086bSDamjan Jovanovic         bAppendPort = aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) );
28451ba086bSDamjan Jovanovic         break;
28551ba086bSDamjan Jovanovic 
28651ba086bSDamjan Jovanovic     case DEFAULT_HTTPS_PORT:
28751ba086bSDamjan Jovanovic         bAppendPort = !aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) );
28851ba086bSDamjan Jovanovic         break;
28951ba086bSDamjan Jovanovic     }
29051ba086bSDamjan Jovanovic     if ( bAppendPort )
29151ba086bSDamjan Jovanovic     {
29251ba086bSDamjan Jovanovic         aBuf.appendAscii( ":" );
29351ba086bSDamjan Jovanovic         aBuf.append( rtl::OUString::valueOf( aPort ) );
29451ba086bSDamjan Jovanovic     }
29551ba086bSDamjan Jovanovic     aBuf.append( inPath );
29651ba086bSDamjan Jovanovic 
29751ba086bSDamjan Jovanovic     rtl::OUString   aUri(aBuf.makeStringAndClear() );
29851ba086bSDamjan Jovanovic     return aUri;
29951ba086bSDamjan Jovanovic }
30051ba086bSDamjan Jovanovic 
30151ba086bSDamjan Jovanovic // -------------------------------------------------------------------
30251ba086bSDamjan Jovanovic // virtual
CanUse(const rtl::OUString & inUri)30351ba086bSDamjan Jovanovic sal_Bool CurlSession::CanUse( const rtl::OUString & inUri )
30451ba086bSDamjan Jovanovic {
30551ba086bSDamjan Jovanovic     try
30651ba086bSDamjan Jovanovic     {
30751ba086bSDamjan Jovanovic         CurlUri theUri( inUri );
30851ba086bSDamjan Jovanovic         if ( ( theUri.GetPort() == m_aUri.GetPort() ) &&
30951ba086bSDamjan Jovanovic              ( theUri.GetHost() == m_aUri.GetHost() ) &&
31051ba086bSDamjan Jovanovic              ( theUri.GetScheme() == m_aUri.GetScheme() ) )
31151ba086bSDamjan Jovanovic         {
31251ba086bSDamjan Jovanovic             return sal_True;
31351ba086bSDamjan Jovanovic         }
31451ba086bSDamjan Jovanovic     }
31551ba086bSDamjan Jovanovic     catch ( DAVException const & )
31651ba086bSDamjan Jovanovic     {
31751ba086bSDamjan Jovanovic         return sal_False;
31851ba086bSDamjan Jovanovic     }
31951ba086bSDamjan Jovanovic     return sal_False;
32051ba086bSDamjan Jovanovic }
32151ba086bSDamjan Jovanovic 
32251ba086bSDamjan Jovanovic // -------------------------------------------------------------------
32351ba086bSDamjan Jovanovic // virtual
UsesProxy()32451ba086bSDamjan Jovanovic sal_Bool CurlSession::UsesProxy()
32551ba086bSDamjan Jovanovic {
32651ba086bSDamjan Jovanovic     Init();
32751ba086bSDamjan Jovanovic     return ( m_aProxyName.getLength() > 0 );
32851ba086bSDamjan Jovanovic }
32951ba086bSDamjan Jovanovic 
Curl_DebugCallback(CURL *,curl_infotype type,unsigned char * data,size_t size,void * userdata)33051ba086bSDamjan Jovanovic int CurlSession::Curl_DebugCallback( CURL *, curl_infotype type, unsigned char *data, size_t size, void* userdata )
33151ba086bSDamjan Jovanovic {
33251ba086bSDamjan Jovanovic     CurlSession *session = static_cast< CurlSession* >( userdata );
33351ba086bSDamjan Jovanovic     return session->curlDebugOutput( type, reinterpret_cast<char*>( data ), size );
33451ba086bSDamjan Jovanovic }
33551ba086bSDamjan Jovanovic 
curlDebugOutput(curl_infotype type,char * data,int size)33651ba086bSDamjan Jovanovic int CurlSession::curlDebugOutput( curl_infotype type, char *data, int size )
33751ba086bSDamjan Jovanovic {
33851ba086bSDamjan Jovanovic     const char *prefix;
33951ba086bSDamjan Jovanovic     switch ( type )
34051ba086bSDamjan Jovanovic     {
34151ba086bSDamjan Jovanovic         case CURLINFO_TEXT:
34251ba086bSDamjan Jovanovic             prefix = "[CurlINFO  ]";
34351ba086bSDamjan Jovanovic             break;
34451ba086bSDamjan Jovanovic         case CURLINFO_HEADER_IN:
34551ba086bSDamjan Jovanovic             prefix = "[CurlHDR <-]";
34651ba086bSDamjan Jovanovic             break;
34751ba086bSDamjan Jovanovic         case CURLINFO_HEADER_OUT:
34851ba086bSDamjan Jovanovic             prefix = "[CurlHDR ->]";
34951ba086bSDamjan Jovanovic             break;
35051ba086bSDamjan Jovanovic         case CURLINFO_DATA_IN:
35151ba086bSDamjan Jovanovic             prefix = "[CurlData<-]";
35251ba086bSDamjan Jovanovic             break;
35351ba086bSDamjan Jovanovic         case CURLINFO_DATA_OUT:
35451ba086bSDamjan Jovanovic             prefix = "[CurlData->]";
35551ba086bSDamjan Jovanovic             break;
35651ba086bSDamjan Jovanovic         default:
35751ba086bSDamjan Jovanovic             return 0;
35851ba086bSDamjan Jovanovic     }
35951ba086bSDamjan Jovanovic 
36051ba086bSDamjan Jovanovic     // Trim the trailing \r\n
36151ba086bSDamjan Jovanovic     if ( size >= 1 && ( data[size - 1] == '\r' || data[size - 1] == '\n' ) )
36251ba086bSDamjan Jovanovic         --size;
36351ba086bSDamjan Jovanovic     if ( size >= 1 && ( data[size - 1] == '\r' || data[size - 1] == '\n' ) )
36451ba086bSDamjan Jovanovic         --size;
36551ba086bSDamjan Jovanovic     rtl::OString message( data, size );
36651ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::FINEST, "$1$ $2$", prefix, message );
36751ba086bSDamjan Jovanovic     return 0;
36851ba086bSDamjan Jovanovic }
36951ba086bSDamjan Jovanovic 
Curl_SSLContextCallback(CURL *,void * ssl_ctx,void * userptr)37051ba086bSDamjan Jovanovic CURLcode CurlSession::Curl_SSLContextCallback( CURL *, void *ssl_ctx, void *userptr )
37151ba086bSDamjan Jovanovic {
37251ba086bSDamjan Jovanovic     CurlSession *session = static_cast<CurlSession*>( userptr );
37351ba086bSDamjan Jovanovic     SSL_CTX *context = static_cast<SSL_CTX*>( ssl_ctx );
37451ba086bSDamjan Jovanovic     SSL_CTX_set_app_data( context, session );
375f7b97bf7SDamjan Jovanovic     SSL_CTX_set_cert_verify_callback( context, OPENSSL_VerifyCertificate, session );
37651ba086bSDamjan Jovanovic     return CURLE_OK;
37751ba086bSDamjan Jovanovic }
37851ba086bSDamjan Jovanovic 
OPENSSL_VerifyCertificate(X509_STORE_CTX * x509_ctx,void * arg)379f7b97bf7SDamjan Jovanovic int CurlSession::OPENSSL_VerifyCertificate( X509_STORE_CTX *x509_ctx, void *arg )
38051ba086bSDamjan Jovanovic {
381f7b97bf7SDamjan Jovanovic     CurlSession *session = static_cast<CurlSession*>( arg );
382f7b97bf7SDamjan Jovanovic     int verifyResult = session->verifyServerX509Certificate( x509_ctx );
383f7b97bf7SDamjan Jovanovic     // We have to both return 1 or 0, and set the X509_V_* error code with X509_STORE_CTX_set_error():
384f7b97bf7SDamjan Jovanovic     X509_STORE_CTX_set_error( x509_ctx, verifyResult );
385f7b97bf7SDamjan Jovanovic     return verifyResult == X509_V_OK ? 1 : 0;
38651ba086bSDamjan Jovanovic }
38751ba086bSDamjan Jovanovic 
convertCertificateToAsn1Der(X509 * certificate)38851ba086bSDamjan Jovanovic static uno::Sequence< sal_Int8 > convertCertificateToAsn1Der( X509 *certificate )
38951ba086bSDamjan Jovanovic {
39051ba086bSDamjan Jovanovic     uno::Sequence< sal_Int8 > asn1DerCertificate;
39151ba086bSDamjan Jovanovic     int len = i2d_X509( certificate, NULL );
39251ba086bSDamjan Jovanovic     if ( len < 0 )
39351ba086bSDamjan Jovanovic         return asn1DerCertificate;
39451ba086bSDamjan Jovanovic     asn1DerCertificate.realloc( len );
39551ba086bSDamjan Jovanovic     unsigned char *end = reinterpret_cast< unsigned char *>( asn1DerCertificate.getArray() );
39651ba086bSDamjan Jovanovic     len = i2d_X509( certificate, &end );
39751ba086bSDamjan Jovanovic     if ( len >= 0 )
39851ba086bSDamjan Jovanovic         return asn1DerCertificate;
39951ba086bSDamjan Jovanovic     else
40051ba086bSDamjan Jovanovic         return uno::Sequence< sal_Int8 >();
40151ba086bSDamjan Jovanovic }
40251ba086bSDamjan Jovanovic 
verifyServerX509Certificate(X509_STORE_CTX * x509StoreContext)403f7b97bf7SDamjan Jovanovic int CurlSession::verifyServerX509Certificate( X509_STORE_CTX *x509StoreContext )
40451ba086bSDamjan Jovanovic {
405f7b97bf7SDamjan Jovanovic     X509 *serverCertificate = X509_STORE_CTX_get0_cert( x509StoreContext );
406f7b97bf7SDamjan Jovanovic     STACK_OF(X509) *chain = X509_STORE_CTX_get0_untrusted( x509StoreContext );
40751ba086bSDamjan Jovanovic 
40851ba086bSDamjan Jovanovic     std::vector< uno::Sequence< sal_Int8 > > asn1DerCertificates;
409f7b97bf7SDamjan Jovanovic     int verifyResult = X509_V_OK;
41051ba086bSDamjan Jovanovic     if ( chain != NULL ) {
41151ba086bSDamjan Jovanovic         int nCertificates = sk_X509_num( chain );
412f7b97bf7SDamjan Jovanovic         for ( int i = 0; i < nCertificates && verifyResult == X509_V_OK; i++ ) {
41351ba086bSDamjan Jovanovic             X509 *certificate = sk_X509_value( chain, i );
41451ba086bSDamjan Jovanovic             uno::Sequence< sal_Int8 > asn1DerCertificate = convertCertificateToAsn1Der( certificate );
415f7b97bf7SDamjan Jovanovic             if( asn1DerCertificate.getLength() > 0 )
41651ba086bSDamjan Jovanovic                 asn1DerCertificates.push_back( asn1DerCertificate );
417f7b97bf7SDamjan Jovanovic             else
418f7b97bf7SDamjan Jovanovic                 verifyResult = X509_V_ERR_UNSPECIFIED;
41951ba086bSDamjan Jovanovic         }
42051ba086bSDamjan Jovanovic     } else {
42151ba086bSDamjan Jovanovic         uno::Sequence< sal_Int8 > asn1DerCertificate = convertCertificateToAsn1Der( serverCertificate );
422f7b97bf7SDamjan Jovanovic         if( asn1DerCertificate.getLength() > 0 )
42351ba086bSDamjan Jovanovic             asn1DerCertificates.push_back( asn1DerCertificate );
424f7b97bf7SDamjan Jovanovic         else
425f7b97bf7SDamjan Jovanovic             verifyResult = X509_V_ERR_UNSPECIFIED;
42651ba086bSDamjan Jovanovic     }
427f7b97bf7SDamjan Jovanovic     if( verifyResult == X509_V_OK )
428f7b97bf7SDamjan Jovanovic         verifyResult = verifyCertificateChain( asn1DerCertificates );
429c464040aSDamjan Jovanovic 
430f7b97bf7SDamjan Jovanovic     rtl::OUString verifyErrorString = rtl::OUString::createFromAscii( X509_verify_cert_error_string( verifyResult ) );
431f7b97bf7SDamjan Jovanovic     m_aLogger.log( LogLevel::FINE, "validateServerX509Certificate() verifyResult=$1$ ($2$)",
432f7b97bf7SDamjan Jovanovic         (sal_Int32)verifyResult, verifyErrorString );
433f7b97bf7SDamjan Jovanovic     return verifyResult;
43451ba086bSDamjan Jovanovic }
43551ba086bSDamjan Jovanovic 
verifyCertificateChain(std::vector<uno::Sequence<sal_Int8>> & asn1DerCertificates)43651ba086bSDamjan Jovanovic int CurlSession::verifyCertificateChain (
43751ba086bSDamjan Jovanovic     std::vector< uno::Sequence< sal_Int8 > > &asn1DerCertificates )
43851ba086bSDamjan Jovanovic {
43951ba086bSDamjan Jovanovic     // Check arguments.
44051ba086bSDamjan Jovanovic     if( asn1DerCertificates.size() <= 0 )
44151ba086bSDamjan Jovanovic     {
442f7b97bf7SDamjan Jovanovic         m_aLogger.log( LogLevel::WARNING, "No certificates to verify - failing!" );
443f7b97bf7SDamjan Jovanovic         return X509_V_ERR_UNSPECIFIED;
44451ba086bSDamjan Jovanovic     }
44551ba086bSDamjan Jovanovic 
44651ba086bSDamjan Jovanovic     // Decode the server certificate.
44751ba086bSDamjan Jovanovic     uno::Reference< security::XCertificate > xServerCertificate(
448f7b97bf7SDamjan Jovanovic         m_xSecurityEnv->createCertificateFromRaw( asn1DerCertificates[0] ) );
44951ba086bSDamjan Jovanovic     if ( ! xServerCertificate.is())
45051ba086bSDamjan Jovanovic     {
45151ba086bSDamjan Jovanovic         m_aLogger.log( LogLevel::WARNING, "Failed to create XCertificate" );
452f7b97bf7SDamjan Jovanovic         return X509_V_ERR_UNSPECIFIED;
45351ba086bSDamjan Jovanovic     }
45451ba086bSDamjan Jovanovic 
45551ba086bSDamjan Jovanovic     // Get the subject from the server certificate.
45651ba086bSDamjan Jovanovic     ::rtl::OUString sServerCertificateSubject (xServerCertificate->getSubjectName());
45751ba086bSDamjan Jovanovic     sal_Int32 nIndex = 0;
45851ba086bSDamjan Jovanovic     while (nIndex >= 0)
45951ba086bSDamjan Jovanovic     {
46051ba086bSDamjan Jovanovic         const ::rtl::OUString sToken (sServerCertificateSubject.getToken(0, ',', nIndex));
46151ba086bSDamjan Jovanovic         if (sToken.compareToAscii("CN=", 3) == 0)
46251ba086bSDamjan Jovanovic         {
46351ba086bSDamjan Jovanovic             sServerCertificateSubject = sToken.copy(3);
46451ba086bSDamjan Jovanovic             break;
46551ba086bSDamjan Jovanovic         }
46651ba086bSDamjan Jovanovic         else if (sToken.compareToAscii(" CN=", 4) == 0)
46751ba086bSDamjan Jovanovic         {
46851ba086bSDamjan Jovanovic             sServerCertificateSubject = sToken.copy(4);
46951ba086bSDamjan Jovanovic             break;
47051ba086bSDamjan Jovanovic         }
47151ba086bSDamjan Jovanovic     }
47251ba086bSDamjan Jovanovic 
47351ba086bSDamjan Jovanovic     // When the certificate container already contains a (trusted)
47451ba086bSDamjan Jovanovic     // entry for the server then we do not have to authenticate any
47551ba086bSDamjan Jovanovic     // certificate.
47651ba086bSDamjan Jovanovic     const security::CertificateContainerStatus eStatus (
477f7b97bf7SDamjan Jovanovic         m_xCertificateContainer->hasCertificate(
47851ba086bSDamjan Jovanovic             getHostName(), sServerCertificateSubject ) );
47951ba086bSDamjan Jovanovic     if (eStatus != security::CertificateContainerStatus_NOCERT)
48051ba086bSDamjan Jovanovic     {
48151ba086bSDamjan Jovanovic         m_aLogger.log( LogLevel::FINER, "Cached certificate found with status=$1$",
48251ba086bSDamjan Jovanovic                 eStatus == security::CertificateContainerStatus_TRUSTED ? "trusted" : "untrusted" );
48351ba086bSDamjan Jovanovic         return eStatus == security::CertificateContainerStatus_TRUSTED
484f7b97bf7SDamjan Jovanovic                ? X509_V_OK
485f7b97bf7SDamjan Jovanovic                : X509_V_ERR_CERT_UNTRUSTED;
48651ba086bSDamjan Jovanovic     }
48751ba086bSDamjan Jovanovic 
48851ba086bSDamjan Jovanovic     // The shortcut failed, so try to verify the whole chain. This is
48951ba086bSDamjan Jovanovic     // done outside the isDomainMatch() block because the result is
49051ba086bSDamjan Jovanovic     // used by the interaction handler.
49151ba086bSDamjan Jovanovic     std::vector< uno::Reference< security::XCertificate > > aChain;
49251ba086bSDamjan Jovanovic     for (nIndex=0; nIndex < asn1DerCertificates.size(); ++nIndex)
49351ba086bSDamjan Jovanovic     {
49451ba086bSDamjan Jovanovic         uno::Reference< security::XCertificate > xCertificate(
495f7b97bf7SDamjan Jovanovic             m_xSecurityEnv->createCertificateFromRaw( asn1DerCertificates[ nIndex ] ) );
49651ba086bSDamjan Jovanovic         if ( ! xCertificate.is())
49751ba086bSDamjan Jovanovic         {
498f7b97bf7SDamjan Jovanovic             m_aLogger.log( LogLevel::WARNING, "Failed to create XCertificate $1$", nIndex );
499f7b97bf7SDamjan Jovanovic             return X509_V_ERR_UNSPECIFIED;
50051ba086bSDamjan Jovanovic         }
50151ba086bSDamjan Jovanovic         aChain.push_back(xCertificate);
50251ba086bSDamjan Jovanovic     }
503f7b97bf7SDamjan Jovanovic     const sal_Int64 nVerificationResult (m_xSecurityEnv->verifyCertificate(
50451ba086bSDamjan Jovanovic             xServerCertificate,
50551ba086bSDamjan Jovanovic             ::comphelper::containerToSequence(aChain)));
50651ba086bSDamjan Jovanovic 
50751ba086bSDamjan Jovanovic     // When the certificate matches the host name then we can use the
50851ba086bSDamjan Jovanovic     // result of the verification.
50951ba086bSDamjan Jovanovic     bool bHostnameMatchesCertHostnames = false;
51051ba086bSDamjan Jovanovic     {
51151ba086bSDamjan Jovanovic         uno::Sequence< uno::Reference< security::XCertificateExtension > > extensions = xServerCertificate->getExtensions();
51251ba086bSDamjan Jovanovic         uno::Sequence< security::CertAltNameEntry > altNames;
51351ba086bSDamjan Jovanovic         for (sal_Int32 i = 0 ; i < extensions.getLength(); ++i)
51451ba086bSDamjan Jovanovic         {
51551ba086bSDamjan Jovanovic             uno::Reference< security::XCertificateExtension >element = extensions[i];
51651ba086bSDamjan Jovanovic 
51751ba086bSDamjan Jovanovic             const rtl::OString aId ( (const sal_Char *)element->getExtensionId().getArray(), element->getExtensionId().getLength());
51851ba086bSDamjan Jovanovic             if ( aId.equals( OID_SUBJECT_ALTERNATIVE_NAME ) )
51951ba086bSDamjan Jovanovic             {
52051ba086bSDamjan Jovanovic                 uno::Reference< security::XSanExtension > sanExtension ( element, uno::UNO_QUERY );
52151ba086bSDamjan Jovanovic                 altNames = sanExtension->getAlternativeNames();
52251ba086bSDamjan Jovanovic                 break;
52351ba086bSDamjan Jovanovic             }
52451ba086bSDamjan Jovanovic         }
52551ba086bSDamjan Jovanovic 
52651ba086bSDamjan Jovanovic         uno::Sequence< ::rtl::OUString > certHostNames(altNames.getLength() + 1);
52751ba086bSDamjan Jovanovic         certHostNames[0] = sServerCertificateSubject;
52851ba086bSDamjan Jovanovic         for( int n = 0; n < altNames.getLength(); ++n )
52951ba086bSDamjan Jovanovic         {
53051ba086bSDamjan Jovanovic             if (altNames[n].Type == security::ExtAltNameType_DNS_NAME)
53151ba086bSDamjan Jovanovic             {
53251ba086bSDamjan Jovanovic                 altNames[n].Value >>= certHostNames[n+1];
53351ba086bSDamjan Jovanovic             }
53451ba086bSDamjan Jovanovic         }
53551ba086bSDamjan Jovanovic 
53651ba086bSDamjan Jovanovic         for ( int i = 0; i < certHostNames.getLength() && !bHostnameMatchesCertHostnames; ++i )
53751ba086bSDamjan Jovanovic         {
53851ba086bSDamjan Jovanovic             bHostnameMatchesCertHostnames = isDomainMatch( certHostNames[i] );
53951ba086bSDamjan Jovanovic         }
54051ba086bSDamjan Jovanovic 
54151ba086bSDamjan Jovanovic     }
54251ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::FINE, "URL hostname $1$ certificate hostname",
54351ba086bSDamjan Jovanovic         bHostnameMatchesCertHostnames ? "matches" : "DOESN'T MATCH" );
54451ba086bSDamjan Jovanovic     if ( bHostnameMatchesCertHostnames )
54551ba086bSDamjan Jovanovic     {
54651ba086bSDamjan Jovanovic         if (nVerificationResult == 0)
54751ba086bSDamjan Jovanovic         {
54851ba086bSDamjan Jovanovic             m_aLogger.log( LogLevel::FINE, "Certificate (chain) is valid" );
549f7b97bf7SDamjan Jovanovic             m_xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_True);
550f7b97bf7SDamjan Jovanovic             return X509_V_OK;
55151ba086bSDamjan Jovanovic         }
55251ba086bSDamjan Jovanovic         else if ((nVerificationResult & security::CertificateValidity::CHAIN_INCOMPLETE) != 0)
55351ba086bSDamjan Jovanovic         {
55451ba086bSDamjan Jovanovic             // We do not have enough information for verification,
55551ba086bSDamjan Jovanovic             // neither automatically (as we just discovered) nor
55651ba086bSDamjan Jovanovic             // manually (so there is no point in showing any dialog.)
55751ba086bSDamjan Jovanovic             m_aLogger.log( LogLevel::WARNING, "Certificate (chain) is incomplete" );
558f7b97bf7SDamjan Jovanovic             return X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
55951ba086bSDamjan Jovanovic         }
56051ba086bSDamjan Jovanovic         else if ((nVerificationResult & security::CertificateValidity::REVOKED) != 0)
56151ba086bSDamjan Jovanovic         {
56251ba086bSDamjan Jovanovic             // Certificate (chain) is invalid.
56351ba086bSDamjan Jovanovic             m_aLogger.log( LogLevel::WARNING, "Certificate (chain) is revoked" );
564f7b97bf7SDamjan Jovanovic             m_xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject,  sal_False);
565f7b97bf7SDamjan Jovanovic             return X509_V_ERR_CERT_REVOKED;
56651ba086bSDamjan Jovanovic         }
56751ba086bSDamjan Jovanovic         else
56851ba086bSDamjan Jovanovic         {
56951ba086bSDamjan Jovanovic             // For all other we have to ask the user.
570*5e3c51cfSlinsong8208             m_aLogger.log( LogLevel::FINE, "Prompting user to validate the certificate" );
57151ba086bSDamjan Jovanovic         }
57251ba086bSDamjan Jovanovic     }
57351ba086bSDamjan Jovanovic 
57451ba086bSDamjan Jovanovic     // We have not been able to automatically verify (or falsify) the
57551ba086bSDamjan Jovanovic     // certificate chain. To resolve this we have to ask the user.
57651ba086bSDamjan Jovanovic     const uno::Reference< ucb::XCommandEnvironment > xEnv( getRequestEnvironment().m_xEnv );
57751ba086bSDamjan Jovanovic     if ( xEnv.is() )
57851ba086bSDamjan Jovanovic     {
57951ba086bSDamjan Jovanovic         uno::Reference< task::XInteractionHandler > xIH( xEnv->getInteractionHandler() );
58051ba086bSDamjan Jovanovic         if ( xIH.is() )
58151ba086bSDamjan Jovanovic         {
58251ba086bSDamjan Jovanovic             rtl::Reference< ucbhelper::SimpleCertificateValidationRequest >
58351ba086bSDamjan Jovanovic                 xRequest( new ucbhelper::SimpleCertificateValidationRequest(
58451ba086bSDamjan Jovanovic                         static_cast<sal_Int32>(nVerificationResult), xServerCertificate, getHostName() ) );
58551ba086bSDamjan Jovanovic             xIH->handle( xRequest.get() );
58651ba086bSDamjan Jovanovic 
58751ba086bSDamjan Jovanovic             rtl::Reference< ucbhelper::InteractionContinuation > xSelection
58851ba086bSDamjan Jovanovic                 = xRequest->getSelection();
58951ba086bSDamjan Jovanovic 
59051ba086bSDamjan Jovanovic             if ( xSelection.is() )
59151ba086bSDamjan Jovanovic             {
59251ba086bSDamjan Jovanovic                 uno::Reference< task::XInteractionApprove > xApprove( xSelection.get(), uno::UNO_QUERY );
59351ba086bSDamjan Jovanovic                 if ( xApprove.is() )
59451ba086bSDamjan Jovanovic                 {
59551ba086bSDamjan Jovanovic                     m_aLogger.log( LogLevel::FINE, "The user approved the certificate" );
596f7b97bf7SDamjan Jovanovic                     m_xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_True );
597f7b97bf7SDamjan Jovanovic                     return X509_V_OK;
59851ba086bSDamjan Jovanovic                 }
59951ba086bSDamjan Jovanovic                 else
60051ba086bSDamjan Jovanovic                 {
60151ba086bSDamjan Jovanovic                     // Don't trust cert
602f7b97bf7SDamjan Jovanovic                     m_aLogger.log( LogLevel::WARNING, "The user REJECTED the certificate" );
603f7b97bf7SDamjan Jovanovic                     m_xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False );
604f7b97bf7SDamjan Jovanovic                     return X509_V_ERR_CERT_REJECTED;
60551ba086bSDamjan Jovanovic                 }
60651ba086bSDamjan Jovanovic             }
60751ba086bSDamjan Jovanovic         }
60851ba086bSDamjan Jovanovic         else
60951ba086bSDamjan Jovanovic         {
61051ba086bSDamjan Jovanovic             // Don't trust cert
61151ba086bSDamjan Jovanovic             m_aLogger.log( LogLevel::WARNING, "Couldn't create the interaction handler for user feedback, rejecting the certificate" );
612f7b97bf7SDamjan Jovanovic             m_xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False );
613f7b97bf7SDamjan Jovanovic             return X509_V_ERR_CERT_REJECTED;
61451ba086bSDamjan Jovanovic         }
61551ba086bSDamjan Jovanovic     }
61651ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::WARNING, "No XCommandEnvironment, rejecting the certificate" );
61751ba086bSDamjan Jovanovic 
618f7b97bf7SDamjan Jovanovic     return X509_V_ERR_CERT_REJECTED;
61951ba086bSDamjan Jovanovic }
62051ba086bSDamjan Jovanovic 
Curl_ProvideCredentials(long statusCode,void * userdata)62151ba086bSDamjan Jovanovic bool CurlSession::Curl_ProvideCredentials( long statusCode, void *userdata ) throw (DAVException)
62251ba086bSDamjan Jovanovic {
62351ba086bSDamjan Jovanovic     CredentialsData *credentialsData = (CredentialsData*)userdata;
62451ba086bSDamjan Jovanovic     return credentialsData->session->provideCredentials( credentialsData->env, credentialsData->request, statusCode );
62551ba086bSDamjan Jovanovic }
62651ba086bSDamjan Jovanovic 
provideCredentials(const DAVRequestEnvironment & env,CurlRequest & request,long statusCode)62751ba086bSDamjan Jovanovic bool CurlSession::provideCredentials( const DAVRequestEnvironment &env, CurlRequest &request, long statusCode ) throw (DAVException)
62851ba086bSDamjan Jovanovic {
62951ba086bSDamjan Jovanovic     DAVAuthListener * pListener = env.m_xAuthListener.get();
63051ba086bSDamjan Jovanovic     if ( !pListener )
63151ba086bSDamjan Jovanovic     {
63251ba086bSDamjan Jovanovic         // abort
63351ba086bSDamjan Jovanovic         m_aLogger.log( LogLevel::FINE, "No DAVAuthListener found, failing credentials entry" );
63451ba086bSDamjan Jovanovic         return false;
63551ba086bSDamjan Jovanovic     }
63651ba086bSDamjan Jovanovic 
63751ba086bSDamjan Jovanovic     rtl::OUString theUserName;
63851ba086bSDamjan Jovanovic     rtl::OUString thePassWord;
63951ba086bSDamjan Jovanovic     try
64051ba086bSDamjan Jovanovic     {
64151ba086bSDamjan Jovanovic         CurlUri uri( env.m_aRequestURI );
64251ba086bSDamjan Jovanovic         theUserName = uri.GetUserName();
64351ba086bSDamjan Jovanovic         thePassWord = uri.GetPassword();
64451ba086bSDamjan Jovanovic     }
64551ba086bSDamjan Jovanovic     catch ( DAVException const &e )
64651ba086bSDamjan Jovanovic     {
64751ba086bSDamjan Jovanovic         // abort
64851ba086bSDamjan Jovanovic         m_aLogger.log(
64951ba086bSDamjan Jovanovic             LogLevel::WARNING,
65051ba086bSDamjan Jovanovic             "Error extracing userinfo from URI: exceptionCode=$1$, status=$2$, data=$3$, owner=$4$, extendedError=$5%",
65151ba086bSDamjan Jovanovic             (sal_Int32)e.getError(), e.getStatus(), e.getData(), e.getOwner(), e.getExtendedError()
65251ba086bSDamjan Jovanovic         );
65351ba086bSDamjan Jovanovic         return false;
65451ba086bSDamjan Jovanovic     }
65551ba086bSDamjan Jovanovic 
65651ba086bSDamjan Jovanovic     bool canUseSystemCreds = false;
65751ba086bSDamjan Jovanovic     long authMethods = 0;
65851ba086bSDamjan Jovanovic     CURLcode rc = CURLE_OK;
65951ba086bSDamjan Jovanovic     if ( statusCode == 401 )
66051ba086bSDamjan Jovanovic         rc = curl_easy_getinfo( m_pCurl, CURLINFO_HTTPAUTH_AVAIL, &authMethods );
66151ba086bSDamjan Jovanovic     else if ( statusCode == 407 )
66251ba086bSDamjan Jovanovic         rc = curl_easy_getinfo( m_pCurl, CURLINFO_PROXYAUTH_AVAIL, &authMethods );
66351ba086bSDamjan Jovanovic     if ( rc == 0 )
66451ba086bSDamjan Jovanovic         canUseSystemCreds = (authMethods & CURLAUTH_NEGOTIATE) || (authMethods & CURLAUTH_NTLM);
66551ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::FINE, "authMethods=$1$, canUseSystemCreds=$2$",
66651ba086bSDamjan Jovanovic         (sal_Int64)authMethods, (sal_Int32)canUseSystemCreds );
66751ba086bSDamjan Jovanovic 
66851ba086bSDamjan Jovanovic     const CurlRequest::Header *authHeader = NULL;
66951ba086bSDamjan Jovanovic     if ( statusCode == 401 )
67051ba086bSDamjan Jovanovic         authHeader = request.findResponseHeader( "WWW-Authenticate" );
67151ba086bSDamjan Jovanovic     else if ( statusCode == 407 )
67251ba086bSDamjan Jovanovic         authHeader = request.findResponseHeader( "Proxy-Authenticate" );
67351ba086bSDamjan Jovanovic     rtl::OUString realm;
67451ba086bSDamjan Jovanovic     if ( authHeader != NULL )
67551ba086bSDamjan Jovanovic     {
67651ba086bSDamjan Jovanovic         int realmStart = authHeader->value.indexOf( "realm=\"" );
67751ba086bSDamjan Jovanovic         if ( realmStart >= 0 )
67851ba086bSDamjan Jovanovic         {
67951ba086bSDamjan Jovanovic             realmStart += 7;
68051ba086bSDamjan Jovanovic             int realmEnd = authHeader->value.indexOf( "\"", realmStart );
68151ba086bSDamjan Jovanovic             if ( realmEnd > 0 )
68251ba086bSDamjan Jovanovic                 realm = rtl::OStringToOUString( authHeader->value.copy( realmStart, realmEnd - realmStart ), RTL_TEXTENCODING_UTF8 );
68351ba086bSDamjan Jovanovic         }
68451ba086bSDamjan Jovanovic     }
68551ba086bSDamjan Jovanovic 
68651ba086bSDamjan Jovanovic     int theRetVal = pListener->authenticate( realm,
68751ba086bSDamjan Jovanovic                                              getHostName(),
68851ba086bSDamjan Jovanovic                                              theUserName,
68951ba086bSDamjan Jovanovic                                              thePassWord,
69051ba086bSDamjan Jovanovic                                              canUseSystemCreds,
69151ba086bSDamjan Jovanovic                                              // Authenticating with both the proxy
69251ba086bSDamjan Jovanovic                                              // and the destination server requires sal_True here,
69351ba086bSDamjan Jovanovic                                              // and needs filling out 2 x password dialogs.
69451ba086bSDamjan Jovanovic                                              sal_True );
69551ba086bSDamjan Jovanovic 
69651ba086bSDamjan Jovanovic     if ( theRetVal == 0 )
69751ba086bSDamjan Jovanovic     {
69851ba086bSDamjan Jovanovic         m_aLogger.log( LogLevel::FINEST, "got credentials for user=$1$ on realm=$2$", theUserName, realm );
69951ba086bSDamjan Jovanovic         // "System credentials" means username and password are empty
70051ba086bSDamjan Jovanovic         const char *curlUsername = NULL;
70151ba086bSDamjan Jovanovic         const char *curlPassword = NULL;
70251ba086bSDamjan Jovanovic         if ( !theUserName.isEmpty() )
70351ba086bSDamjan Jovanovic             curlUsername = rtl::OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ).getStr();
70451ba086bSDamjan Jovanovic         if ( !thePassWord.isEmpty() )
70551ba086bSDamjan Jovanovic             curlPassword = rtl::OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ).getStr();
70651ba086bSDamjan Jovanovic         if ( statusCode == 401 )
70751ba086bSDamjan Jovanovic         {
70851ba086bSDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_USERNAME, curlUsername );
70951ba086bSDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_PASSWORD, curlPassword );
71051ba086bSDamjan Jovanovic         }
71151ba086bSDamjan Jovanovic         else
71251ba086bSDamjan Jovanovic         {
71351ba086bSDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_PROXYUSERNAME, curlUsername );
71451ba086bSDamjan Jovanovic             curl_easy_setopt( m_pCurl, CURLOPT_PROXYPASSWORD, curlPassword );
71551ba086bSDamjan Jovanovic         }
71651ba086bSDamjan Jovanovic         return true;
71751ba086bSDamjan Jovanovic     }
71851ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::WARNING, "credentials entry cancelled or failed" );
71951ba086bSDamjan Jovanovic 
72051ba086bSDamjan Jovanovic     return false;
72151ba086bSDamjan Jovanovic }
72251ba086bSDamjan Jovanovic 
addEnvironmentRequestHeaders(CurlRequest & curlRequest,const DAVRequestEnvironment & env)72351ba086bSDamjan Jovanovic void CurlSession::addEnvironmentRequestHeaders( CurlRequest &curlRequest, const DAVRequestEnvironment &env )
72451ba086bSDamjan Jovanovic     throw ( DAVException )
72551ba086bSDamjan Jovanovic {
72651ba086bSDamjan Jovanovic     bool bHasUserAgent( false );
72751ba086bSDamjan Jovanovic     DAVRequestHeaders::const_iterator aHeaderIter( env.m_aRequestHeaders.begin() );
72851ba086bSDamjan Jovanovic     const DAVRequestHeaders::const_iterator aEnd( env.m_aRequestHeaders.end() );
72951ba086bSDamjan Jovanovic 
73051ba086bSDamjan Jovanovic     while ( aHeaderIter != aEnd )
73151ba086bSDamjan Jovanovic     {
73251ba086bSDamjan Jovanovic         const rtl::OString aHeader = rtl::OUStringToOString( aHeaderIter->first,
73351ba086bSDamjan Jovanovic                                                              RTL_TEXTENCODING_UTF8 );
73451ba086bSDamjan Jovanovic         const rtl::OString aValue = rtl::OUStringToOString( aHeaderIter->second,
73551ba086bSDamjan Jovanovic                                                             RTL_TEXTENCODING_UTF8 );
73651ba086bSDamjan Jovanovic 
73751ba086bSDamjan Jovanovic         if ( !bHasUserAgent )
73851ba086bSDamjan Jovanovic             bHasUserAgent = aHeaderIter->first.equalsAsciiL(
73951ba086bSDamjan Jovanovic                 RTL_CONSTASCII_STRINGPARAM( "User-Agent" ) );
74051ba086bSDamjan Jovanovic 
74151ba086bSDamjan Jovanovic         curlRequest.addHeader( aHeader, aValue );
74251ba086bSDamjan Jovanovic 
74351ba086bSDamjan Jovanovic         ++aHeaderIter;
74451ba086bSDamjan Jovanovic     }
74551ba086bSDamjan Jovanovic 
74651ba086bSDamjan Jovanovic     if ( !bHasUserAgent )
74751ba086bSDamjan Jovanovic     {
74851ba086bSDamjan Jovanovic         const rtl::OUString &rUserAgent = WebDAVUserAgent::get();
74951ba086bSDamjan Jovanovic         curlRequest.addHeader( "User-Agent", rtl::OUStringToOString( rUserAgent, RTL_TEXTENCODING_UTF8 ) );
75051ba086bSDamjan Jovanovic     }
75151ba086bSDamjan Jovanovic }
75251ba086bSDamjan Jovanovic 
processResponse(CurlRequest & curlRequest,CURLcode curlCode)75351ba086bSDamjan Jovanovic void CurlSession::processResponse( CurlRequest &curlRequest, CURLcode curlCode )
75451ba086bSDamjan Jovanovic     throw( DAVException )
75551ba086bSDamjan Jovanovic {
75651ba086bSDamjan Jovanovic     long statusCode = 0;
75751ba086bSDamjan Jovanovic     CURLcode curlRes;
75851ba086bSDamjan Jovanovic     curlRes = curl_easy_getinfo( m_pCurl, CURLINFO_RESPONSE_CODE, &statusCode );
75951ba086bSDamjan Jovanovic     if ( curlRes != 0 || statusCode == 0 )
76051ba086bSDamjan Jovanovic         statusCode = curlRequest.getStatusCode();
76151ba086bSDamjan Jovanovic 
76251ba086bSDamjan Jovanovic     // check header according:
76351ba086bSDamjan Jovanovic     // http://tools.ietf.org/html/rfc7231#section-7.4.2
76451ba086bSDamjan Jovanovic     // need to do this so we can adjust the protocol accordingly
76551ba086bSDamjan Jovanovic     const CurlRequest::Header *server = curlRequest.findResponseHeader( "server" );
76651ba086bSDamjan Jovanovic     if ( server != NULL )
76751ba086bSDamjan Jovanovic         m_aServerHeaderField = server->value;
76851ba086bSDamjan Jovanovic 
76951ba086bSDamjan Jovanovic     if ( curlCode != 0 )
77051ba086bSDamjan Jovanovic     {
77151ba086bSDamjan Jovanovic         m_aLogger.log( LogLevel::WARNING, "Curl request failed with CURLcode $1$", (sal_Int64)curlCode );
772b9e06544SArrigo Marchiori         DAVException::ExceptionCode exCode = DAVException::DAV_HTTP_ERROR;
773b9e06544SArrigo Marchiori         rtl::OUString exData;
774b9e06544SArrigo Marchiori         switch (curlCode) {
775b9e06544SArrigo Marchiori         case CURLE_COULDNT_RESOLVE_HOST:
776b9e06544SArrigo Marchiori             exCode = DAVException::DAV_HTTP_LOOKUP;
777b9e06544SArrigo Marchiori             exData = CurlUri::makeConnectionEndPointString( getHostName(),
778b9e06544SArrigo Marchiori                                                             getPort() );
779b9e06544SArrigo Marchiori             break;
780b9e06544SArrigo Marchiori         case CURLE_COULDNT_CONNECT:
781b9e06544SArrigo Marchiori             exCode = DAVException::DAV_HTTP_CONNECT;
782b9e06544SArrigo Marchiori             exData = CurlUri::makeConnectionEndPointString( getHostName(),
783b9e06544SArrigo Marchiori                                                             getPort() );
784b9e06544SArrigo Marchiori             break;
785b9e06544SArrigo Marchiori         case CURLE_OPERATION_TIMEDOUT:
786b9e06544SArrigo Marchiori             exCode = DAVException::DAV_HTTP_TIMEOUT;
787b9e06544SArrigo Marchiori             exData = CurlUri::makeConnectionEndPointString( getHostName(),
788b9e06544SArrigo Marchiori                                                             getPort() );
789b9e06544SArrigo Marchiori             break;
790b9e06544SArrigo Marchiori         case CURLE_LOGIN_DENIED:
791b9e06544SArrigo Marchiori         case CURLE_AUTH_ERROR:
792b9e06544SArrigo Marchiori             exCode = DAVException::DAV_HTTP_AUTH;
793b9e06544SArrigo Marchiori             exData = CurlUri::makeConnectionEndPointString( getHostName(),
794b9e06544SArrigo Marchiori                                                             getPort() );
795b9e06544SArrigo Marchiori             break;
796b9e06544SArrigo Marchiori         default:
797b9e06544SArrigo Marchiori             {
798b9e06544SArrigo Marchiori                 const char *s = curl_easy_strerror(curlCode);
799b9e06544SArrigo Marchiori                 exCode = DAVException::DAV_HTTP_ERROR;
800b9e06544SArrigo Marchiori                 exData = ::rtl::OUString(s, strlen(s),
801b9e06544SArrigo Marchiori                                          RTL_TEXTENCODING_UTF8);
802b9e06544SArrigo Marchiori                 break;
803b9e06544SArrigo Marchiori             }
804b9e06544SArrigo Marchiori         }
805b9e06544SArrigo Marchiori         throw DAVException( exCode, exData );
80651ba086bSDamjan Jovanovic     }
80751ba086bSDamjan Jovanovic 
80851ba086bSDamjan Jovanovic     rtl::OUString reasonPhrase = rtl::OStringToOUString( curlRequest.getReasonPhrase(), RTL_TEXTENCODING_UTF8 );
80951ba086bSDamjan Jovanovic     if ( statusCode != 0 && statusCode / 100 != 2 )
81051ba086bSDamjan Jovanovic     {
81151ba086bSDamjan Jovanovic         switch (statusCode)
81251ba086bSDamjan Jovanovic         {
81351ba086bSDamjan Jovanovic             case SC_MOVED_PERMANENTLY:             // 301
81451ba086bSDamjan Jovanovic             case SC_MOVED_TEMPORARILY:             // 302
81551ba086bSDamjan Jovanovic             case SC_SEE_OTHER:                     // 303
81651ba086bSDamjan Jovanovic             case SC_TEMPORARY_REDIRECT:            // 307
81751ba086bSDamjan Jovanovic             {
81851ba086bSDamjan Jovanovic                 // new location for certain redirections
81951ba086bSDamjan Jovanovic 
82051ba086bSDamjan Jovanovic                 const CurlRequest::Header *location = curlRequest.findResponseHeader( "location" );
82151ba086bSDamjan Jovanovic                 if ( location != NULL )
82251ba086bSDamjan Jovanovic                 {
82351ba086bSDamjan Jovanovic                     m_aLogger.log( LogLevel::FINE, "HTTP $1$ response with new location = $2$",
82451ba086bSDamjan Jovanovic                         statusCode, location->value );
82551ba086bSDamjan Jovanovic                     throw DAVException( DAVException::DAV_HTTP_REDIRECT,
82651ba086bSDamjan Jovanovic                                         rtl::OStringToOUString( location->value, RTL_TEXTENCODING_UTF8 ) );
82751ba086bSDamjan Jovanovic                 }
82851ba086bSDamjan Jovanovic                 break;
82951ba086bSDamjan Jovanovic             }
83051ba086bSDamjan Jovanovic             case SC_UNAUTHORIZED:                  // 401
83151ba086bSDamjan Jovanovic             case SC_PROXY_AUTHENTICATION_REQUIRED: // 407
83251ba086bSDamjan Jovanovic             {
83351ba086bSDamjan Jovanovic                 throw DAVException( DAVException::DAV_HTTP_ERROR,
83451ba086bSDamjan Jovanovic                                     reasonPhrase,
83551ba086bSDamjan Jovanovic                                     statusCode );
83651ba086bSDamjan Jovanovic                 break;
83751ba086bSDamjan Jovanovic             }
83851ba086bSDamjan Jovanovic             case SC_REQUEST_ENTITY_TOO_LARGE:      // 413
83951ba086bSDamjan Jovanovic             {
84051ba086bSDamjan Jovanovic                 if ( m_bTransferEncodingSwitched )
84151ba086bSDamjan Jovanovic                     throw DAVException( DAVException::DAV_HTTP_ERROR,
84251ba086bSDamjan Jovanovic                                         reasonPhrase,
84351ba086bSDamjan Jovanovic                                         statusCode );
84451ba086bSDamjan Jovanovic                 m_bTransferEncodingSwitched = true;
84551ba086bSDamjan Jovanovic                 curlRequest.setChunkedEncoding( !curlRequest.isChunkedEncoding() );
84651ba086bSDamjan Jovanovic                 break;
84751ba086bSDamjan Jovanovic             }
84851ba086bSDamjan Jovanovic             case SC_LOCKED:                        // 423
84951ba086bSDamjan Jovanovic                 throw DAVException( DAVException::DAV_LOCKED,
85051ba086bSDamjan Jovanovic                                     reasonPhrase,
85151ba086bSDamjan Jovanovic                                     statusCode );
85251ba086bSDamjan Jovanovic             default:
85351ba086bSDamjan Jovanovic                 throw DAVException( DAVException::DAV_HTTP_ERROR,
85451ba086bSDamjan Jovanovic                                     reasonPhrase,
85551ba086bSDamjan Jovanovic                                     statusCode );
85651ba086bSDamjan Jovanovic         }
85751ba086bSDamjan Jovanovic     }
85851ba086bSDamjan Jovanovic }
85951ba086bSDamjan Jovanovic 
responseHeadersToDAVResource(const std::vector<CurlRequest::Header> & responseHeaders,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource)86051ba086bSDamjan Jovanovic static void responseHeadersToDAVResource( const std::vector< CurlRequest::Header> &responseHeaders,
86151ba086bSDamjan Jovanovic                                           const std::vector< ::rtl::OUString > &inHeaderNames,
86251ba086bSDamjan Jovanovic                                           DAVResource &ioResource )
86351ba086bSDamjan Jovanovic {
86451ba086bSDamjan Jovanovic     std::vector< CurlRequest::Header >::const_iterator it( responseHeaders.begin() );
86551ba086bSDamjan Jovanovic     const std::vector< CurlRequest::Header >::const_iterator end( responseHeaders.end() );
86651ba086bSDamjan Jovanovic     while ( it != end )
86751ba086bSDamjan Jovanovic     {
86851ba086bSDamjan Jovanovic         bool storeHeader = false;
86951ba086bSDamjan Jovanovic         if ( inHeaderNames.size() == 0 )
87051ba086bSDamjan Jovanovic             storeHeader = true;
87151ba086bSDamjan Jovanovic         else
87251ba086bSDamjan Jovanovic         {
87351ba086bSDamjan Jovanovic             std::vector< ::rtl::OUString >::const_iterator reqIt( inHeaderNames.begin() );
87451ba086bSDamjan Jovanovic             const std::vector< ::rtl::OUString >::const_iterator reqEnd( inHeaderNames.end() );
87551ba086bSDamjan Jovanovic             while ( reqIt != reqEnd )
87651ba086bSDamjan Jovanovic             {
87751ba086bSDamjan Jovanovic                 // header names are case insensitive
87851ba086bSDamjan Jovanovic                 if ( (*reqIt).equalsIgnoreAsciiCase( rtl::OStringToOUString( (*it).name, RTL_TEXTENCODING_UTF8 ) ) )
87951ba086bSDamjan Jovanovic                 {
88051ba086bSDamjan Jovanovic                     storeHeader = true;
88151ba086bSDamjan Jovanovic                     break;
88251ba086bSDamjan Jovanovic                 }
88351ba086bSDamjan Jovanovic                 else
88451ba086bSDamjan Jovanovic                 {
88551ba086bSDamjan Jovanovic                     ++reqIt;
88651ba086bSDamjan Jovanovic                 }
88751ba086bSDamjan Jovanovic             }
88851ba086bSDamjan Jovanovic         }
88951ba086bSDamjan Jovanovic 
89051ba086bSDamjan Jovanovic         if ( storeHeader )
89151ba086bSDamjan Jovanovic         {
89251ba086bSDamjan Jovanovic             DAVPropertyValue thePropertyValue;
89351ba086bSDamjan Jovanovic             thePropertyValue.IsCaseSensitive = false;
89451ba086bSDamjan Jovanovic             thePropertyValue.Name = rtl::OStringToOUString( (*it).name, RTL_TEXTENCODING_UTF8 );
89551ba086bSDamjan Jovanovic             thePropertyValue.Value <<= rtl::OStringToOUString( (*it).value, RTL_TEXTENCODING_UTF8 );
89651ba086bSDamjan Jovanovic             ioResource.properties.push_back( thePropertyValue );
89751ba086bSDamjan Jovanovic         }
89851ba086bSDamjan Jovanovic 
89951ba086bSDamjan Jovanovic         it++;
90051ba086bSDamjan Jovanovic     }
90151ba086bSDamjan Jovanovic }
90251ba086bSDamjan Jovanovic 
90351ba086bSDamjan Jovanovic // -------------------------------------------------------------------
90451ba086bSDamjan Jovanovic // PROPFIND - allprop & named
90551ba086bSDamjan Jovanovic // -------------------------------------------------------------------
90651ba086bSDamjan Jovanovic 
propfind(CurlRequest & curlRequest,const rtl::OUString & inPath,const Depth inDepth,const std::vector<::rtl::OUString> * inPropNames,const bool onlyPropertyNames,const DAVRequestEnvironment & rEnv)90751ba086bSDamjan Jovanovic void CurlSession::propfind( CurlRequest &curlRequest,
90851ba086bSDamjan Jovanovic                             const rtl::OUString &inPath,
90951ba086bSDamjan Jovanovic                             const Depth inDepth,
91051ba086bSDamjan Jovanovic                             const std::vector< ::rtl::OUString > * inPropNames,
91151ba086bSDamjan Jovanovic                             const bool onlyPropertyNames,
91251ba086bSDamjan Jovanovic                             const DAVRequestEnvironment & rEnv )
91351ba086bSDamjan Jovanovic {
91451ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
91551ba086bSDamjan Jovanovic 
91651ba086bSDamjan Jovanovic     if ( inDepth == DAVZERO )
91751ba086bSDamjan Jovanovic         curlRequest.addHeader( "Depth", "0" );
91851ba086bSDamjan Jovanovic     else if ( inDepth == DAVONE )
91951ba086bSDamjan Jovanovic         curlRequest.addHeader( "Depth", "1" );
92051ba086bSDamjan Jovanovic     else if ( inDepth == DAVINFINITY )
92151ba086bSDamjan Jovanovic         curlRequest.addHeader( "Depth", "infinity" );
92251ba086bSDamjan Jovanovic 
92351ba086bSDamjan Jovanovic     rtl::OString xml = PropfindRequest::generatePROPFINDRequestBody( inPropNames, onlyPropertyNames );
92451ba086bSDamjan Jovanovic     if ( xml.getLength() > 0 )
92551ba086bSDamjan Jovanovic     {
92651ba086bSDamjan Jovanovic         curlRequest.addHeader( "Content-Type", "application/xml" );
92751ba086bSDamjan Jovanovic         curlRequest.setRequestBody( xml.getStr(), xml.getLength() );
92851ba086bSDamjan Jovanovic     }
92951ba086bSDamjan Jovanovic 
93051ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
93151ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
93251ba086bSDamjan Jovanovic 
93351ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.propfind( m_aUri, inPath );
93451ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
93551ba086bSDamjan Jovanovic }
93651ba086bSDamjan Jovanovic 
PROPFIND(const rtl::OUString & inPath,const Depth inDepth,const std::vector<rtl::OUString> & inPropNames,std::vector<DAVResource> & ioResources,const DAVRequestEnvironment & rEnv)93751ba086bSDamjan Jovanovic void CurlSession::PROPFIND( const rtl::OUString & inPath,
93851ba086bSDamjan Jovanovic                             const Depth inDepth,
93951ba086bSDamjan Jovanovic                             const std::vector< rtl::OUString > & inPropNames,
94051ba086bSDamjan Jovanovic                             std::vector< DAVResource > & ioResources,
94151ba086bSDamjan Jovanovic                             const DAVRequestEnvironment & rEnv )
94251ba086bSDamjan Jovanovic     throw ( DAVException )
94351ba086bSDamjan Jovanovic {
94451ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "PROPFIND line $1$", (sal_Int32)__LINE__ );
94551ba086bSDamjan Jovanovic 
94651ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
94751ba086bSDamjan Jovanovic 
94851ba086bSDamjan Jovanovic     Init( rEnv );
94951ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
95051ba086bSDamjan Jovanovic 
95151ba086bSDamjan Jovanovic     propfind( curlRequest, inPath, inDepth, &inPropNames, false, rEnv );
95251ba086bSDamjan Jovanovic 
95351ba086bSDamjan Jovanovic     const std::vector< DAVResource > rResources( parseWebDAVPropFindResponse( curlRequest.getResponseBody().get() ) );
95451ba086bSDamjan Jovanovic     std::vector< DAVResource > *pIoResources = &ioResources;
95551ba086bSDamjan Jovanovic     *pIoResources = rResources;
95651ba086bSDamjan Jovanovic }
95751ba086bSDamjan Jovanovic 
95851ba086bSDamjan Jovanovic // -------------------------------------------------------------------
95951ba086bSDamjan Jovanovic // PROPFIND - propnames
96051ba086bSDamjan Jovanovic // -------------------------------------------------------------------
PROPFIND(const rtl::OUString & inPath,const Depth inDepth,std::vector<DAVResourceInfo> & ioResInfo,const DAVRequestEnvironment & rEnv)96151ba086bSDamjan Jovanovic void CurlSession::PROPFIND( const rtl::OUString & inPath,
96251ba086bSDamjan Jovanovic                             const Depth inDepth,
96351ba086bSDamjan Jovanovic                             std::vector< DAVResourceInfo > & ioResInfo,
96451ba086bSDamjan Jovanovic                             const DAVRequestEnvironment & rEnv )
96551ba086bSDamjan Jovanovic     throw( DAVException )
96651ba086bSDamjan Jovanovic {
96751ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "PROPFIND line $1$", (sal_Int32)__LINE__ );
96851ba086bSDamjan Jovanovic 
96951ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
97051ba086bSDamjan Jovanovic 
97151ba086bSDamjan Jovanovic     Init( rEnv );
97251ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
97351ba086bSDamjan Jovanovic 
97451ba086bSDamjan Jovanovic     propfind( curlRequest, inPath, inDepth, NULL, true, rEnv );
97551ba086bSDamjan Jovanovic 
97651ba086bSDamjan Jovanovic     const std::vector< DAVResourceInfo > rResInfo( parseWebDAVPropNameResponse( curlRequest.getResponseBody().get() ) );
97751ba086bSDamjan Jovanovic     std::vector< DAVResourceInfo > *pIoResInfo = &ioResInfo;
97851ba086bSDamjan Jovanovic     *pIoResInfo = rResInfo;
97951ba086bSDamjan Jovanovic }
98051ba086bSDamjan Jovanovic 
98151ba086bSDamjan Jovanovic // -------------------------------------------------------------------
98251ba086bSDamjan Jovanovic // PROPPATCH
98351ba086bSDamjan Jovanovic // -------------------------------------------------------------------
PROPPATCH(const rtl::OUString & inPath,const std::vector<ProppatchValue> & inValues,const DAVRequestEnvironment & rEnv)98451ba086bSDamjan Jovanovic void CurlSession::PROPPATCH( const rtl::OUString & inPath,
98551ba086bSDamjan Jovanovic                              const std::vector< ProppatchValue > & inValues,
98651ba086bSDamjan Jovanovic                              const DAVRequestEnvironment & rEnv )
98751ba086bSDamjan Jovanovic     throw( DAVException )
98851ba086bSDamjan Jovanovic {
98951ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "PROPPATCH line $1$", (sal_Int32)__LINE__ );
99051ba086bSDamjan Jovanovic 
99151ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
99251ba086bSDamjan Jovanovic 
99351ba086bSDamjan Jovanovic     Init( rEnv );
99451ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
99551ba086bSDamjan Jovanovic 
99651ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
99751ba086bSDamjan Jovanovic 
99851ba086bSDamjan Jovanovic     // check whether a lock on this resource is already owned
99951ba086bSDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
100051ba086bSDamjan Jovanovic     ucb::Lock inLock;
100151ba086bSDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
100251ba086bSDamjan Jovanovic     if ( pLock )
100351ba086bSDamjan Jovanovic     {
100451ba086bSDamjan Jovanovic         inLock = pLock->getLock();
100551ba086bSDamjan Jovanovic     }
100651ba086bSDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
100751ba086bSDamjan Jovanovic     {
100851ba086bSDamjan Jovanovic         curlRequest.addHeader( "If",
100951ba086bSDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
101051ba086bSDamjan Jovanovic     }
101151ba086bSDamjan Jovanovic 
101251ba086bSDamjan Jovanovic     rtl::OString xml = ProppatchRequest::generatePROPPATCHRequestBody( inValues );
101351ba086bSDamjan Jovanovic     if ( xml.getLength() > 0 )
101451ba086bSDamjan Jovanovic     {
101551ba086bSDamjan Jovanovic         curlRequest.addHeader( "Content-Type", "application/xml" );
101651ba086bSDamjan Jovanovic         curlRequest.setRequestBody( xml.getStr(), xml.getLength() );
101751ba086bSDamjan Jovanovic     }
101851ba086bSDamjan Jovanovic 
101951ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
102051ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
102151ba086bSDamjan Jovanovic 
102251ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.proppatch( m_aUri, inPath );
102351ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
102451ba086bSDamjan Jovanovic }
102551ba086bSDamjan Jovanovic 
102651ba086bSDamjan Jovanovic // -------------------------------------------------------------------
102751ba086bSDamjan Jovanovic // HEAD
102851ba086bSDamjan Jovanovic // -------------------------------------------------------------------
HEAD(const::rtl::OUString & inPath,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource,const DAVRequestEnvironment & rEnv)102951ba086bSDamjan Jovanovic void CurlSession::HEAD( const ::rtl::OUString & inPath,
103051ba086bSDamjan Jovanovic                         const std::vector< ::rtl::OUString > & inHeaderNames,
103151ba086bSDamjan Jovanovic                         DAVResource & ioResource,
103251ba086bSDamjan Jovanovic                         const DAVRequestEnvironment & rEnv )
103351ba086bSDamjan Jovanovic     throw( DAVException )
103451ba086bSDamjan Jovanovic {
103551ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "HEAD line $1$", (sal_Int32)__LINE__ );
103651ba086bSDamjan Jovanovic 
103751ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
103851ba086bSDamjan Jovanovic 
103951ba086bSDamjan Jovanovic     Init(rEnv );
104051ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
104151ba086bSDamjan Jovanovic 
104251ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
104351ba086bSDamjan Jovanovic 
104451ba086bSDamjan Jovanovic     ioResource.uri = inPath;
104551ba086bSDamjan Jovanovic     ioResource.properties.clear();
104651ba086bSDamjan Jovanovic 
104751ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
104851ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
104951ba086bSDamjan Jovanovic 
105051ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.head( m_aUri, inPath );
105151ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
105251ba086bSDamjan Jovanovic     responseHeadersToDAVResource( curlRequest.getResponseHeaders(), inHeaderNames, ioResource );
105351ba086bSDamjan Jovanovic }
105451ba086bSDamjan Jovanovic 
105551ba086bSDamjan Jovanovic // -------------------------------------------------------------------
105651ba086bSDamjan Jovanovic // GET
105751ba086bSDamjan Jovanovic // -------------------------------------------------------------------
105851ba086bSDamjan Jovanovic uno::Reference< io::XInputStream >
GET(const rtl::OUString & inPath,const DAVRequestEnvironment & rEnv)105951ba086bSDamjan Jovanovic CurlSession::GET( const rtl::OUString & inPath,
106051ba086bSDamjan Jovanovic                   const DAVRequestEnvironment & rEnv )
106151ba086bSDamjan Jovanovic     throw ( DAVException )
106251ba086bSDamjan Jovanovic {
106351ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ );
106451ba086bSDamjan Jovanovic 
106551ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
106651ba086bSDamjan Jovanovic 
106751ba086bSDamjan Jovanovic     Init( rEnv );
106851ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
106951ba086bSDamjan Jovanovic 
107051ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
107151ba086bSDamjan Jovanovic 
107251ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
107351ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
107451ba086bSDamjan Jovanovic 
107551ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.get( m_aUri, inPath );
107651ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
107751ba086bSDamjan Jovanovic 
107851ba086bSDamjan Jovanovic     return uno::Reference< io::XInputStream >( curlRequest.getResponseBody().get() );
107951ba086bSDamjan Jovanovic }
108051ba086bSDamjan Jovanovic 
108151ba086bSDamjan Jovanovic // -------------------------------------------------------------------
108251ba086bSDamjan Jovanovic // GET
108351ba086bSDamjan Jovanovic // -------------------------------------------------------------------
GET(const rtl::OUString & inPath,uno::Reference<io::XOutputStream> & ioOutputStream,const DAVRequestEnvironment & rEnv)108451ba086bSDamjan Jovanovic void CurlSession::GET( const rtl::OUString & inPath,
108551ba086bSDamjan Jovanovic                        uno::Reference< io::XOutputStream > & ioOutputStream,
108651ba086bSDamjan Jovanovic                        const DAVRequestEnvironment & rEnv )
108751ba086bSDamjan Jovanovic     throw ( DAVException )
108851ba086bSDamjan Jovanovic {
108951ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ );
109051ba086bSDamjan Jovanovic 
109151ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
109251ba086bSDamjan Jovanovic 
109351ba086bSDamjan Jovanovic     Init( rEnv );
109451ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
109551ba086bSDamjan Jovanovic 
109651ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
109751ba086bSDamjan Jovanovic 
109851ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
109951ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
110051ba086bSDamjan Jovanovic 
110151ba086bSDamjan Jovanovic     curlRequest.saveResponseBodyTo( ioOutputStream );
110251ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.get( m_aUri, inPath );
110351ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
110451ba086bSDamjan Jovanovic }
110551ba086bSDamjan Jovanovic 
110651ba086bSDamjan Jovanovic // -------------------------------------------------------------------
110751ba086bSDamjan Jovanovic // GET
110851ba086bSDamjan Jovanovic // -------------------------------------------------------------------
110951ba086bSDamjan Jovanovic uno::Reference< io::XInputStream >
GET(const rtl::OUString & inPath,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource,const DAVRequestEnvironment & rEnv)111051ba086bSDamjan Jovanovic CurlSession::GET( const rtl::OUString & inPath,
111151ba086bSDamjan Jovanovic                   const std::vector< ::rtl::OUString > & inHeaderNames,
111251ba086bSDamjan Jovanovic                   DAVResource & ioResource,
111351ba086bSDamjan Jovanovic                   const DAVRequestEnvironment & rEnv )
111451ba086bSDamjan Jovanovic     throw ( DAVException )
111551ba086bSDamjan Jovanovic {
111651ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ );
111751ba086bSDamjan Jovanovic 
111851ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
111951ba086bSDamjan Jovanovic 
112051ba086bSDamjan Jovanovic     Init( rEnv );
112151ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
112251ba086bSDamjan Jovanovic 
112351ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
112451ba086bSDamjan Jovanovic 
112551ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
112651ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
112751ba086bSDamjan Jovanovic 
112851ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.get( m_aUri, inPath );
112951ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
113051ba086bSDamjan Jovanovic     responseHeadersToDAVResource( curlRequest.getResponseHeaders(), inHeaderNames, ioResource );
113151ba086bSDamjan Jovanovic 
113251ba086bSDamjan Jovanovic     return uno::Reference< io::XInputStream >( curlRequest.getResponseBody().get() );
113351ba086bSDamjan Jovanovic }
113451ba086bSDamjan Jovanovic 
113551ba086bSDamjan Jovanovic 
113651ba086bSDamjan Jovanovic // -------------------------------------------------------------------
113751ba086bSDamjan Jovanovic // GET
113851ba086bSDamjan Jovanovic // -------------------------------------------------------------------
GET(const rtl::OUString & inPath,uno::Reference<io::XOutputStream> & ioOutputStream,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource,const DAVRequestEnvironment & rEnv)113951ba086bSDamjan Jovanovic void CurlSession::GET( const rtl::OUString & inPath,
114051ba086bSDamjan Jovanovic                        uno::Reference< io::XOutputStream > & ioOutputStream,
114151ba086bSDamjan Jovanovic                        const std::vector< ::rtl::OUString > & inHeaderNames,
114251ba086bSDamjan Jovanovic                        DAVResource & ioResource,
114351ba086bSDamjan Jovanovic                        const DAVRequestEnvironment & rEnv )
114451ba086bSDamjan Jovanovic     throw ( DAVException )
114551ba086bSDamjan Jovanovic {
114651ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ );
114751ba086bSDamjan Jovanovic 
114851ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
114951ba086bSDamjan Jovanovic 
115051ba086bSDamjan Jovanovic     Init( rEnv );
115151ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
115251ba086bSDamjan Jovanovic 
115351ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
115451ba086bSDamjan Jovanovic 
115551ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
115651ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
115751ba086bSDamjan Jovanovic 
115851ba086bSDamjan Jovanovic     curlRequest.saveResponseBodyTo( ioOutputStream );
115951ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.get( m_aUri, inPath );
116051ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
116151ba086bSDamjan Jovanovic     responseHeadersToDAVResource( curlRequest.getResponseHeaders(), inHeaderNames, ioResource );
116251ba086bSDamjan Jovanovic }
116351ba086bSDamjan Jovanovic 
116451ba086bSDamjan Jovanovic // -------------------------------------------------------------------
116551ba086bSDamjan Jovanovic // PUT
116651ba086bSDamjan Jovanovic // -------------------------------------------------------------------
PUT(const rtl::OUString & inPath,const uno::Reference<io::XInputStream> & inInputStream,const DAVRequestEnvironment & rEnv)116751ba086bSDamjan Jovanovic void CurlSession::PUT( const rtl::OUString & inPath,
116851ba086bSDamjan Jovanovic                        const uno::Reference< io::XInputStream > & inInputStream,
116951ba086bSDamjan Jovanovic                        const DAVRequestEnvironment & rEnv )
117051ba086bSDamjan Jovanovic     throw ( DAVException )
117151ba086bSDamjan Jovanovic {
117251ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "PUT line $1$", (sal_Int32)__LINE__ );
117351ba086bSDamjan Jovanovic 
117451ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
117551ba086bSDamjan Jovanovic 
117651ba086bSDamjan Jovanovic     Init( rEnv );
117751ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
117851ba086bSDamjan Jovanovic 
117951ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
118051ba086bSDamjan Jovanovic 
118151ba086bSDamjan Jovanovic     uno::Sequence< sal_Int8 > aDataToSend;
118251ba086bSDamjan Jovanovic     if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
118351ba086bSDamjan Jovanovic         throw DAVException( DAVException::DAV_INVALID_ARG );
118451ba086bSDamjan Jovanovic     curlRequest.setRequestBody( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
118551ba086bSDamjan Jovanovic                                 aDataToSend.getLength() );
118651ba086bSDamjan Jovanovic 
118751ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
118851ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
118951ba086bSDamjan Jovanovic 
119051ba086bSDamjan Jovanovic     // check whether a lock on this resource is already owned
119151ba086bSDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
119251ba086bSDamjan Jovanovic     ucb::Lock inLock;
119351ba086bSDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
119451ba086bSDamjan Jovanovic     if ( pLock )
119551ba086bSDamjan Jovanovic     {
119651ba086bSDamjan Jovanovic         inLock = pLock->getLock();
119751ba086bSDamjan Jovanovic     }
119851ba086bSDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
119951ba086bSDamjan Jovanovic     {
120051ba086bSDamjan Jovanovic         curlRequest.addHeader( "If",
120151ba086bSDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
120251ba086bSDamjan Jovanovic     }
120351ba086bSDamjan Jovanovic 
120451ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.put( m_aUri, inPath );
120551ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
120651ba086bSDamjan Jovanovic }
120751ba086bSDamjan Jovanovic 
120851ba086bSDamjan Jovanovic // -------------------------------------------------------------------
120951ba086bSDamjan Jovanovic // POST
121051ba086bSDamjan Jovanovic // -------------------------------------------------------------------
121151ba086bSDamjan Jovanovic uno::Reference< io::XInputStream >
POST(const rtl::OUString & inPath,const rtl::OUString & rContentType,const rtl::OUString & rReferer,const uno::Reference<io::XInputStream> & inInputStream,const DAVRequestEnvironment & rEnv)121251ba086bSDamjan Jovanovic CurlSession::POST( const rtl::OUString & inPath,
121351ba086bSDamjan Jovanovic                    const rtl::OUString & rContentType,
121451ba086bSDamjan Jovanovic                    const rtl::OUString & rReferer,
121551ba086bSDamjan Jovanovic                    const uno::Reference< io::XInputStream > & inInputStream,
121651ba086bSDamjan Jovanovic                    const DAVRequestEnvironment & rEnv )
121751ba086bSDamjan Jovanovic     throw ( DAVException )
121851ba086bSDamjan Jovanovic {
121951ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "POST line $1$", (sal_Int32)__LINE__ );
122051ba086bSDamjan Jovanovic 
122151ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
122251ba086bSDamjan Jovanovic 
122351ba086bSDamjan Jovanovic     Init( rEnv );
122451ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
122551ba086bSDamjan Jovanovic 
122651ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
122751ba086bSDamjan Jovanovic 
122851ba086bSDamjan Jovanovic     uno::Sequence< sal_Int8 > aDataToSend;
122951ba086bSDamjan Jovanovic     if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
123051ba086bSDamjan Jovanovic         throw DAVException( DAVException::DAV_INVALID_ARG );
123151ba086bSDamjan Jovanovic     curlRequest.setRequestBody( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
123251ba086bSDamjan Jovanovic                                 aDataToSend.getLength() );
123351ba086bSDamjan Jovanovic 
123451ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
123551ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
123651ba086bSDamjan Jovanovic 
123751ba086bSDamjan Jovanovic     if ( !rContentType.isEmpty() )
123851ba086bSDamjan Jovanovic         curlRequest.addHeader( "Content-Type", rtl::OUStringToOString( rContentType, RTL_TEXTENCODING_UTF8 ).getStr() );
123951ba086bSDamjan Jovanovic     if ( !rReferer.isEmpty() )
124051ba086bSDamjan Jovanovic         curlRequest.addHeader( "Referer", rtl::OUStringToOString( rReferer, RTL_TEXTENCODING_UTF8 ).getStr() );
124151ba086bSDamjan Jovanovic 
124251ba086bSDamjan Jovanovic     // check whether a lock on this resource is already owned
124351ba086bSDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
124451ba086bSDamjan Jovanovic     ucb::Lock inLock;
124551ba086bSDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
124651ba086bSDamjan Jovanovic     if ( pLock )
124751ba086bSDamjan Jovanovic     {
124851ba086bSDamjan Jovanovic         inLock = pLock->getLock();
124951ba086bSDamjan Jovanovic     }
125051ba086bSDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
125151ba086bSDamjan Jovanovic     {
125251ba086bSDamjan Jovanovic         curlRequest.addHeader( "If",
125351ba086bSDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
125451ba086bSDamjan Jovanovic     }
125551ba086bSDamjan Jovanovic 
125651ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.post( m_aUri, inPath );
125751ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
125851ba086bSDamjan Jovanovic     return uno::Reference< io::XInputStream >( curlRequest.getResponseBody().get() );
125951ba086bSDamjan Jovanovic }
126051ba086bSDamjan Jovanovic 
126151ba086bSDamjan Jovanovic // -------------------------------------------------------------------
126251ba086bSDamjan Jovanovic // POST
126351ba086bSDamjan Jovanovic // -------------------------------------------------------------------
POST(const rtl::OUString & inPath,const rtl::OUString & rContentType,const rtl::OUString & rReferer,const uno::Reference<io::XInputStream> & inInputStream,uno::Reference<io::XOutputStream> & oOutputStream,const DAVRequestEnvironment & rEnv)126451ba086bSDamjan Jovanovic void CurlSession::POST( const rtl::OUString & inPath,
126551ba086bSDamjan Jovanovic                         const rtl::OUString & rContentType,
126651ba086bSDamjan Jovanovic                         const rtl::OUString & rReferer,
126751ba086bSDamjan Jovanovic                         const uno::Reference< io::XInputStream > & inInputStream,
126851ba086bSDamjan Jovanovic                         uno::Reference< io::XOutputStream > & oOutputStream,
126951ba086bSDamjan Jovanovic                         const DAVRequestEnvironment & rEnv )
127051ba086bSDamjan Jovanovic     throw ( DAVException )
127151ba086bSDamjan Jovanovic {
127251ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "POST line $1$", (sal_Int32)__LINE__ );
127351ba086bSDamjan Jovanovic 
127451ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
127551ba086bSDamjan Jovanovic 
127651ba086bSDamjan Jovanovic     Init( rEnv );
127751ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
127851ba086bSDamjan Jovanovic 
127951ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
128051ba086bSDamjan Jovanovic 
128151ba086bSDamjan Jovanovic     uno::Sequence< sal_Int8 > aDataToSend;
128251ba086bSDamjan Jovanovic     if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
128351ba086bSDamjan Jovanovic         throw DAVException( DAVException::DAV_INVALID_ARG );
128451ba086bSDamjan Jovanovic     curlRequest.setRequestBody( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
128551ba086bSDamjan Jovanovic                                 aDataToSend.getLength() );
128651ba086bSDamjan Jovanovic 
128751ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
128851ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
128951ba086bSDamjan Jovanovic 
129051ba086bSDamjan Jovanovic     if ( !rContentType.isEmpty() )
129151ba086bSDamjan Jovanovic         curlRequest.addHeader( "Content-Type", rtl::OUStringToOString( rContentType, RTL_TEXTENCODING_UTF8 ).getStr() );
129251ba086bSDamjan Jovanovic     if ( !rReferer.isEmpty() )
129351ba086bSDamjan Jovanovic         curlRequest.addHeader( "Referer", rtl::OUStringToOString( rReferer, RTL_TEXTENCODING_UTF8 ).getStr() );
129451ba086bSDamjan Jovanovic 
129551ba086bSDamjan Jovanovic     // check whether a lock on this resource is already owned
129651ba086bSDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
129751ba086bSDamjan Jovanovic     ucb::Lock inLock;
129851ba086bSDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
129951ba086bSDamjan Jovanovic     if ( pLock )
130051ba086bSDamjan Jovanovic     {
130151ba086bSDamjan Jovanovic         inLock = pLock->getLock();
130251ba086bSDamjan Jovanovic     }
130351ba086bSDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
130451ba086bSDamjan Jovanovic     {
130551ba086bSDamjan Jovanovic         curlRequest.addHeader( "If",
130651ba086bSDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
130751ba086bSDamjan Jovanovic     }
130851ba086bSDamjan Jovanovic 
130951ba086bSDamjan Jovanovic     curlRequest.saveResponseBodyTo( oOutputStream );
131051ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.post( m_aUri, inPath );
131151ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
131251ba086bSDamjan Jovanovic }
131351ba086bSDamjan Jovanovic 
131451ba086bSDamjan Jovanovic // -------------------------------------------------------------------
131551ba086bSDamjan Jovanovic // MKCOL
131651ba086bSDamjan Jovanovic // -------------------------------------------------------------------
MKCOL(const rtl::OUString & inPath,const DAVRequestEnvironment & rEnv)131751ba086bSDamjan Jovanovic void CurlSession::MKCOL( const rtl::OUString & inPath,
131851ba086bSDamjan Jovanovic                          const DAVRequestEnvironment & rEnv )
131951ba086bSDamjan Jovanovic     throw ( DAVException )
132051ba086bSDamjan Jovanovic {
132151ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "MKCOL line $1$", (sal_Int32)__LINE__ );
132251ba086bSDamjan Jovanovic 
132351ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
132451ba086bSDamjan Jovanovic 
132551ba086bSDamjan Jovanovic     Init( rEnv );
132651ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
132751ba086bSDamjan Jovanovic 
132851ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
132951ba086bSDamjan Jovanovic 
133051ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
133151ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
133251ba086bSDamjan Jovanovic 
133351ba086bSDamjan Jovanovic     // check whether a lock on this resource is already owned
133451ba086bSDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
133551ba086bSDamjan Jovanovic     ucb::Lock inLock;
133651ba086bSDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
133751ba086bSDamjan Jovanovic     if ( pLock )
133851ba086bSDamjan Jovanovic     {
133951ba086bSDamjan Jovanovic         inLock = pLock->getLock();
134051ba086bSDamjan Jovanovic     }
134151ba086bSDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
134251ba086bSDamjan Jovanovic     {
134351ba086bSDamjan Jovanovic         curlRequest.addHeader( "If",
134451ba086bSDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
134551ba086bSDamjan Jovanovic     }
134651ba086bSDamjan Jovanovic 
134751ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.mkcol( m_aUri, inPath );
134851ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
134951ba086bSDamjan Jovanovic }
135051ba086bSDamjan Jovanovic 
135151ba086bSDamjan Jovanovic // -------------------------------------------------------------------
135251ba086bSDamjan Jovanovic // COPY
135351ba086bSDamjan Jovanovic // -------------------------------------------------------------------
COPY(const rtl::OUString & inSourceURL,const rtl::OUString & inDestinationURL,const DAVRequestEnvironment & rEnv,sal_Bool inOverWrite)135451ba086bSDamjan Jovanovic void CurlSession::COPY( const rtl::OUString & inSourceURL,
135551ba086bSDamjan Jovanovic                         const rtl::OUString & inDestinationURL,
135651ba086bSDamjan Jovanovic                         const DAVRequestEnvironment & rEnv,
135751ba086bSDamjan Jovanovic                         sal_Bool inOverWrite )
135851ba086bSDamjan Jovanovic     throw ( DAVException )
135951ba086bSDamjan Jovanovic {
136051ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "COPY line $1$", (sal_Int32)__LINE__ );
136151ba086bSDamjan Jovanovic 
136251ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
136351ba086bSDamjan Jovanovic 
136451ba086bSDamjan Jovanovic     Init( rEnv );
136551ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
136651ba086bSDamjan Jovanovic 
136751ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
136851ba086bSDamjan Jovanovic 
136951ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
137051ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
137151ba086bSDamjan Jovanovic 
137251ba086bSDamjan Jovanovic     curlRequest.addHeader( "Destination", rtl::OUStringToOString( inDestinationURL, RTL_TEXTENCODING_UTF8 ).getStr() );
137351ba086bSDamjan Jovanovic     curlRequest.addHeader( "Overwrite", inOverWrite? "T" : "F" );
137451ba086bSDamjan Jovanovic 
137551ba086bSDamjan Jovanovic     // check whether a lock on the destination resource is already owned
137651ba086bSDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inDestinationURL ) );
137751ba086bSDamjan Jovanovic     ucb::Lock inLock;
137851ba086bSDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
137951ba086bSDamjan Jovanovic     if ( pLock )
138051ba086bSDamjan Jovanovic     {
138151ba086bSDamjan Jovanovic         inLock = pLock->getLock();
138251ba086bSDamjan Jovanovic     }
138351ba086bSDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
138451ba086bSDamjan Jovanovic     {
138551ba086bSDamjan Jovanovic         curlRequest.addHeader( "If",
138651ba086bSDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
138751ba086bSDamjan Jovanovic     }
138851ba086bSDamjan Jovanovic 
138951ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.copy( m_aUri, CurlUri( inSourceURL ).GetPath() );
139051ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
139151ba086bSDamjan Jovanovic }
139251ba086bSDamjan Jovanovic 
139351ba086bSDamjan Jovanovic // -------------------------------------------------------------------
139451ba086bSDamjan Jovanovic // MOVE
139551ba086bSDamjan Jovanovic // -------------------------------------------------------------------
MOVE(const rtl::OUString & inSourceURL,const rtl::OUString & inDestinationURL,const DAVRequestEnvironment & rEnv,sal_Bool inOverWrite)139651ba086bSDamjan Jovanovic void CurlSession::MOVE( const rtl::OUString & inSourceURL,
139751ba086bSDamjan Jovanovic                         const rtl::OUString & inDestinationURL,
139851ba086bSDamjan Jovanovic                         const DAVRequestEnvironment & rEnv,
139951ba086bSDamjan Jovanovic                         sal_Bool inOverWrite )
140051ba086bSDamjan Jovanovic     throw ( DAVException )
140151ba086bSDamjan Jovanovic {
140251ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "MOVE line $1$", (sal_Int32)__LINE__ );
140351ba086bSDamjan Jovanovic 
140451ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
140551ba086bSDamjan Jovanovic 
140651ba086bSDamjan Jovanovic     Init( rEnv );
140751ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
140851ba086bSDamjan Jovanovic 
140951ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
141051ba086bSDamjan Jovanovic 
141151ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
141251ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
141351ba086bSDamjan Jovanovic 
141451ba086bSDamjan Jovanovic     curlRequest.addHeader( "Destination", rtl::OUStringToOString( inDestinationURL, RTL_TEXTENCODING_UTF8 ).getStr() );
141551ba086bSDamjan Jovanovic     curlRequest.addHeader( "Overwrite", inOverWrite? "T" : "F" );
141651ba086bSDamjan Jovanovic 
141751ba086bSDamjan Jovanovic     // check whether a lock on the destination resource is already owned
141851ba086bSDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inDestinationURL ) );
141951ba086bSDamjan Jovanovic     ucb::Lock inLock;
142051ba086bSDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
142151ba086bSDamjan Jovanovic     if ( pLock )
142251ba086bSDamjan Jovanovic     {
142351ba086bSDamjan Jovanovic         inLock = pLock->getLock();
142451ba086bSDamjan Jovanovic     }
142551ba086bSDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
142651ba086bSDamjan Jovanovic     {
142751ba086bSDamjan Jovanovic         curlRequest.addHeader( "If",
142851ba086bSDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
142951ba086bSDamjan Jovanovic     }
143051ba086bSDamjan Jovanovic 
143151ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.copy( m_aUri, CurlUri( inSourceURL ).GetPath() );
143251ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
143351ba086bSDamjan Jovanovic }
143451ba086bSDamjan Jovanovic 
143551ba086bSDamjan Jovanovic // -------------------------------------------------------------------
143651ba086bSDamjan Jovanovic // DESTROY
143751ba086bSDamjan Jovanovic // -------------------------------------------------------------------
DESTROY(const rtl::OUString & inPath,const DAVRequestEnvironment & rEnv)143851ba086bSDamjan Jovanovic void CurlSession::DESTROY( const rtl::OUString & inPath,
143951ba086bSDamjan Jovanovic                            const DAVRequestEnvironment & rEnv )
144051ba086bSDamjan Jovanovic     throw ( DAVException )
144151ba086bSDamjan Jovanovic {
144251ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "DESTROY line $1$", (sal_Int32)__LINE__ );
144351ba086bSDamjan Jovanovic 
144451ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
144551ba086bSDamjan Jovanovic 
144651ba086bSDamjan Jovanovic     Init( rEnv );
144751ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
144851ba086bSDamjan Jovanovic 
144951ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
145051ba086bSDamjan Jovanovic 
145151ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
145251ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
145351ba086bSDamjan Jovanovic 
145451ba086bSDamjan Jovanovic     // check whether a lock on this resource is already owned
145551ba086bSDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
145651ba086bSDamjan Jovanovic     ucb::Lock inLock;
145751ba086bSDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
145851ba086bSDamjan Jovanovic     if ( pLock )
145951ba086bSDamjan Jovanovic     {
146051ba086bSDamjan Jovanovic         inLock = pLock->getLock();
146151ba086bSDamjan Jovanovic     }
146251ba086bSDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
146351ba086bSDamjan Jovanovic     {
146451ba086bSDamjan Jovanovic         curlRequest.addHeader( "If",
146551ba086bSDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
146651ba086bSDamjan Jovanovic     }
146751ba086bSDamjan Jovanovic 
146851ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.delete_( m_aUri, inPath );
146951ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
147051ba086bSDamjan Jovanovic }
147151ba086bSDamjan Jovanovic 
147251ba086bSDamjan Jovanovic // -------------------------------------------------------------------
147351ba086bSDamjan Jovanovic 
147451ba086bSDamjan Jovanovic namespace
147551ba086bSDamjan Jovanovic {
lastChanceToSendRefreshRequest(TimeValue const & rStart,sal_Int32 timeout)147651ba086bSDamjan Jovanovic     sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart,
147751ba086bSDamjan Jovanovic                                               sal_Int32 timeout )
147851ba086bSDamjan Jovanovic     {
147951ba086bSDamjan Jovanovic         TimeValue aEnd;
148051ba086bSDamjan Jovanovic         osl_getSystemTime( &aEnd );
148151ba086bSDamjan Jovanovic 
148251ba086bSDamjan Jovanovic         // Try to estimate a safe absolute time for sending the
148351ba086bSDamjan Jovanovic         // lock refresh request.
148451ba086bSDamjan Jovanovic         sal_Int32 lastChanceToSendRefreshRequest = DAVINFINITY;
148551ba086bSDamjan Jovanovic         if ( timeout != DAVINFINITY )
148651ba086bSDamjan Jovanovic         {
148751ba086bSDamjan Jovanovic             sal_Int32 calltime = aEnd.Seconds - rStart.Seconds;
148851ba086bSDamjan Jovanovic             if ( calltime <= timeout )
148951ba086bSDamjan Jovanovic             {
149051ba086bSDamjan Jovanovic                 lastChanceToSendRefreshRequest
149151ba086bSDamjan Jovanovic                     = aEnd.Seconds + timeout - calltime;
149251ba086bSDamjan Jovanovic             }
149351ba086bSDamjan Jovanovic             else
149451ba086bSDamjan Jovanovic             {
149551ba086bSDamjan Jovanovic                 OSL_TRACE( "No chance to refresh lock before timeout!" );
149651ba086bSDamjan Jovanovic             }
149751ba086bSDamjan Jovanovic         }
149851ba086bSDamjan Jovanovic         return lastChanceToSendRefreshRequest;
149951ba086bSDamjan Jovanovic     }
150051ba086bSDamjan Jovanovic 
150151ba086bSDamjan Jovanovic } // namespace
150251ba086bSDamjan Jovanovic 
150351ba086bSDamjan Jovanovic // -------------------------------------------------------------------
150451ba086bSDamjan Jovanovic // LOCK (set new lock)
150551ba086bSDamjan Jovanovic // -------------------------------------------------------------------
LOCK(const::rtl::OUString & inPath,ucb::Lock & inLock,const DAVRequestEnvironment & rEnv)150651ba086bSDamjan Jovanovic void CurlSession::LOCK( const ::rtl::OUString & inPath,
150751ba086bSDamjan Jovanovic                         ucb::Lock & inLock,
150851ba086bSDamjan Jovanovic                         const DAVRequestEnvironment & rEnv )
150951ba086bSDamjan Jovanovic     throw ( DAVException )
151051ba086bSDamjan Jovanovic {
151151ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "LOCK line $1$", (sal_Int32)__LINE__ );
151251ba086bSDamjan Jovanovic 
151351ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
151451ba086bSDamjan Jovanovic 
151551ba086bSDamjan Jovanovic     // before locking, search in the lock store if we already own a lock for this resource
151651ba086bSDamjan Jovanovic     // if present, return with exception DAV_LOCKED_SELF
151751ba086bSDamjan Jovanovic     rtl::OUString   aUri( composeCurrentUri( inPath ) );
151851ba086bSDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
151951ba086bSDamjan Jovanovic     if ( pLock )
152051ba086bSDamjan Jovanovic     {
152151ba086bSDamjan Jovanovic // already present, meaning already locked by the same AOO session and already in the lockstore
152251ba086bSDamjan Jovanovic // just return, nothing to do
152351ba086bSDamjan Jovanovic         return;
152451ba086bSDamjan Jovanovic     }
152551ba086bSDamjan Jovanovic 
152651ba086bSDamjan Jovanovic     Init( rEnv );
152751ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
152851ba086bSDamjan Jovanovic 
152951ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
153051ba086bSDamjan Jovanovic 
153151ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
153251ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
153351ba086bSDamjan Jovanovic 
153451ba086bSDamjan Jovanovic     if ( inLock.Timeout == -1 )
153551ba086bSDamjan Jovanovic         curlRequest.addHeader( "Timeout", "Infinite" );
153651ba086bSDamjan Jovanovic     else
153751ba086bSDamjan Jovanovic         curlRequest.addHeader( "Timeout", "Second-" + rtl::OString::valueOf( inLock.Timeout ) );
153851ba086bSDamjan Jovanovic 
153951ba086bSDamjan Jovanovic     switch ( inLock.Depth )
154051ba086bSDamjan Jovanovic     {
154151ba086bSDamjan Jovanovic         //i126305 TODO investigate on this case...
154251ba086bSDamjan Jovanovic     case ucb::LockDepth_MAKE_FIXED_SIZE:
154351ba086bSDamjan Jovanovic 
154451ba086bSDamjan Jovanovic     case ucb::LockDepth_ZERO:
154551ba086bSDamjan Jovanovic         curlRequest.addHeader( "Depth", "0" );
154651ba086bSDamjan Jovanovic         break;
154751ba086bSDamjan Jovanovic     case ucb::LockDepth_ONE:
154851ba086bSDamjan Jovanovic         curlRequest.addHeader( "Depth", "1" );
154951ba086bSDamjan Jovanovic         break;
155051ba086bSDamjan Jovanovic     case ucb::LockDepth_INFINITY:
155151ba086bSDamjan Jovanovic         curlRequest.addHeader( "Depth", "infinity" );
155251ba086bSDamjan Jovanovic         break;
155351ba086bSDamjan Jovanovic     }
155451ba086bSDamjan Jovanovic 
155551ba086bSDamjan Jovanovic     rtl::OString xml = LockRequest::generateRequestBody( inLock );
155651ba086bSDamjan Jovanovic     curlRequest.addHeader( "Content-Type", "application/xml" );
155751ba086bSDamjan Jovanovic     curlRequest.setRequestBody( xml.getStr(), xml.getLength() );
155851ba086bSDamjan Jovanovic 
155951ba086bSDamjan Jovanovic     TimeValue startCall;
156051ba086bSDamjan Jovanovic     osl_getSystemTime( &startCall );
156151ba086bSDamjan Jovanovic 
156251ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.lock( m_aUri, inPath );
156351ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
156451ba086bSDamjan Jovanovic 
156551ba086bSDamjan Jovanovic     // the returned property, a sequence of locks
156651ba086bSDamjan Jovanovic     // only the first is used
156751ba086bSDamjan Jovanovic     const DAVPropertyValue outLock( parseWebDAVLockResponse( curlRequest.getResponseBody().get() ) );
156851ba086bSDamjan Jovanovic     if(outLock.Name.compareToAscii(RTL_CONSTASCII_STRINGPARAM( "DAV:lockdiscovery" )) == 0 )
156951ba086bSDamjan Jovanovic     {
157051ba086bSDamjan Jovanovic         // got a lock, use only the first returned
157151ba086bSDamjan Jovanovic         uno::Sequence< ucb::Lock >      aLocks;
157251ba086bSDamjan Jovanovic         outLock.Value >>= aLocks;
157351ba086bSDamjan Jovanovic         ucb::Lock aLock = aLocks[0];
157451ba086bSDamjan Jovanovic 
157551ba086bSDamjan Jovanovic         CurlLock* aNewLock = new CurlLock( aLock, aUri, inPath );
157651ba086bSDamjan Jovanovic         // add the store the new lock
157751ba086bSDamjan Jovanovic         m_aCurlLockStore.addLock(aNewLock,this,
157851ba086bSDamjan Jovanovic                                  lastChanceToSendRefreshRequest(
157951ba086bSDamjan Jovanovic                                      startCall, static_cast< sal_Int32 >(aLock.Timeout) ) );
158051ba086bSDamjan Jovanovic     }
158151ba086bSDamjan Jovanovic }
158251ba086bSDamjan Jovanovic 
158351ba086bSDamjan Jovanovic // -------------------------------------------------------------------
158451ba086bSDamjan Jovanovic // LOCK (refresh existing lock from DAVResourceAccess)
158551ba086bSDamjan Jovanovic // -------------------------------------------------------------------
LOCK(const::rtl::OUString &,sal_Int64 nTimeout,const DAVRequestEnvironment &)158651ba086bSDamjan Jovanovic sal_Int64 CurlSession::LOCK( const ::rtl::OUString & /*inPath*/,
158751ba086bSDamjan Jovanovic                              sal_Int64 nTimeout,
158851ba086bSDamjan Jovanovic                              const DAVRequestEnvironment & /*rEnv*/ )
158951ba086bSDamjan Jovanovic     throw ( DAVException )
159051ba086bSDamjan Jovanovic {
159151ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "LOCK line $1$", (sal_Int32)__LINE__ );
159251ba086bSDamjan Jovanovic 
159351ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
159451ba086bSDamjan Jovanovic 
159551ba086bSDamjan Jovanovic     return nTimeout;
159651ba086bSDamjan Jovanovic     /*
159751ba086bSDamjan Jovanovic     // Try to get the neon lock from lock store
159851ba086bSDamjan Jovanovic     CurlLock * theLock
159951ba086bSDamjan Jovanovic         = m_aCurlLockStore.findByUri( makeAbsoluteURL( inPath ) );
160051ba086bSDamjan Jovanovic     if ( !theLock )
160151ba086bSDamjan Jovanovic          throw DAVException( DAVException::DAV_NOT_LOCKED );
160251ba086bSDamjan Jovanovic 
160351ba086bSDamjan Jovanovic     Init( rEnv );
160451ba086bSDamjan Jovanovic 
160551ba086bSDamjan Jovanovic     // refresh existing lock.
160651ba086bSDamjan Jovanovic     theLock->timeout = static_cast< long >( nTimeout );
160751ba086bSDamjan Jovanovic 
160851ba086bSDamjan Jovanovic     TimeValue startCall;
160951ba086bSDamjan Jovanovic     osl_getSystemTime( &startCall );
161051ba086bSDamjan Jovanovic 
161151ba086bSDamjan Jovanovic     int theRetVal = ne_lock_refresh( m_pHttpSession, theLock );
161251ba086bSDamjan Jovanovic 
161351ba086bSDamjan Jovanovic     if ( theRetVal == NE_OK )
161451ba086bSDamjan Jovanovic     {
161551ba086bSDamjan Jovanovic         m_aCurlLockStore.updateLock( theLock,
161651ba086bSDamjan Jovanovic                                      lastChanceToSendRefreshRequest(
161751ba086bSDamjan Jovanovic                                          startCall, theLock->timeout ) );
161851ba086bSDamjan Jovanovic     }
161951ba086bSDamjan Jovanovic 
162051ba086bSDamjan Jovanovic     HandleError( theRetVal, inPath, rEnv );
162151ba086bSDamjan Jovanovic 
162251ba086bSDamjan Jovanovic     return theLock->timeout;
162351ba086bSDamjan Jovanovic     */
162451ba086bSDamjan Jovanovic }
162551ba086bSDamjan Jovanovic 
162651ba086bSDamjan Jovanovic // -------------------------------------------------------------------
162751ba086bSDamjan Jovanovic // LOCK (refresh existing lock from CurlLockStore)
162851ba086bSDamjan Jovanovic // -------------------------------------------------------------------
LOCK(CurlLock * pLock,sal_Int32 & rlastChanceToSendRefreshRequest)162951ba086bSDamjan Jovanovic bool CurlSession::LOCK( CurlLock * pLock,
163051ba086bSDamjan Jovanovic                         sal_Int32 & rlastChanceToSendRefreshRequest )
163151ba086bSDamjan Jovanovic {
163251ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "LOCK line $1$", (sal_Int32)__LINE__ );
163351ba086bSDamjan Jovanovic 
163451ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
163551ba086bSDamjan Jovanovic 
163651ba086bSDamjan Jovanovic     Init();
163751ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
163851ba086bSDamjan Jovanovic 
163951ba086bSDamjan Jovanovic     const ucb::Lock & inLock = pLock->getLock();
164051ba086bSDamjan Jovanovic     rtl::OUString inPath = pLock->getResourcePath();
164151ba086bSDamjan Jovanovic 
164251ba086bSDamjan Jovanovic     if ( inLock.Timeout == -1 )
164351ba086bSDamjan Jovanovic         curlRequest.addHeader( "Timeout", "Infinite" );
164451ba086bSDamjan Jovanovic     else
164551ba086bSDamjan Jovanovic         curlRequest.addHeader( "Timeout", "Second-" + rtl::OString::valueOf( inLock.Timeout ) );
164651ba086bSDamjan Jovanovic 
164751ba086bSDamjan Jovanovic     switch ( inLock.Depth )
164851ba086bSDamjan Jovanovic     {
164951ba086bSDamjan Jovanovic         //i126305 TODO investigate on this case...
165051ba086bSDamjan Jovanovic     case ucb::LockDepth_MAKE_FIXED_SIZE:
165151ba086bSDamjan Jovanovic 
165251ba086bSDamjan Jovanovic     case ucb::LockDepth_ZERO:
165351ba086bSDamjan Jovanovic         curlRequest.addHeader( "Depth", "0" );
165451ba086bSDamjan Jovanovic         break;
165551ba086bSDamjan Jovanovic     case ucb::LockDepth_ONE:
165651ba086bSDamjan Jovanovic         curlRequest.addHeader( "Depth", "1" );
165751ba086bSDamjan Jovanovic         break;
165851ba086bSDamjan Jovanovic     case ucb::LockDepth_INFINITY:
165951ba086bSDamjan Jovanovic         curlRequest.addHeader( "Depth", "infinity" );
166051ba086bSDamjan Jovanovic         break;
166151ba086bSDamjan Jovanovic     }
166251ba086bSDamjan Jovanovic 
166351ba086bSDamjan Jovanovic     if ( inLock.LockTokens.getLength() > 0 )
166451ba086bSDamjan Jovanovic     {
166551ba086bSDamjan Jovanovic         curlRequest.addHeader( "If",
166651ba086bSDamjan Jovanovic             ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
166751ba086bSDamjan Jovanovic     }
166851ba086bSDamjan Jovanovic 
166951ba086bSDamjan Jovanovic     rtl::OString xml = LockRequest::generateRequestBody( inLock );
167051ba086bSDamjan Jovanovic     curlRequest.addHeader( "Content-Type", "application/xml" );
167151ba086bSDamjan Jovanovic     curlRequest.setRequestBody( xml.getStr(), xml.getLength() );
167251ba086bSDamjan Jovanovic 
167351ba086bSDamjan Jovanovic     TimeValue startCall;
167451ba086bSDamjan Jovanovic     osl_getSystemTime( &startCall );
167551ba086bSDamjan Jovanovic 
167651ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.lock( m_aUri, inPath );
167751ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
167851ba086bSDamjan Jovanovic 
167951ba086bSDamjan Jovanovic     // the returned property, a sequence of locks
168051ba086bSDamjan Jovanovic     // only the first is used
168151ba086bSDamjan Jovanovic     const DAVPropertyValue outLock( parseWebDAVLockResponse( curlRequest.getResponseBody().get() ) );
168251ba086bSDamjan Jovanovic     uno::Sequence< ucb::Lock >      aLocks;
168351ba086bSDamjan Jovanovic     outLock.Value >>= aLocks;
168451ba086bSDamjan Jovanovic     ucb::Lock aLock = aLocks[0];
168551ba086bSDamjan Jovanovic 
168651ba086bSDamjan Jovanovic     // if ok, update the lastchance refresh time in lock
168751ba086bSDamjan Jovanovic     rlastChanceToSendRefreshRequest
168851ba086bSDamjan Jovanovic         = lastChanceToSendRefreshRequest( startCall, static_cast< sal_Int32 >(aLock.Timeout) );
168951ba086bSDamjan Jovanovic 
169051ba086bSDamjan Jovanovic     return true;
169151ba086bSDamjan Jovanovic }
169251ba086bSDamjan Jovanovic 
169351ba086bSDamjan Jovanovic // -------------------------------------------------------------------
169451ba086bSDamjan Jovanovic // UNLOCK called from external (DAVResourceAccess)
169551ba086bSDamjan Jovanovic // -------------------------------------------------------------------
UNLOCK(const::rtl::OUString & inPath,const DAVRequestEnvironment & rEnv)169651ba086bSDamjan Jovanovic void CurlSession::UNLOCK( const ::rtl::OUString & inPath,
169751ba086bSDamjan Jovanovic                           const DAVRequestEnvironment & rEnv )
169851ba086bSDamjan Jovanovic     throw ( DAVException )
169951ba086bSDamjan Jovanovic {
170051ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "UNLOCK line $1$", (sal_Int32)__LINE__ );
170151ba086bSDamjan Jovanovic 
170251ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
170351ba086bSDamjan Jovanovic 
170451ba086bSDamjan Jovanovic     rtl::OUString aUri( composeCurrentUri( inPath ) );
170551ba086bSDamjan Jovanovic     CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
170651ba086bSDamjan Jovanovic     if ( !pLock )
170751ba086bSDamjan Jovanovic     {
170851ba086bSDamjan Jovanovic         throw DAVException( DAVException::DAV_NOT_LOCKED );
170951ba086bSDamjan Jovanovic     }
171051ba086bSDamjan Jovanovic 
171151ba086bSDamjan Jovanovic     Init( rEnv );
171251ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
171351ba086bSDamjan Jovanovic 
171451ba086bSDamjan Jovanovic     addEnvironmentRequestHeaders( curlRequest, rEnv );
171551ba086bSDamjan Jovanovic 
171651ba086bSDamjan Jovanovic     CredentialsData credsData( this, curlRequest, rEnv );
171751ba086bSDamjan Jovanovic     curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
171851ba086bSDamjan Jovanovic 
171951ba086bSDamjan Jovanovic     ucb::Lock inLock = pLock->getLock();
172051ba086bSDamjan Jovanovic     curlRequest.addHeader( "Lock-Token",
172151ba086bSDamjan Jovanovic             ( "<" + rtl::OUStringToOString( inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">" ).getStr() );
172251ba086bSDamjan Jovanovic 
172351ba086bSDamjan Jovanovic     // remove lock from lockstore
172451ba086bSDamjan Jovanovic     // so, if something goes wrong, we don't refresh it anymore
172551ba086bSDamjan Jovanovic     m_aCurlLockStore.removeLock( pLock );
172651ba086bSDamjan Jovanovic     delete pLock;
172751ba086bSDamjan Jovanovic 
172851ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.unlock( m_aUri, inPath );
172951ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
173051ba086bSDamjan Jovanovic }
173151ba086bSDamjan Jovanovic 
173251ba086bSDamjan Jovanovic // -------------------------------------------------------------------
173351ba086bSDamjan Jovanovic // UNLOCK (called from CurlLockStore)
173451ba086bSDamjan Jovanovic // -------------------------------------------------------------------
UNLOCK(CurlLock * pLock)173551ba086bSDamjan Jovanovic bool CurlSession::UNLOCK( CurlLock * pLock )
173651ba086bSDamjan Jovanovic {
173751ba086bSDamjan Jovanovic     m_aLogger.log( LogLevel::INFO, "UNLOCK line $1$", (sal_Int32)__LINE__ );
173851ba086bSDamjan Jovanovic 
173951ba086bSDamjan Jovanovic     osl::Guard< osl::Mutex > theGuard( m_aMutex );
174051ba086bSDamjan Jovanovic 
174151ba086bSDamjan Jovanovic     Init();
174251ba086bSDamjan Jovanovic     CurlRequest curlRequest( m_pCurl );
174351ba086bSDamjan Jovanovic 
174451ba086bSDamjan Jovanovic     rtl::OUString inPath = pLock->getResourcePath();
174551ba086bSDamjan Jovanovic     ucb::Lock inLock = pLock->getLock();
174651ba086bSDamjan Jovanovic     curlRequest.addHeader( "Lock-Token",
174751ba086bSDamjan Jovanovic             ( "<" + rtl::OUStringToOString( inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">" ).getStr() );
174851ba086bSDamjan Jovanovic 
174951ba086bSDamjan Jovanovic     CURLcode rc = curlRequest.unlock( m_aUri, inPath );
175051ba086bSDamjan Jovanovic     processResponse( curlRequest, rc );
175151ba086bSDamjan Jovanovic     return true;
175251ba086bSDamjan Jovanovic }
175351ba086bSDamjan Jovanovic 
175451ba086bSDamjan Jovanovic // -------------------------------------------------------------------
abort()175551ba086bSDamjan Jovanovic void CurlSession::abort()
175651ba086bSDamjan Jovanovic     throw ( DAVException )
175751ba086bSDamjan Jovanovic {
175851ba086bSDamjan Jovanovic     // 11.11.09 (tkr): The following code lines causing crashes if
175951ba086bSDamjan Jovanovic     // closing a ongoing connection. It turned out that this existing
176051ba086bSDamjan Jovanovic     // solution doesn't work in multi-threading environments.
176151ba086bSDamjan Jovanovic     // So I disabled them in 3.2. . Issue #73893# should fix it in OOo 3.3.
176251ba086bSDamjan Jovanovic     //if ( m_pHttpSession )
176351ba086bSDamjan Jovanovic     //    ne_close_connection( m_pHttpSession );
176451ba086bSDamjan Jovanovic }
176551ba086bSDamjan Jovanovic 
176651ba086bSDamjan Jovanovic // -------------------------------------------------------------------
getProxySettings() const176751ba086bSDamjan Jovanovic const ucbhelper::InternetProxyServer & CurlSession::getProxySettings() const
176851ba086bSDamjan Jovanovic {
176951ba086bSDamjan Jovanovic     if ( m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) ) ||
177051ba086bSDamjan Jovanovic          m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) ) )
177151ba086bSDamjan Jovanovic     {
177251ba086bSDamjan Jovanovic         return m_rProxyDecider.getProxy( m_aUri.GetScheme(),
177351ba086bSDamjan Jovanovic                                          m_aUri.GetHost(),
177451ba086bSDamjan Jovanovic                                          m_aUri.GetPort() );
177551ba086bSDamjan Jovanovic     }
177651ba086bSDamjan Jovanovic     else
177751ba086bSDamjan Jovanovic     {
177851ba086bSDamjan Jovanovic         // TODO: figure out, if this case can occur
177951ba086bSDamjan Jovanovic         return m_rProxyDecider.getProxy( m_aUri.GetScheme(),
178051ba086bSDamjan Jovanovic                                          rtl::OUString() /* not used */,
178151ba086bSDamjan Jovanovic                                          -1 /* not used */ );
178251ba086bSDamjan Jovanovic     }
178351ba086bSDamjan Jovanovic }
178451ba086bSDamjan Jovanovic 
178551ba086bSDamjan Jovanovic /*
178651ba086bSDamjan Jovanovic // -------------------------------------------------------------------
178751ba086bSDamjan Jovanovic namespace {
178851ba086bSDamjan Jovanovic 
178951ba086bSDamjan Jovanovic bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks,
179051ba086bSDamjan Jovanovic                         const char * token )
179151ba086bSDamjan Jovanovic {
179251ba086bSDamjan Jovanovic     for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n )
179351ba086bSDamjan Jovanovic     {
179451ba086bSDamjan Jovanovic         const uno::Sequence< rtl::OUString > & rTokens
179551ba086bSDamjan Jovanovic             = rLocks[ n ].LockTokens;
179651ba086bSDamjan Jovanovic         for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m )
179751ba086bSDamjan Jovanovic         {
179851ba086bSDamjan Jovanovic             if ( rTokens[ m ].equalsAscii( token ) )
179951ba086bSDamjan Jovanovic                 return true;
180051ba086bSDamjan Jovanovic         }
180151ba086bSDamjan Jovanovic     }
180251ba086bSDamjan Jovanovic     return false;
180351ba086bSDamjan Jovanovic }
180451ba086bSDamjan Jovanovic 
180551ba086bSDamjan Jovanovic } // namespace
180651ba086bSDamjan Jovanovic */
180751ba086bSDamjan Jovanovic 
180851ba086bSDamjan Jovanovic // -------------------------------------------------------------------
180951ba086bSDamjan Jovanovic // This method doesn't seem to be used.
181051ba086bSDamjan Jovanovic // In any case the default behavior is to ask a lock with a life of 3 minutes
181151ba086bSDamjan Jovanovic // it will then be refreshed automatically (see CurlLockStore class)
181251ba086bSDamjan Jovanovic // In case of AOO crash the lock will expire by itself
removeExpiredLocktoken(const rtl::OUString &,const DAVRequestEnvironment &)181351ba086bSDamjan Jovanovic bool CurlSession::removeExpiredLocktoken( const rtl::OUString & /*inURL*/,
181451ba086bSDamjan Jovanovic                                           const DAVRequestEnvironment & /*rEnv*/ )
181551ba086bSDamjan Jovanovic {
181651ba086bSDamjan Jovanovic     return true;
181751ba086bSDamjan Jovanovic     /*
181851ba086bSDamjan Jovanovic     CurlLock * theLock = m_aCurlLockStore.findByUri( inURL );
181951ba086bSDamjan Jovanovic     if ( !theLock )
182051ba086bSDamjan Jovanovic         return false;
182151ba086bSDamjan Jovanovic 
182251ba086bSDamjan Jovanovic     // do a lockdiscovery to check whether this lock is still valid.
182351ba086bSDamjan Jovanovic     try
182451ba086bSDamjan Jovanovic     {
182551ba086bSDamjan Jovanovic         // @@@ Alternative: use ne_lock_discover() => less overhead
182651ba086bSDamjan Jovanovic 
182751ba086bSDamjan Jovanovic         std::vector< DAVResource > aResources;
182851ba086bSDamjan Jovanovic         std::vector< rtl::OUString > aPropNames;
182951ba086bSDamjan Jovanovic         aPropNames.push_back( DAVProperties::LOCKDISCOVERY );
183051ba086bSDamjan Jovanovic 
183151ba086bSDamjan Jovanovic         PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv );
183251ba086bSDamjan Jovanovic 
183351ba086bSDamjan Jovanovic         if ( aResources.size() == 0 )
183451ba086bSDamjan Jovanovic             return false;
183551ba086bSDamjan Jovanovic 
183651ba086bSDamjan Jovanovic         std::vector< DAVPropertyValue >::const_iterator it
183751ba086bSDamjan Jovanovic             = aResources[ 0 ].properties.begin();
183851ba086bSDamjan Jovanovic         std::vector< DAVPropertyValue >::const_iterator end
183951ba086bSDamjan Jovanovic             = aResources[ 0 ].properties.end();
184051ba086bSDamjan Jovanovic 
184151ba086bSDamjan Jovanovic         while ( it != end )
184251ba086bSDamjan Jovanovic         {
184351ba086bSDamjan Jovanovic             if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) )
184451ba086bSDamjan Jovanovic             {
184551ba086bSDamjan Jovanovic                 uno::Sequence< ucb::Lock > aLocks;
184651ba086bSDamjan Jovanovic                 if ( !( (*it).Value >>= aLocks ) )
184751ba086bSDamjan Jovanovic                     return false;
184851ba086bSDamjan Jovanovic 
184951ba086bSDamjan Jovanovic                 if ( !containsLocktoken( aLocks, theLock->token ) )
185051ba086bSDamjan Jovanovic                 {
185151ba086bSDamjan Jovanovic                     // expired!
185251ba086bSDamjan Jovanovic                     break;
185351ba086bSDamjan Jovanovic                 }
185451ba086bSDamjan Jovanovic 
185551ba086bSDamjan Jovanovic                 // still valid.
185651ba086bSDamjan Jovanovic                 return false;
185751ba086bSDamjan Jovanovic             }
185851ba086bSDamjan Jovanovic             ++it;
185951ba086bSDamjan Jovanovic         }
186051ba086bSDamjan Jovanovic 
186151ba086bSDamjan Jovanovic         // No lockdiscovery prop in propfind result / locktoken not found
186251ba086bSDamjan Jovanovic         // in propfind result -> not locked
186351ba086bSDamjan Jovanovic         OSL_TRACE( "CurlSession::removeExpiredLocktoken: Removing "
186451ba086bSDamjan Jovanovic                    " expired lock token for %s. token: %s",
186551ba086bSDamjan Jovanovic                    rtl::OUStringToOString( inURL,
186651ba086bSDamjan Jovanovic                                            RTL_TEXTENCODING_UTF8 ).getStr(),
186751ba086bSDamjan Jovanovic                    theLock->token );
186851ba086bSDamjan Jovanovic 
186951ba086bSDamjan Jovanovic         m_aCurlLockStore.removeLock( theLock );
187051ba086bSDamjan Jovanovic         ne_lock_destroy( theLock );
187151ba086bSDamjan Jovanovic         return true;
187251ba086bSDamjan Jovanovic     }
187351ba086bSDamjan Jovanovic     catch ( DAVException const & )
187451ba086bSDamjan Jovanovic     {
187551ba086bSDamjan Jovanovic     }
187651ba086bSDamjan Jovanovic     return false;
187751ba086bSDamjan Jovanovic     */
187851ba086bSDamjan Jovanovic }
187951ba086bSDamjan Jovanovic 
188051ba086bSDamjan Jovanovic // -------------------------------------------------------------------
188151ba086bSDamjan Jovanovic // static
188251ba086bSDamjan Jovanovic bool
getDataFromInputStream(const uno::Reference<io::XInputStream> & xStream,uno::Sequence<sal_Int8> & rData,bool bAppendTrailingZeroByte)188351ba086bSDamjan Jovanovic CurlSession::getDataFromInputStream(
188451ba086bSDamjan Jovanovic     const uno::Reference< io::XInputStream > & xStream,
188551ba086bSDamjan Jovanovic     uno::Sequence< sal_Int8 > & rData,
188651ba086bSDamjan Jovanovic     bool bAppendTrailingZeroByte )
188751ba086bSDamjan Jovanovic {
188851ba086bSDamjan Jovanovic     if ( xStream.is() )
188951ba086bSDamjan Jovanovic     {
189051ba086bSDamjan Jovanovic         uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY );
189151ba086bSDamjan Jovanovic         if ( xSeekable.is() )
189251ba086bSDamjan Jovanovic         {
189351ba086bSDamjan Jovanovic             try
189451ba086bSDamjan Jovanovic             {
189551ba086bSDamjan Jovanovic                 sal_Int32 nSize
189651ba086bSDamjan Jovanovic                     = sal::static_int_cast<sal_Int32>(xSeekable->getLength());
189751ba086bSDamjan Jovanovic                 sal_Int32 nRead
189851ba086bSDamjan Jovanovic                     = xStream->readBytes( rData, nSize );
189951ba086bSDamjan Jovanovic 
190051ba086bSDamjan Jovanovic                 if ( nRead == nSize )
190151ba086bSDamjan Jovanovic                 {
190251ba086bSDamjan Jovanovic                     if ( bAppendTrailingZeroByte )
190351ba086bSDamjan Jovanovic                     {
190451ba086bSDamjan Jovanovic                         rData.realloc( nSize + 1 );
190551ba086bSDamjan Jovanovic                         rData[ nSize ] = sal_Int8( 0 );
190651ba086bSDamjan Jovanovic                     }
190751ba086bSDamjan Jovanovic                     return true;
190851ba086bSDamjan Jovanovic                 }
190951ba086bSDamjan Jovanovic             }
191051ba086bSDamjan Jovanovic             catch ( io::NotConnectedException const & )
191151ba086bSDamjan Jovanovic             {
191251ba086bSDamjan Jovanovic                 // readBytes
191351ba086bSDamjan Jovanovic             }
191451ba086bSDamjan Jovanovic             catch ( io::BufferSizeExceededException const & )
191551ba086bSDamjan Jovanovic             {
191651ba086bSDamjan Jovanovic                 // readBytes
191751ba086bSDamjan Jovanovic             }
191851ba086bSDamjan Jovanovic             catch ( io::IOException const & )
191951ba086bSDamjan Jovanovic             {
192051ba086bSDamjan Jovanovic                 // getLength, readBytes
192151ba086bSDamjan Jovanovic             }
192251ba086bSDamjan Jovanovic         }
192351ba086bSDamjan Jovanovic         else
192451ba086bSDamjan Jovanovic         {
192551ba086bSDamjan Jovanovic             try
192651ba086bSDamjan Jovanovic             {
192751ba086bSDamjan Jovanovic                 uno::Sequence< sal_Int8 > aBuffer;
192851ba086bSDamjan Jovanovic                 sal_Int32 nPos = 0;
192951ba086bSDamjan Jovanovic 
193051ba086bSDamjan Jovanovic                 sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 );
193151ba086bSDamjan Jovanovic                 while ( nRead > 0 )
193251ba086bSDamjan Jovanovic                 {
193351ba086bSDamjan Jovanovic                     if ( rData.getLength() < ( nPos + nRead ) )
193451ba086bSDamjan Jovanovic                         rData.realloc( nPos + nRead );
193551ba086bSDamjan Jovanovic 
193651ba086bSDamjan Jovanovic                     aBuffer.realloc( nRead );
193751ba086bSDamjan Jovanovic                     rtl_copyMemory( (void*)( rData.getArray() + nPos ),
193851ba086bSDamjan Jovanovic                                     (const void*)aBuffer.getConstArray(),
193951ba086bSDamjan Jovanovic                                     nRead );
194051ba086bSDamjan Jovanovic                     nPos += nRead;
194151ba086bSDamjan Jovanovic 
194251ba086bSDamjan Jovanovic                     aBuffer.realloc( 0 );
194351ba086bSDamjan Jovanovic                     nRead = xStream->readSomeBytes( aBuffer, 65536 );
194451ba086bSDamjan Jovanovic                 }
194551ba086bSDamjan Jovanovic 
194651ba086bSDamjan Jovanovic                 if ( bAppendTrailingZeroByte )
194751ba086bSDamjan Jovanovic                 {
194851ba086bSDamjan Jovanovic                     rData.realloc( nPos + 1 );
194951ba086bSDamjan Jovanovic                     rData[ nPos ] = sal_Int8( 0 );
195051ba086bSDamjan Jovanovic                 }
195151ba086bSDamjan Jovanovic                 return true;
195251ba086bSDamjan Jovanovic             }
195351ba086bSDamjan Jovanovic             catch ( io::NotConnectedException const & )
195451ba086bSDamjan Jovanovic             {
195551ba086bSDamjan Jovanovic                 // readBytes
195651ba086bSDamjan Jovanovic             }
195751ba086bSDamjan Jovanovic             catch ( io::BufferSizeExceededException const & )
195851ba086bSDamjan Jovanovic             {
195951ba086bSDamjan Jovanovic                 // readBytes
196051ba086bSDamjan Jovanovic             }
196151ba086bSDamjan Jovanovic             catch ( io::IOException const & )
196251ba086bSDamjan Jovanovic             {
196351ba086bSDamjan Jovanovic                 // readBytes
196451ba086bSDamjan Jovanovic             }
196551ba086bSDamjan Jovanovic         }
196651ba086bSDamjan Jovanovic     }
196751ba086bSDamjan Jovanovic     return false;
196851ba086bSDamjan Jovanovic }
196951ba086bSDamjan Jovanovic 
197051ba086bSDamjan Jovanovic // ---------------------------------------------------------------------
197151ba086bSDamjan Jovanovic sal_Bool
isDomainMatch(rtl::OUString certHostName)197251ba086bSDamjan Jovanovic CurlSession::isDomainMatch( rtl::OUString certHostName )
197351ba086bSDamjan Jovanovic {
197451ba086bSDamjan Jovanovic     rtl::OUString hostName = getHostName();
197551ba086bSDamjan Jovanovic 
197651ba086bSDamjan Jovanovic     if (hostName.equalsIgnoreAsciiCase( certHostName ) )
197751ba086bSDamjan Jovanovic         return sal_True;
197851ba086bSDamjan Jovanovic 
197951ba086bSDamjan Jovanovic     if ( 0 == certHostName.indexOf( rtl::OUString::createFromAscii( "*" ) ) &&
198051ba086bSDamjan Jovanovic          hostName.getLength() >= certHostName.getLength() )
198151ba086bSDamjan Jovanovic     {
198251ba086bSDamjan Jovanovic         rtl::OUString cmpStr = certHostName.copy( 1 );
198351ba086bSDamjan Jovanovic 
198451ba086bSDamjan Jovanovic         if ( hostName.matchIgnoreAsciiCase(
198551ba086bSDamjan Jovanovic                 cmpStr, hostName.getLength() - cmpStr.getLength() ) )
198651ba086bSDamjan Jovanovic             return sal_True;
198751ba086bSDamjan Jovanovic     }
198851ba086bSDamjan Jovanovic     return sal_False;
198951ba086bSDamjan Jovanovic }
1990