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