19646dec5SDamjan Jovanovic /**************************************************************
29646dec5SDamjan Jovanovic *
39646dec5SDamjan Jovanovic * Licensed to the Apache Software Foundation (ASF) under one
49646dec5SDamjan Jovanovic * or more contributor license agreements. See the NOTICE file
59646dec5SDamjan Jovanovic * distributed with this work for additional information
69646dec5SDamjan Jovanovic * regarding copyright ownership. The ASF licenses this file
79646dec5SDamjan Jovanovic * to you under the Apache License, Version 2.0 (the
89646dec5SDamjan Jovanovic * "License"); you may not use this file except in compliance
99646dec5SDamjan Jovanovic * with the License. You may obtain a copy of the License at
109646dec5SDamjan Jovanovic *
119646dec5SDamjan Jovanovic * http://www.apache.org/licenses/LICENSE-2.0
129646dec5SDamjan Jovanovic *
139646dec5SDamjan Jovanovic * Unless required by applicable law or agreed to in writing,
149646dec5SDamjan Jovanovic * software distributed under the License is distributed on an
159646dec5SDamjan Jovanovic * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169646dec5SDamjan Jovanovic * KIND, either express or implied. See the License for the
179646dec5SDamjan Jovanovic * specific language governing permissions and limitations
189646dec5SDamjan Jovanovic * under the License.
199646dec5SDamjan Jovanovic *
209646dec5SDamjan Jovanovic *************************************************************/
219646dec5SDamjan Jovanovic
229646dec5SDamjan Jovanovic
239646dec5SDamjan Jovanovic
249646dec5SDamjan Jovanovic // MARKER(update_precomp.py): autogen include statement, do not remove
259646dec5SDamjan Jovanovic #include "precompiled_webdav.hxx"
269646dec5SDamjan Jovanovic
279646dec5SDamjan Jovanovic #include <hash_map>
289646dec5SDamjan Jovanovic #include <vector>
299646dec5SDamjan Jovanovic #include <string.h>
309646dec5SDamjan Jovanovic #include <rtl/string.h>
319646dec5SDamjan Jovanovic #include <rtl/strbuf.hxx>
329646dec5SDamjan Jovanovic #include <rtl/ustrbuf.hxx>
339646dec5SDamjan Jovanovic #include <osl/time.h>
349646dec5SDamjan Jovanovic #include "comphelper/sequence.hxx"
359646dec5SDamjan Jovanovic #include "ucbhelper/simplecertificatevalidationrequest.hxx"
369646dec5SDamjan Jovanovic
379646dec5SDamjan Jovanovic #include "DAVAuthListener.hxx"
389646dec5SDamjan Jovanovic #include "CurlTypes.hxx"
399646dec5SDamjan Jovanovic #include "CurlSession.hxx"
409646dec5SDamjan Jovanovic #include "LockRequest.hxx"
419646dec5SDamjan Jovanovic #include "PropfindRequest.hxx"
429646dec5SDamjan Jovanovic #include "ProppatchRequest.hxx"
439646dec5SDamjan Jovanovic #include "CurlInputStream.hxx"
449646dec5SDamjan Jovanovic #include "UCBDeadPropertyValue.hxx"
459646dec5SDamjan Jovanovic #include "webdavuseragent.hxx"
469646dec5SDamjan Jovanovic #include "webdavresponseparser.hxx"
479646dec5SDamjan Jovanovic #include "webdavprovider.hxx"
489646dec5SDamjan Jovanovic
499646dec5SDamjan Jovanovic
509646dec5SDamjan Jovanovic #include <com/sun/star/logging/LogLevel.hpp>
519646dec5SDamjan Jovanovic #include <com/sun/star/security/XCertificate.hpp>
529646dec5SDamjan Jovanovic #include <com/sun/star/security/CertificateValidity.hpp>
539646dec5SDamjan Jovanovic #include <com/sun/star/security/CertificateContainerStatus.hpp>
549646dec5SDamjan Jovanovic #include <com/sun/star/security/CertAltNameEntry.hpp>
559646dec5SDamjan Jovanovic #include <com/sun/star/security/XSanExtension.hpp>
569646dec5SDamjan Jovanovic #include <com/sun/star/ucb/Lock.hpp>
579646dec5SDamjan Jovanovic #include <com/sun/star/xml/crypto/XSEInitializer.hpp>
589646dec5SDamjan Jovanovic
599646dec5SDamjan Jovanovic using namespace com::sun::star;
609646dec5SDamjan Jovanovic using namespace com::sun::star::logging;
619646dec5SDamjan Jovanovic using namespace http_dav_ucp;
629646dec5SDamjan Jovanovic
639646dec5SDamjan Jovanovic #define OID_SUBJECT_ALTERNATIVE_NAME "2.5.29.17"
649646dec5SDamjan Jovanovic
659646dec5SDamjan Jovanovic struct CredentialsData
669646dec5SDamjan Jovanovic {
CredentialsDataCredentialsData679646dec5SDamjan Jovanovic CredentialsData( CurlSession *curlSession, CurlRequest &curlRequest, const DAVRequestEnvironment &requestEnvironment )
689646dec5SDamjan Jovanovic : session( curlSession)
699646dec5SDamjan Jovanovic , request( curlRequest )
709646dec5SDamjan Jovanovic , env( requestEnvironment )
719646dec5SDamjan Jovanovic {}
729646dec5SDamjan Jovanovic
739646dec5SDamjan Jovanovic CurlSession *session;
749646dec5SDamjan Jovanovic CurlRequest &request;
759646dec5SDamjan Jovanovic const DAVRequestEnvironment &env;
769646dec5SDamjan Jovanovic };
779646dec5SDamjan Jovanovic
789646dec5SDamjan Jovanovic // -------------------------------------------------------------------
799646dec5SDamjan Jovanovic // static members!
809646dec5SDamjan Jovanovic CurlLockStore CurlSession::m_aCurlLockStore;
819646dec5SDamjan Jovanovic
829646dec5SDamjan Jovanovic
839646dec5SDamjan Jovanovic // -------------------------------------------------------------------
849646dec5SDamjan Jovanovic // Constructor
859646dec5SDamjan Jovanovic // -------------------------------------------------------------------
CurlSession(const rtl::Reference<DAVSessionFactory> & rSessionFactory,const rtl::OUString & inUri,const ucbhelper::InternetProxyDecider & rProxyDecider)869646dec5SDamjan Jovanovic CurlSession::CurlSession(
879646dec5SDamjan Jovanovic const rtl::Reference< DAVSessionFactory > & rSessionFactory,
889646dec5SDamjan Jovanovic const rtl::OUString& inUri,
899646dec5SDamjan Jovanovic const ucbhelper::InternetProxyDecider & rProxyDecider )
909646dec5SDamjan Jovanovic throw ( DAVException )
919646dec5SDamjan Jovanovic : DAVSession( rSessionFactory )
929646dec5SDamjan Jovanovic , m_aMutex()
939646dec5SDamjan Jovanovic , m_aContext( m_xFactory->getServiceFactory() )
949646dec5SDamjan Jovanovic , m_aLogger( m_aContext.getUNOContext(), WEBDAV_CONTENT_PROVIDER_SERVICE_NAME )
959646dec5SDamjan Jovanovic , m_aUri( inUri )
969646dec5SDamjan Jovanovic , m_aProxyName()
979646dec5SDamjan Jovanovic , m_nProxyPort( 0 )
989646dec5SDamjan Jovanovic , m_aServerHeaderField()
999646dec5SDamjan Jovanovic , m_pCurl( 0 )
1009646dec5SDamjan Jovanovic , m_bUseChunkedEncoding( false )
1019646dec5SDamjan Jovanovic , m_bTransferEncodingSwitched( false )
1029646dec5SDamjan Jovanovic , m_rProxyDecider( rProxyDecider )
1039646dec5SDamjan Jovanovic , m_aEnv()
1049646dec5SDamjan Jovanovic {
1059646dec5SDamjan Jovanovic m_pCurl = curl_easy_init();
1069646dec5SDamjan Jovanovic
1079646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_HTTPAUTH, CURLAUTH_ANY );
1089646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYAUTH, CURLAUTH_ANY );
1099646dec5SDamjan Jovanovic
1109646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_SSL_CTX_FUNCTION, Curl_SSLContextCallback );
1119646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_SSL_CTX_DATA, this );
1129646dec5SDamjan Jovanovic
113*3b9e6fb2Slinsong8208 // If a certificate's common name / alt name doesn't match the hostname we are
114e8e5910fSDamjan Jovanovic // connecting to, Curl will refuse to connect. Disable this, as we do that check
115e8e5910fSDamjan Jovanovic // ourselves, and give the user the option of connecting anyway.
116e8e5910fSDamjan Jovanovic //
117e8e5910fSDamjan Jovanovic // Note also, how "man CURLOPT_SSL_VERIFYHOST" tells us that setting 0 here
118e8e5910fSDamjan Jovanovic // disables SNI, which is bad news, some servers require SNI. However reading Curl
119e8e5910fSDamjan Jovanovic // 8.6.0's Curl_ssl_peer_init() in file lib/vtls/vtls.c shows that SNI is sent
120e8e5910fSDamjan Jovanovic // regardless, as long as we are connecting to a domain name, NOT an IP address.
121e8e5910fSDamjan Jovanovic // Tests confirm this. For OpenSSL anyway - other Curl crypto providers are stricter...
122e8e5910fSDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_SSL_VERIFYHOST, 0 );
123e8e5910fSDamjan Jovanovic
1249646dec5SDamjan Jovanovic if ( m_aLogger.getLogLevel() == LogLevel::FINEST )
1259646dec5SDamjan Jovanovic {
1269646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_DEBUGFUNCTION, Curl_DebugCallback );
1279646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_DEBUGDATA, this );
1289646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_VERBOSE, 1L);
1299646dec5SDamjan Jovanovic }
1300ec0f743SDamjan Jovanovic
1310ec0f743SDamjan Jovanovic // Create a certificate container.
1320ec0f743SDamjan Jovanovic if( !m_aContext.createComponent( "com.sun.star.security.CertificateContainer", m_xCertificateContainer ) )
1330ec0f743SDamjan Jovanovic throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii( "Failed to create com.sun.star.security.CertificateContainer" ) );
1340ec0f743SDamjan Jovanovic uno::Reference< xml::crypto::XSEInitializer > xSEInitializer;
1350ec0f743SDamjan Jovanovic if( !m_aContext.createComponent( "com.sun.star.xml.crypto.SEInitializer", xSEInitializer ) )
1360ec0f743SDamjan Jovanovic throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii( "Failed to create com.sun.star.xml.crypto.SEInitializer" ) );
1370ec0f743SDamjan Jovanovic m_xSecurityContext = xSEInitializer->createSecurityContext( rtl::OUString() );
1380ec0f743SDamjan Jovanovic if( m_xSecurityContext.is() )
1390ec0f743SDamjan Jovanovic m_xSecurityEnv = m_xSecurityContext->getSecurityEnvironment();
1400ec0f743SDamjan Jovanovic if ( ! m_xSecurityContext.is() || ! m_xSecurityEnv.is())
1410ec0f743SDamjan Jovanovic throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii( "Failure creating security services for certificate verification" ) );
1420ec0f743SDamjan Jovanovic
1430ec0f743SDamjan Jovanovic // Populate one nonsense certificate, which we won't ever really use, just to get Curl to initialize:
1440ec0f743SDamjan Jovanovic struct curl_blob blob;
1450ec0f743SDamjan Jovanovic blob.data = (void*)
1460ec0f743SDamjan Jovanovic "-----BEGIN CERTIFICATE-----\n"
1470ec0f743SDamjan Jovanovic "MIIC/zCCAeegAwIBAgIUQYFHL3Bv7alQBtXQWy9SXGusm5YwDQYJKoZIhvcNAQEL\n"
1480ec0f743SDamjan Jovanovic "BQAwDzENMAsGA1UEAwwEVEVTVDAeFw0yNDA0MjExNzU3MzdaFw0yNDA0MjIxNzU3\n"
1490ec0f743SDamjan Jovanovic "MzdaMA8xDTALBgNVBAMMBFRFU1QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n"
1500ec0f743SDamjan Jovanovic "AoIBAQCZSXla2TE7GU6xOfie5uilpRf7KQflWcQRgwTCFhk0yzbsSPJYdqbuUqfx\n"
1510ec0f743SDamjan Jovanovic "k0pV9Sx8GIkvc7jKQBwS79T15qn6dAZOF40x/k2jEMq150oc/80+dqeNP2jWvxv7\n"
1520ec0f743SDamjan Jovanovic "FjgBKSiuGUaHldy6XU3NhrA9G1Ys2/yHQRXER1NTeknEzPiPlobRUk1sNR2Prc5r\n"
1530ec0f743SDamjan Jovanovic "0u6cdUWGhbDOKDV9jjvA/14jmaAK+vUqrzzAdiOHVrkglA5oyBKX0BUokRCa8jID\n"
1540ec0f743SDamjan Jovanovic "34tH9zeuvozA3xXCi8l9to+HOgT/n7LAGeOSnNPeSHC/xkwumt/rJ05tL9DXg6Ud\n"
1550ec0f743SDamjan Jovanovic "3Pjf8KZM+FWJsjoJkcwBR0P2Qh3FAgMBAAGjUzBRMB0GA1UdDgQWBBR7pCl5msAz\n"
1560ec0f743SDamjan Jovanovic "rGApirAQ+/tFuHl5kDAfBgNVHSMEGDAWgBR7pCl5msAzrGApirAQ+/tFuHl5kDAP\n"
1570ec0f743SDamjan Jovanovic "BgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBDJ1S51MKlafDAfFbU\n"
1580ec0f743SDamjan Jovanovic "DJcxw3JNHn+VxQuaQQpeeqLIn3rgKHRBV9eOTYHf8AMoCYdQfPs1z45vqBmcyrDw\n"
1590ec0f743SDamjan Jovanovic "LoXL6vlUbSLUuYFyfCaFup3bbh2lLozsLcD6bcvV07amX6V3u0ZOKpwqhg+k/IJd\n"
1600ec0f743SDamjan Jovanovic "cPVM8jYAnNZZYD6rMHWnW5ZgMFSzSj3Jyyaov/3zwixvFZdViBG+R2RmJZVgMiFP\n"
1610ec0f743SDamjan Jovanovic "PNxY3USKiHqdwZIszf3G63Ku0EYtFf3KN8YpoqSMDCDfjL0NhJOtkBUs5HL+4XfK\n"
1620ec0f743SDamjan Jovanovic "hToBqJojDMLFRdVIhPQX1LoPd92CUwhueIrYTikScAqY2TIwXpPH0kBjfrVDus8s\n"
1630ec0f743SDamjan Jovanovic "vPAk\n"
1640ec0f743SDamjan Jovanovic "-----END CERTIFICATE-----";
1650ec0f743SDamjan Jovanovic blob.len = strlen( (char*) blob.data ) + 1;
1660ec0f743SDamjan Jovanovic blob.flags = CURL_BLOB_COPY;
1670ec0f743SDamjan Jovanovic CURLcode rc;
1680ec0f743SDamjan Jovanovic rc = curl_easy_setopt( m_pCurl, CURLOPT_CAINFO_BLOB, &blob );
1690ec0f743SDamjan Jovanovic if( rc != CURLE_OK )
1700ec0f743SDamjan Jovanovic throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii("Error initializing Curl certificate" ) );
1710ec0f743SDamjan Jovanovic
1729646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "CurlSession::CurlSession with URL $1$",
1739646dec5SDamjan Jovanovic rtl::OUStringToOString( inUri, RTL_TEXTENCODING_UTF8 ).getStr() );
1749646dec5SDamjan Jovanovic }
1759646dec5SDamjan Jovanovic
1769646dec5SDamjan Jovanovic // -------------------------------------------------------------------
1779646dec5SDamjan Jovanovic // Destructor
1789646dec5SDamjan Jovanovic // -------------------------------------------------------------------
~CurlSession()1799646dec5SDamjan Jovanovic CurlSession::~CurlSession( )
1809646dec5SDamjan Jovanovic {
1819646dec5SDamjan Jovanovic if ( m_pCurl )
1829646dec5SDamjan Jovanovic {
1839646dec5SDamjan Jovanovic curl_easy_cleanup( m_pCurl );
1849646dec5SDamjan Jovanovic m_pCurl = 0;
1859646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "CurlSession::~CurlSession: closed curl session");
1869646dec5SDamjan Jovanovic }
1879646dec5SDamjan Jovanovic }
1889646dec5SDamjan Jovanovic
1899646dec5SDamjan Jovanovic // -------------------------------------------------------------------
Init(const DAVRequestEnvironment & rEnv)1909646dec5SDamjan Jovanovic void CurlSession::Init( const DAVRequestEnvironment & rEnv )
1919646dec5SDamjan Jovanovic throw ( DAVException )
1929646dec5SDamjan Jovanovic {
1939646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
1949646dec5SDamjan Jovanovic m_aEnv = rEnv;
1959646dec5SDamjan Jovanovic Init();
1969646dec5SDamjan Jovanovic }
1979646dec5SDamjan Jovanovic
1989646dec5SDamjan Jovanovic // -------------------------------------------------------------------
Init()1999646dec5SDamjan Jovanovic void CurlSession::Init()
2009646dec5SDamjan Jovanovic throw ( DAVException )
2019646dec5SDamjan Jovanovic {
2029646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
2039646dec5SDamjan Jovanovic
2049646dec5SDamjan Jovanovic const sal_Char *url = rtl::OUStringToOString( m_aUri.GetURI(), RTL_TEXTENCODING_UTF8 ).getStr();
2059646dec5SDamjan Jovanovic CURLcode rc;
2069646dec5SDamjan Jovanovic rc = curl_easy_setopt( m_pCurl, CURLOPT_URL, url );
2079646dec5SDamjan Jovanovic if ( rc != CURLE_OK )
2089646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_SESSION_CREATE,
2099646dec5SDamjan Jovanovic CurlUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) );
2109646dec5SDamjan Jovanovic
2119646dec5SDamjan Jovanovic const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings();
2129646dec5SDamjan Jovanovic if ( ( rProxyCfg.aName != m_aProxyName )
2139646dec5SDamjan Jovanovic || ( rProxyCfg.nPort != m_nProxyPort ) )
2149646dec5SDamjan Jovanovic {
2159646dec5SDamjan Jovanovic m_aProxyName = rProxyCfg.aName;
2169646dec5SDamjan Jovanovic m_nProxyPort = rProxyCfg.nPort;
2179646dec5SDamjan Jovanovic if ( !m_aProxyName.isEmpty() )
2189646dec5SDamjan Jovanovic {
2199646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "Using $1$ proxy server at $2$:$3$",
2209646dec5SDamjan Jovanovic m_aUri.GetScheme(), m_aProxyName, m_nProxyPort );
2219646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXY, rtl::OUStringToOString( m_aProxyName, RTL_TEXTENCODING_UTF8 ).getStr() );
2229646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYPORT, (long)m_nProxyPort );
2239646dec5SDamjan Jovanovic if ( m_aUri.GetScheme().equalsAscii( "https" ) )
2249646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYTYPE, CURLPROXY_HTTPS );
2259646dec5SDamjan Jovanovic else
2269646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP );
2279646dec5SDamjan Jovanovic // no other proxy types are implemented by AOO
2289646dec5SDamjan Jovanovic }
2299646dec5SDamjan Jovanovic else
2309646dec5SDamjan Jovanovic {
2319646dec5SDamjan Jovanovic // Empty string as opposed to NULL, means don't use the default curl proxy.
2329646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "Not using a proxy server" );
2339646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXY, "" );
2349646dec5SDamjan Jovanovic }
2359646dec5SDamjan Jovanovic // if we change the proxy settings, clear the credentials for the previous proxy too
2369646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYUSERNAME, "" );
2379646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYPASSWORD, "" );
2389646dec5SDamjan Jovanovic }
2399646dec5SDamjan Jovanovic }
2409646dec5SDamjan Jovanovic
isSSLNeeded()2419646dec5SDamjan Jovanovic bool CurlSession::isSSLNeeded()
2429646dec5SDamjan Jovanovic {
2439646dec5SDamjan Jovanovic return m_aUri.GetScheme().equalsIgnoreAsciiCase( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "https" ) ) );
2449646dec5SDamjan Jovanovic }
2459646dec5SDamjan Jovanovic
2469646dec5SDamjan Jovanovic // -------------------------------------------------------------------
2479646dec5SDamjan Jovanovic // helper function
2489646dec5SDamjan Jovanovic // it composes the uri for lockstore registration
composeCurrentUri(const rtl::OUString & inPath)2499646dec5SDamjan Jovanovic rtl::OUString CurlSession::composeCurrentUri(const rtl::OUString & inPath)
2509646dec5SDamjan Jovanovic {
2519646dec5SDamjan Jovanovic rtl::OUString aScheme( m_aUri.GetScheme() );
2529646dec5SDamjan Jovanovic rtl::OUStringBuffer aBuf( aScheme );
2539646dec5SDamjan Jovanovic aBuf.appendAscii( "://" );
2549646dec5SDamjan Jovanovic if ( m_aUri.GetUserName().getLength() > 0 )
2559646dec5SDamjan Jovanovic {
2569646dec5SDamjan Jovanovic aBuf.append( m_aUri.GetUserName() );
2579646dec5SDamjan Jovanovic if ( m_aUri.GetPassword().getLength() > 0 )
2589646dec5SDamjan Jovanovic {
2599646dec5SDamjan Jovanovic aBuf.appendAscii( ":" );
2609646dec5SDamjan Jovanovic aBuf.append( m_aUri.GetPassword() );
2619646dec5SDamjan Jovanovic }
2629646dec5SDamjan Jovanovic aBuf.appendAscii( "@" );
2639646dec5SDamjan Jovanovic }
2649646dec5SDamjan Jovanovic // Is host a numeric IPv6 address?
2659646dec5SDamjan Jovanovic if ( ( m_aUri.GetHost().indexOf( ':' ) != -1 ) &&
2669646dec5SDamjan Jovanovic ( m_aUri.GetHost()[ 0 ] != sal_Unicode( '[' ) ) )
2679646dec5SDamjan Jovanovic {
2689646dec5SDamjan Jovanovic aBuf.appendAscii( "[" );
2699646dec5SDamjan Jovanovic aBuf.append( m_aUri.GetHost() );
2709646dec5SDamjan Jovanovic aBuf.appendAscii( "]" );
2719646dec5SDamjan Jovanovic }
2729646dec5SDamjan Jovanovic else
2739646dec5SDamjan Jovanovic {
2749646dec5SDamjan Jovanovic aBuf.append( m_aUri.GetHost() );
2759646dec5SDamjan Jovanovic }
2769646dec5SDamjan Jovanovic
2779646dec5SDamjan Jovanovic // append port, but only, if not default port.
2789646dec5SDamjan Jovanovic bool bAppendPort = true;
2799646dec5SDamjan Jovanovic sal_Int32 aPort = m_aUri.GetPort();
2809646dec5SDamjan Jovanovic switch ( aPort )
2819646dec5SDamjan Jovanovic {
2829646dec5SDamjan Jovanovic case DEFAULT_HTTP_PORT:
2839646dec5SDamjan Jovanovic bAppendPort = aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) );
2849646dec5SDamjan Jovanovic break;
2859646dec5SDamjan Jovanovic
2869646dec5SDamjan Jovanovic case DEFAULT_HTTPS_PORT:
2879646dec5SDamjan Jovanovic bAppendPort = !aScheme.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) );
2889646dec5SDamjan Jovanovic break;
2899646dec5SDamjan Jovanovic }
2909646dec5SDamjan Jovanovic if ( bAppendPort )
2919646dec5SDamjan Jovanovic {
2929646dec5SDamjan Jovanovic aBuf.appendAscii( ":" );
2939646dec5SDamjan Jovanovic aBuf.append( rtl::OUString::valueOf( aPort ) );
2949646dec5SDamjan Jovanovic }
2959646dec5SDamjan Jovanovic aBuf.append( inPath );
2969646dec5SDamjan Jovanovic
2979646dec5SDamjan Jovanovic rtl::OUString aUri(aBuf.makeStringAndClear() );
2989646dec5SDamjan Jovanovic return aUri;
2999646dec5SDamjan Jovanovic }
3009646dec5SDamjan Jovanovic
3019646dec5SDamjan Jovanovic // -------------------------------------------------------------------
3029646dec5SDamjan Jovanovic // virtual
CanUse(const rtl::OUString & inUri)3039646dec5SDamjan Jovanovic sal_Bool CurlSession::CanUse( const rtl::OUString & inUri )
3049646dec5SDamjan Jovanovic {
3059646dec5SDamjan Jovanovic try
3069646dec5SDamjan Jovanovic {
3079646dec5SDamjan Jovanovic CurlUri theUri( inUri );
3089646dec5SDamjan Jovanovic if ( ( theUri.GetPort() == m_aUri.GetPort() ) &&
3099646dec5SDamjan Jovanovic ( theUri.GetHost() == m_aUri.GetHost() ) &&
3109646dec5SDamjan Jovanovic ( theUri.GetScheme() == m_aUri.GetScheme() ) )
3119646dec5SDamjan Jovanovic {
3129646dec5SDamjan Jovanovic return sal_True;
3139646dec5SDamjan Jovanovic }
3149646dec5SDamjan Jovanovic }
3159646dec5SDamjan Jovanovic catch ( DAVException const & )
3169646dec5SDamjan Jovanovic {
3179646dec5SDamjan Jovanovic return sal_False;
3189646dec5SDamjan Jovanovic }
3199646dec5SDamjan Jovanovic return sal_False;
3209646dec5SDamjan Jovanovic }
3219646dec5SDamjan Jovanovic
3229646dec5SDamjan Jovanovic // -------------------------------------------------------------------
3239646dec5SDamjan Jovanovic // virtual
UsesProxy()3249646dec5SDamjan Jovanovic sal_Bool CurlSession::UsesProxy()
3259646dec5SDamjan Jovanovic {
3269646dec5SDamjan Jovanovic Init();
3279646dec5SDamjan Jovanovic return ( m_aProxyName.getLength() > 0 );
3289646dec5SDamjan Jovanovic }
3299646dec5SDamjan Jovanovic
Curl_DebugCallback(CURL *,curl_infotype type,unsigned char * data,size_t size,void * userdata)3309646dec5SDamjan Jovanovic int CurlSession::Curl_DebugCallback( CURL *, curl_infotype type, unsigned char *data, size_t size, void* userdata )
3319646dec5SDamjan Jovanovic {
3329646dec5SDamjan Jovanovic CurlSession *session = static_cast< CurlSession* >( userdata );
3339646dec5SDamjan Jovanovic return session->curlDebugOutput( type, reinterpret_cast<char*>( data ), size );
3349646dec5SDamjan Jovanovic }
3359646dec5SDamjan Jovanovic
curlDebugOutput(curl_infotype type,char * data,int size)3369646dec5SDamjan Jovanovic int CurlSession::curlDebugOutput( curl_infotype type, char *data, int size )
3379646dec5SDamjan Jovanovic {
3389646dec5SDamjan Jovanovic const char *prefix;
3399646dec5SDamjan Jovanovic switch ( type )
3409646dec5SDamjan Jovanovic {
3419646dec5SDamjan Jovanovic case CURLINFO_TEXT:
3429646dec5SDamjan Jovanovic prefix = "[CurlINFO ]";
3439646dec5SDamjan Jovanovic break;
3449646dec5SDamjan Jovanovic case CURLINFO_HEADER_IN:
3459646dec5SDamjan Jovanovic prefix = "[CurlHDR <-]";
3469646dec5SDamjan Jovanovic break;
3479646dec5SDamjan Jovanovic case CURLINFO_HEADER_OUT:
3489646dec5SDamjan Jovanovic prefix = "[CurlHDR ->]";
3499646dec5SDamjan Jovanovic break;
3509646dec5SDamjan Jovanovic case CURLINFO_DATA_IN:
3519646dec5SDamjan Jovanovic prefix = "[CurlData<-]";
3529646dec5SDamjan Jovanovic break;
3539646dec5SDamjan Jovanovic case CURLINFO_DATA_OUT:
3549646dec5SDamjan Jovanovic prefix = "[CurlData->]";
3559646dec5SDamjan Jovanovic break;
3569646dec5SDamjan Jovanovic default:
3579646dec5SDamjan Jovanovic return 0;
3589646dec5SDamjan Jovanovic }
3599646dec5SDamjan Jovanovic
3609646dec5SDamjan Jovanovic // Trim the trailing \r\n
3619646dec5SDamjan Jovanovic if ( size >= 1 && ( data[size - 1] == '\r' || data[size - 1] == '\n' ) )
3629646dec5SDamjan Jovanovic --size;
3639646dec5SDamjan Jovanovic if ( size >= 1 && ( data[size - 1] == '\r' || data[size - 1] == '\n' ) )
3649646dec5SDamjan Jovanovic --size;
3659646dec5SDamjan Jovanovic rtl::OString message( data, size );
3669646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::FINEST, "$1$ $2$", prefix, message );
3679646dec5SDamjan Jovanovic return 0;
3689646dec5SDamjan Jovanovic }
3699646dec5SDamjan Jovanovic
Curl_SSLContextCallback(CURL *,void * ssl_ctx,void * userptr)3709646dec5SDamjan Jovanovic CURLcode CurlSession::Curl_SSLContextCallback( CURL *, void *ssl_ctx, void *userptr )
3719646dec5SDamjan Jovanovic {
3729646dec5SDamjan Jovanovic CurlSession *session = static_cast<CurlSession*>( userptr );
3739646dec5SDamjan Jovanovic SSL_CTX *context = static_cast<SSL_CTX*>( ssl_ctx );
3749646dec5SDamjan Jovanovic SSL_CTX_set_app_data( context, session );
3750ec0f743SDamjan Jovanovic SSL_CTX_set_cert_verify_callback( context, OPENSSL_VerifyCertificate, session );
3769646dec5SDamjan Jovanovic return CURLE_OK;
3779646dec5SDamjan Jovanovic }
3789646dec5SDamjan Jovanovic
OPENSSL_VerifyCertificate(X509_STORE_CTX * x509_ctx,void * arg)3790ec0f743SDamjan Jovanovic int CurlSession::OPENSSL_VerifyCertificate( X509_STORE_CTX *x509_ctx, void *arg )
3809646dec5SDamjan Jovanovic {
3810ec0f743SDamjan Jovanovic CurlSession *session = static_cast<CurlSession*>( arg );
3820ec0f743SDamjan Jovanovic int verifyResult = session->verifyServerX509Certificate( x509_ctx );
3830ec0f743SDamjan Jovanovic // We have to both return 1 or 0, and set the X509_V_* error code with X509_STORE_CTX_set_error():
3840ec0f743SDamjan Jovanovic X509_STORE_CTX_set_error( x509_ctx, verifyResult );
3850ec0f743SDamjan Jovanovic return verifyResult == X509_V_OK ? 1 : 0;
3869646dec5SDamjan Jovanovic }
3879646dec5SDamjan Jovanovic
convertCertificateToAsn1Der(X509 * certificate)3889646dec5SDamjan Jovanovic static uno::Sequence< sal_Int8 > convertCertificateToAsn1Der( X509 *certificate )
3899646dec5SDamjan Jovanovic {
3909646dec5SDamjan Jovanovic uno::Sequence< sal_Int8 > asn1DerCertificate;
3919646dec5SDamjan Jovanovic int len = i2d_X509( certificate, NULL );
3929646dec5SDamjan Jovanovic if ( len < 0 )
3939646dec5SDamjan Jovanovic return asn1DerCertificate;
3949646dec5SDamjan Jovanovic asn1DerCertificate.realloc( len );
3959646dec5SDamjan Jovanovic unsigned char *end = reinterpret_cast< unsigned char *>( asn1DerCertificate.getArray() );
3969646dec5SDamjan Jovanovic len = i2d_X509( certificate, &end );
3979646dec5SDamjan Jovanovic if ( len >= 0 )
3989646dec5SDamjan Jovanovic return asn1DerCertificate;
3999646dec5SDamjan Jovanovic else
4009646dec5SDamjan Jovanovic return uno::Sequence< sal_Int8 >();
4019646dec5SDamjan Jovanovic }
4029646dec5SDamjan Jovanovic
verifyServerX509Certificate(X509_STORE_CTX * x509StoreContext)4030ec0f743SDamjan Jovanovic int CurlSession::verifyServerX509Certificate( X509_STORE_CTX *x509StoreContext )
4049646dec5SDamjan Jovanovic {
4050ec0f743SDamjan Jovanovic X509 *serverCertificate = X509_STORE_CTX_get0_cert( x509StoreContext );
4060ec0f743SDamjan Jovanovic STACK_OF(X509) *chain = X509_STORE_CTX_get0_untrusted( x509StoreContext );
4079646dec5SDamjan Jovanovic
4089646dec5SDamjan Jovanovic std::vector< uno::Sequence< sal_Int8 > > asn1DerCertificates;
4090ec0f743SDamjan Jovanovic int verifyResult = X509_V_OK;
4109646dec5SDamjan Jovanovic if ( chain != NULL ) {
4119646dec5SDamjan Jovanovic int nCertificates = sk_X509_num( chain );
4120ec0f743SDamjan Jovanovic for ( int i = 0; i < nCertificates && verifyResult == X509_V_OK; i++ ) {
4139646dec5SDamjan Jovanovic X509 *certificate = sk_X509_value( chain, i );
4149646dec5SDamjan Jovanovic uno::Sequence< sal_Int8 > asn1DerCertificate = convertCertificateToAsn1Der( certificate );
4150ec0f743SDamjan Jovanovic if( asn1DerCertificate.getLength() > 0 )
4169646dec5SDamjan Jovanovic asn1DerCertificates.push_back( asn1DerCertificate );
4170ec0f743SDamjan Jovanovic else
4180ec0f743SDamjan Jovanovic verifyResult = X509_V_ERR_UNSPECIFIED;
4199646dec5SDamjan Jovanovic }
4209646dec5SDamjan Jovanovic } else {
4219646dec5SDamjan Jovanovic uno::Sequence< sal_Int8 > asn1DerCertificate = convertCertificateToAsn1Der( serverCertificate );
4220ec0f743SDamjan Jovanovic if( asn1DerCertificate.getLength() > 0 )
4239646dec5SDamjan Jovanovic asn1DerCertificates.push_back( asn1DerCertificate );
4240ec0f743SDamjan Jovanovic else
4250ec0f743SDamjan Jovanovic verifyResult = X509_V_ERR_UNSPECIFIED;
4269646dec5SDamjan Jovanovic }
4270ec0f743SDamjan Jovanovic if( verifyResult == X509_V_OK )
4280ec0f743SDamjan Jovanovic verifyResult = verifyCertificateChain( asn1DerCertificates );
429f7ba5d5aSDamjan Jovanovic
4300ec0f743SDamjan Jovanovic rtl::OUString verifyErrorString = rtl::OUString::createFromAscii( X509_verify_cert_error_string( verifyResult ) );
4310ec0f743SDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "validateServerX509Certificate() verifyResult=$1$ ($2$)",
4320ec0f743SDamjan Jovanovic (sal_Int32)verifyResult, verifyErrorString );
4330ec0f743SDamjan Jovanovic return verifyResult;
4349646dec5SDamjan Jovanovic }
4359646dec5SDamjan Jovanovic
verifyCertificateChain(std::vector<uno::Sequence<sal_Int8>> & asn1DerCertificates)4369646dec5SDamjan Jovanovic int CurlSession::verifyCertificateChain (
4379646dec5SDamjan Jovanovic std::vector< uno::Sequence< sal_Int8 > > &asn1DerCertificates )
4389646dec5SDamjan Jovanovic {
4399646dec5SDamjan Jovanovic // Check arguments.
4409646dec5SDamjan Jovanovic if( asn1DerCertificates.size() <= 0 )
4419646dec5SDamjan Jovanovic {
4420ec0f743SDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "No certificates to verify - failing!" );
4430ec0f743SDamjan Jovanovic return X509_V_ERR_UNSPECIFIED;
4449646dec5SDamjan Jovanovic }
4459646dec5SDamjan Jovanovic
4469646dec5SDamjan Jovanovic // Decode the server certificate.
4479646dec5SDamjan Jovanovic uno::Reference< security::XCertificate > xServerCertificate(
4480ec0f743SDamjan Jovanovic m_xSecurityEnv->createCertificateFromRaw( asn1DerCertificates[0] ) );
4499646dec5SDamjan Jovanovic if ( ! xServerCertificate.is())
4509646dec5SDamjan Jovanovic {
4519646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Failed to create XCertificate" );
4520ec0f743SDamjan Jovanovic return X509_V_ERR_UNSPECIFIED;
4539646dec5SDamjan Jovanovic }
4549646dec5SDamjan Jovanovic
4559646dec5SDamjan Jovanovic // Get the subject from the server certificate.
4569646dec5SDamjan Jovanovic ::rtl::OUString sServerCertificateSubject (xServerCertificate->getSubjectName());
4579646dec5SDamjan Jovanovic sal_Int32 nIndex = 0;
4589646dec5SDamjan Jovanovic while (nIndex >= 0)
4599646dec5SDamjan Jovanovic {
4609646dec5SDamjan Jovanovic const ::rtl::OUString sToken (sServerCertificateSubject.getToken(0, ',', nIndex));
4619646dec5SDamjan Jovanovic if (sToken.compareToAscii("CN=", 3) == 0)
4629646dec5SDamjan Jovanovic {
4639646dec5SDamjan Jovanovic sServerCertificateSubject = sToken.copy(3);
4649646dec5SDamjan Jovanovic break;
4659646dec5SDamjan Jovanovic }
4669646dec5SDamjan Jovanovic else if (sToken.compareToAscii(" CN=", 4) == 0)
4679646dec5SDamjan Jovanovic {
4689646dec5SDamjan Jovanovic sServerCertificateSubject = sToken.copy(4);
4699646dec5SDamjan Jovanovic break;
4709646dec5SDamjan Jovanovic }
4719646dec5SDamjan Jovanovic }
4729646dec5SDamjan Jovanovic
4739646dec5SDamjan Jovanovic // When the certificate container already contains a (trusted)
4749646dec5SDamjan Jovanovic // entry for the server then we do not have to authenticate any
4759646dec5SDamjan Jovanovic // certificate.
4769646dec5SDamjan Jovanovic const security::CertificateContainerStatus eStatus (
4770ec0f743SDamjan Jovanovic m_xCertificateContainer->hasCertificate(
4789646dec5SDamjan Jovanovic getHostName(), sServerCertificateSubject ) );
4799646dec5SDamjan Jovanovic if (eStatus != security::CertificateContainerStatus_NOCERT)
4809646dec5SDamjan Jovanovic {
4819646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::FINER, "Cached certificate found with status=$1$",
4829646dec5SDamjan Jovanovic eStatus == security::CertificateContainerStatus_TRUSTED ? "trusted" : "untrusted" );
4839646dec5SDamjan Jovanovic return eStatus == security::CertificateContainerStatus_TRUSTED
4840ec0f743SDamjan Jovanovic ? X509_V_OK
4850ec0f743SDamjan Jovanovic : X509_V_ERR_CERT_UNTRUSTED;
4869646dec5SDamjan Jovanovic }
4879646dec5SDamjan Jovanovic
4889646dec5SDamjan Jovanovic // The shortcut failed, so try to verify the whole chain. This is
4899646dec5SDamjan Jovanovic // done outside the isDomainMatch() block because the result is
4909646dec5SDamjan Jovanovic // used by the interaction handler.
4919646dec5SDamjan Jovanovic std::vector< uno::Reference< security::XCertificate > > aChain;
4929646dec5SDamjan Jovanovic for (nIndex=0; nIndex < asn1DerCertificates.size(); ++nIndex)
4939646dec5SDamjan Jovanovic {
4949646dec5SDamjan Jovanovic uno::Reference< security::XCertificate > xCertificate(
4950ec0f743SDamjan Jovanovic m_xSecurityEnv->createCertificateFromRaw( asn1DerCertificates[ nIndex ] ) );
4969646dec5SDamjan Jovanovic if ( ! xCertificate.is())
4979646dec5SDamjan Jovanovic {
4980ec0f743SDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Failed to create XCertificate $1$", nIndex );
4990ec0f743SDamjan Jovanovic return X509_V_ERR_UNSPECIFIED;
5009646dec5SDamjan Jovanovic }
5019646dec5SDamjan Jovanovic aChain.push_back(xCertificate);
5029646dec5SDamjan Jovanovic }
5030ec0f743SDamjan Jovanovic const sal_Int64 nVerificationResult (m_xSecurityEnv->verifyCertificate(
5049646dec5SDamjan Jovanovic xServerCertificate,
5059646dec5SDamjan Jovanovic ::comphelper::containerToSequence(aChain)));
5069646dec5SDamjan Jovanovic
5079646dec5SDamjan Jovanovic // When the certificate matches the host name then we can use the
5089646dec5SDamjan Jovanovic // result of the verification.
5099646dec5SDamjan Jovanovic bool bHostnameMatchesCertHostnames = false;
5109646dec5SDamjan Jovanovic {
5119646dec5SDamjan Jovanovic uno::Sequence< uno::Reference< security::XCertificateExtension > > extensions = xServerCertificate->getExtensions();
5129646dec5SDamjan Jovanovic uno::Sequence< security::CertAltNameEntry > altNames;
5139646dec5SDamjan Jovanovic for (sal_Int32 i = 0 ; i < extensions.getLength(); ++i)
5149646dec5SDamjan Jovanovic {
5159646dec5SDamjan Jovanovic uno::Reference< security::XCertificateExtension >element = extensions[i];
5169646dec5SDamjan Jovanovic
5179646dec5SDamjan Jovanovic const rtl::OString aId ( (const sal_Char *)element->getExtensionId().getArray(), element->getExtensionId().getLength());
5189646dec5SDamjan Jovanovic if ( aId.equals( OID_SUBJECT_ALTERNATIVE_NAME ) )
5199646dec5SDamjan Jovanovic {
5209646dec5SDamjan Jovanovic uno::Reference< security::XSanExtension > sanExtension ( element, uno::UNO_QUERY );
5219646dec5SDamjan Jovanovic altNames = sanExtension->getAlternativeNames();
5229646dec5SDamjan Jovanovic break;
5239646dec5SDamjan Jovanovic }
5249646dec5SDamjan Jovanovic }
5259646dec5SDamjan Jovanovic
5269646dec5SDamjan Jovanovic uno::Sequence< ::rtl::OUString > certHostNames(altNames.getLength() + 1);
5279646dec5SDamjan Jovanovic certHostNames[0] = sServerCertificateSubject;
5289646dec5SDamjan Jovanovic for( int n = 0; n < altNames.getLength(); ++n )
5299646dec5SDamjan Jovanovic {
5309646dec5SDamjan Jovanovic if (altNames[n].Type == security::ExtAltNameType_DNS_NAME)
5319646dec5SDamjan Jovanovic {
5329646dec5SDamjan Jovanovic altNames[n].Value >>= certHostNames[n+1];
5339646dec5SDamjan Jovanovic }
5349646dec5SDamjan Jovanovic }
5359646dec5SDamjan Jovanovic
5369646dec5SDamjan Jovanovic for ( int i = 0; i < certHostNames.getLength() && !bHostnameMatchesCertHostnames; ++i )
5379646dec5SDamjan Jovanovic {
5389646dec5SDamjan Jovanovic bHostnameMatchesCertHostnames = isDomainMatch( certHostNames[i] );
5399646dec5SDamjan Jovanovic }
5409646dec5SDamjan Jovanovic
5419646dec5SDamjan Jovanovic }
5429646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "URL hostname $1$ certificate hostname",
5439646dec5SDamjan Jovanovic bHostnameMatchesCertHostnames ? "matches" : "DOESN'T MATCH" );
5449646dec5SDamjan Jovanovic if ( bHostnameMatchesCertHostnames )
5459646dec5SDamjan Jovanovic {
5469646dec5SDamjan Jovanovic if (nVerificationResult == 0)
5479646dec5SDamjan Jovanovic {
5489646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "Certificate (chain) is valid" );
5490ec0f743SDamjan Jovanovic m_xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_True);
5500ec0f743SDamjan Jovanovic return X509_V_OK;
5519646dec5SDamjan Jovanovic }
5529646dec5SDamjan Jovanovic else if ((nVerificationResult & security::CertificateValidity::CHAIN_INCOMPLETE) != 0)
5539646dec5SDamjan Jovanovic {
5549646dec5SDamjan Jovanovic // We do not have enough information for verification,
5559646dec5SDamjan Jovanovic // neither automatically (as we just discovered) nor
5569646dec5SDamjan Jovanovic // manually (so there is no point in showing any dialog.)
5579646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Certificate (chain) is incomplete" );
5580ec0f743SDamjan Jovanovic return X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT;
5599646dec5SDamjan Jovanovic }
5609646dec5SDamjan Jovanovic else if ((nVerificationResult & security::CertificateValidity::REVOKED) != 0)
5619646dec5SDamjan Jovanovic {
5629646dec5SDamjan Jovanovic // Certificate (chain) is invalid.
5639646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Certificate (chain) is revoked" );
5640ec0f743SDamjan Jovanovic m_xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_False);
5650ec0f743SDamjan Jovanovic return X509_V_ERR_CERT_REVOKED;
5669646dec5SDamjan Jovanovic }
5679646dec5SDamjan Jovanovic else
5689646dec5SDamjan Jovanovic {
5699646dec5SDamjan Jovanovic // For all other we have to ask the user.
570*3b9e6fb2Slinsong8208 m_aLogger.log( LogLevel::FINE, "Prompting user to validate the certificate" );
5719646dec5SDamjan Jovanovic }
5729646dec5SDamjan Jovanovic }
5739646dec5SDamjan Jovanovic
5749646dec5SDamjan Jovanovic // We have not been able to automatically verify (or falsify) the
5759646dec5SDamjan Jovanovic // certificate chain. To resolve this we have to ask the user.
5769646dec5SDamjan Jovanovic const uno::Reference< ucb::XCommandEnvironment > xEnv( getRequestEnvironment().m_xEnv );
5779646dec5SDamjan Jovanovic if ( xEnv.is() )
5789646dec5SDamjan Jovanovic {
5799646dec5SDamjan Jovanovic uno::Reference< task::XInteractionHandler > xIH( xEnv->getInteractionHandler() );
5809646dec5SDamjan Jovanovic if ( xIH.is() )
5819646dec5SDamjan Jovanovic {
5829646dec5SDamjan Jovanovic rtl::Reference< ucbhelper::SimpleCertificateValidationRequest >
5839646dec5SDamjan Jovanovic xRequest( new ucbhelper::SimpleCertificateValidationRequest(
5849646dec5SDamjan Jovanovic static_cast<sal_Int32>(nVerificationResult), xServerCertificate, getHostName() ) );
5859646dec5SDamjan Jovanovic xIH->handle( xRequest.get() );
5869646dec5SDamjan Jovanovic
5879646dec5SDamjan Jovanovic rtl::Reference< ucbhelper::InteractionContinuation > xSelection
5889646dec5SDamjan Jovanovic = xRequest->getSelection();
5899646dec5SDamjan Jovanovic
5909646dec5SDamjan Jovanovic if ( xSelection.is() )
5919646dec5SDamjan Jovanovic {
5929646dec5SDamjan Jovanovic uno::Reference< task::XInteractionApprove > xApprove( xSelection.get(), uno::UNO_QUERY );
5939646dec5SDamjan Jovanovic if ( xApprove.is() )
5949646dec5SDamjan Jovanovic {
5959646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "The user approved the certificate" );
5960ec0f743SDamjan Jovanovic m_xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_True );
5970ec0f743SDamjan Jovanovic return X509_V_OK;
5989646dec5SDamjan Jovanovic }
5999646dec5SDamjan Jovanovic else
6009646dec5SDamjan Jovanovic {
6019646dec5SDamjan Jovanovic // Don't trust cert
6020ec0f743SDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "The user REJECTED the certificate" );
6030ec0f743SDamjan Jovanovic m_xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False );
6040ec0f743SDamjan Jovanovic return X509_V_ERR_CERT_REJECTED;
6059646dec5SDamjan Jovanovic }
6069646dec5SDamjan Jovanovic }
6079646dec5SDamjan Jovanovic }
6089646dec5SDamjan Jovanovic else
6099646dec5SDamjan Jovanovic {
6109646dec5SDamjan Jovanovic // Don't trust cert
6119646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Couldn't create the interaction handler for user feedback, rejecting the certificate" );
6120ec0f743SDamjan Jovanovic m_xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False );
6130ec0f743SDamjan Jovanovic return X509_V_ERR_CERT_REJECTED;
6149646dec5SDamjan Jovanovic }
6159646dec5SDamjan Jovanovic }
6169646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "No XCommandEnvironment, rejecting the certificate" );
6179646dec5SDamjan Jovanovic
6180ec0f743SDamjan Jovanovic return X509_V_ERR_CERT_REJECTED;
6199646dec5SDamjan Jovanovic }
6209646dec5SDamjan Jovanovic
Curl_ProvideCredentials(long statusCode,void * userdata)6219646dec5SDamjan Jovanovic bool CurlSession::Curl_ProvideCredentials( long statusCode, void *userdata ) throw (DAVException)
6229646dec5SDamjan Jovanovic {
6239646dec5SDamjan Jovanovic CredentialsData *credentialsData = (CredentialsData*)userdata;
6249646dec5SDamjan Jovanovic return credentialsData->session->provideCredentials( credentialsData->env, credentialsData->request, statusCode );
6259646dec5SDamjan Jovanovic }
6269646dec5SDamjan Jovanovic
provideCredentials(const DAVRequestEnvironment & env,CurlRequest & request,long statusCode)6279646dec5SDamjan Jovanovic bool CurlSession::provideCredentials( const DAVRequestEnvironment &env, CurlRequest &request, long statusCode ) throw (DAVException)
6289646dec5SDamjan Jovanovic {
6299646dec5SDamjan Jovanovic DAVAuthListener * pListener = env.m_xAuthListener.get();
6309646dec5SDamjan Jovanovic if ( !pListener )
6319646dec5SDamjan Jovanovic {
6329646dec5SDamjan Jovanovic // abort
6339646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "No DAVAuthListener found, failing credentials entry" );
6349646dec5SDamjan Jovanovic return false;
6359646dec5SDamjan Jovanovic }
6369646dec5SDamjan Jovanovic
6379646dec5SDamjan Jovanovic rtl::OUString theUserName;
6389646dec5SDamjan Jovanovic rtl::OUString thePassWord;
6399646dec5SDamjan Jovanovic try
6409646dec5SDamjan Jovanovic {
6419646dec5SDamjan Jovanovic CurlUri uri( env.m_aRequestURI );
6429646dec5SDamjan Jovanovic theUserName = uri.GetUserName();
6439646dec5SDamjan Jovanovic thePassWord = uri.GetPassword();
6449646dec5SDamjan Jovanovic }
6459646dec5SDamjan Jovanovic catch ( DAVException const &e )
6469646dec5SDamjan Jovanovic {
6479646dec5SDamjan Jovanovic // abort
6489646dec5SDamjan Jovanovic m_aLogger.log(
6499646dec5SDamjan Jovanovic LogLevel::WARNING,
6509646dec5SDamjan Jovanovic "Error extracing userinfo from URI: exceptionCode=$1$, status=$2$, data=$3$, owner=$4$, extendedError=$5%",
6519646dec5SDamjan Jovanovic (sal_Int32)e.getError(), e.getStatus(), e.getData(), e.getOwner(), e.getExtendedError()
6529646dec5SDamjan Jovanovic );
6539646dec5SDamjan Jovanovic return false;
6549646dec5SDamjan Jovanovic }
6559646dec5SDamjan Jovanovic
6569646dec5SDamjan Jovanovic bool canUseSystemCreds = false;
6579646dec5SDamjan Jovanovic long authMethods = 0;
6589646dec5SDamjan Jovanovic CURLcode rc = CURLE_OK;
6599646dec5SDamjan Jovanovic if ( statusCode == 401 )
6609646dec5SDamjan Jovanovic rc = curl_easy_getinfo( m_pCurl, CURLINFO_HTTPAUTH_AVAIL, &authMethods );
6619646dec5SDamjan Jovanovic else if ( statusCode == 407 )
6629646dec5SDamjan Jovanovic rc = curl_easy_getinfo( m_pCurl, CURLINFO_PROXYAUTH_AVAIL, &authMethods );
6639646dec5SDamjan Jovanovic if ( rc == 0 )
6649646dec5SDamjan Jovanovic canUseSystemCreds = (authMethods & CURLAUTH_NEGOTIATE) || (authMethods & CURLAUTH_NTLM);
6659646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "authMethods=$1$, canUseSystemCreds=$2$",
6669646dec5SDamjan Jovanovic (sal_Int64)authMethods, (sal_Int32)canUseSystemCreds );
6679646dec5SDamjan Jovanovic
6689646dec5SDamjan Jovanovic const CurlRequest::Header *authHeader = NULL;
6699646dec5SDamjan Jovanovic if ( statusCode == 401 )
6709646dec5SDamjan Jovanovic authHeader = request.findResponseHeader( "WWW-Authenticate" );
6719646dec5SDamjan Jovanovic else if ( statusCode == 407 )
6729646dec5SDamjan Jovanovic authHeader = request.findResponseHeader( "Proxy-Authenticate" );
6739646dec5SDamjan Jovanovic rtl::OUString realm;
6749646dec5SDamjan Jovanovic if ( authHeader != NULL )
6759646dec5SDamjan Jovanovic {
6769646dec5SDamjan Jovanovic int realmStart = authHeader->value.indexOf( "realm=\"" );
6779646dec5SDamjan Jovanovic if ( realmStart >= 0 )
6789646dec5SDamjan Jovanovic {
6799646dec5SDamjan Jovanovic realmStart += 7;
6809646dec5SDamjan Jovanovic int realmEnd = authHeader->value.indexOf( "\"", realmStart );
6819646dec5SDamjan Jovanovic if ( realmEnd > 0 )
6829646dec5SDamjan Jovanovic realm = rtl::OStringToOUString( authHeader->value.copy( realmStart, realmEnd - realmStart ), RTL_TEXTENCODING_UTF8 );
6839646dec5SDamjan Jovanovic }
6849646dec5SDamjan Jovanovic }
6859646dec5SDamjan Jovanovic
6869646dec5SDamjan Jovanovic int theRetVal = pListener->authenticate( realm,
6879646dec5SDamjan Jovanovic getHostName(),
6889646dec5SDamjan Jovanovic theUserName,
6899646dec5SDamjan Jovanovic thePassWord,
6909646dec5SDamjan Jovanovic canUseSystemCreds,
6919646dec5SDamjan Jovanovic // Authenticating with both the proxy
6929646dec5SDamjan Jovanovic // and the destination server requires sal_True here,
6939646dec5SDamjan Jovanovic // and needs filling out 2 x password dialogs.
6949646dec5SDamjan Jovanovic sal_True );
6959646dec5SDamjan Jovanovic
6969646dec5SDamjan Jovanovic if ( theRetVal == 0 )
6979646dec5SDamjan Jovanovic {
6989646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::FINEST, "got credentials for user=$1$ on realm=$2$", theUserName, realm );
6999646dec5SDamjan Jovanovic // "System credentials" means username and password are empty
7009646dec5SDamjan Jovanovic const char *curlUsername = NULL;
7019646dec5SDamjan Jovanovic const char *curlPassword = NULL;
7029646dec5SDamjan Jovanovic if ( !theUserName.isEmpty() )
7039646dec5SDamjan Jovanovic curlUsername = rtl::OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ).getStr();
7049646dec5SDamjan Jovanovic if ( !thePassWord.isEmpty() )
7059646dec5SDamjan Jovanovic curlPassword = rtl::OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ).getStr();
7069646dec5SDamjan Jovanovic if ( statusCode == 401 )
7079646dec5SDamjan Jovanovic {
7089646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_USERNAME, curlUsername );
7099646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PASSWORD, curlPassword );
7109646dec5SDamjan Jovanovic }
7119646dec5SDamjan Jovanovic else
7129646dec5SDamjan Jovanovic {
7139646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYUSERNAME, curlUsername );
7149646dec5SDamjan Jovanovic curl_easy_setopt( m_pCurl, CURLOPT_PROXYPASSWORD, curlPassword );
7159646dec5SDamjan Jovanovic }
7169646dec5SDamjan Jovanovic return true;
7179646dec5SDamjan Jovanovic }
7189646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "credentials entry cancelled or failed" );
7199646dec5SDamjan Jovanovic
7209646dec5SDamjan Jovanovic return false;
7219646dec5SDamjan Jovanovic }
7229646dec5SDamjan Jovanovic
addEnvironmentRequestHeaders(CurlRequest & curlRequest,const DAVRequestEnvironment & env)7239646dec5SDamjan Jovanovic void CurlSession::addEnvironmentRequestHeaders( CurlRequest &curlRequest, const DAVRequestEnvironment &env )
7249646dec5SDamjan Jovanovic throw ( DAVException )
7259646dec5SDamjan Jovanovic {
7269646dec5SDamjan Jovanovic bool bHasUserAgent( false );
7279646dec5SDamjan Jovanovic DAVRequestHeaders::const_iterator aHeaderIter( env.m_aRequestHeaders.begin() );
7289646dec5SDamjan Jovanovic const DAVRequestHeaders::const_iterator aEnd( env.m_aRequestHeaders.end() );
7299646dec5SDamjan Jovanovic
7309646dec5SDamjan Jovanovic while ( aHeaderIter != aEnd )
7319646dec5SDamjan Jovanovic {
7329646dec5SDamjan Jovanovic const rtl::OString aHeader = rtl::OUStringToOString( aHeaderIter->first,
7339646dec5SDamjan Jovanovic RTL_TEXTENCODING_UTF8 );
7349646dec5SDamjan Jovanovic const rtl::OString aValue = rtl::OUStringToOString( aHeaderIter->second,
7359646dec5SDamjan Jovanovic RTL_TEXTENCODING_UTF8 );
7369646dec5SDamjan Jovanovic
7379646dec5SDamjan Jovanovic if ( !bHasUserAgent )
7389646dec5SDamjan Jovanovic bHasUserAgent = aHeaderIter->first.equalsAsciiL(
7399646dec5SDamjan Jovanovic RTL_CONSTASCII_STRINGPARAM( "User-Agent" ) );
7409646dec5SDamjan Jovanovic
7419646dec5SDamjan Jovanovic curlRequest.addHeader( aHeader, aValue );
7429646dec5SDamjan Jovanovic
7439646dec5SDamjan Jovanovic ++aHeaderIter;
7449646dec5SDamjan Jovanovic }
7459646dec5SDamjan Jovanovic
7469646dec5SDamjan Jovanovic if ( !bHasUserAgent )
7479646dec5SDamjan Jovanovic {
7489646dec5SDamjan Jovanovic const rtl::OUString &rUserAgent = WebDAVUserAgent::get();
7499646dec5SDamjan Jovanovic curlRequest.addHeader( "User-Agent", rtl::OUStringToOString( rUserAgent, RTL_TEXTENCODING_UTF8 ) );
7509646dec5SDamjan Jovanovic }
7519646dec5SDamjan Jovanovic }
7529646dec5SDamjan Jovanovic
processResponse(CurlRequest & curlRequest,CURLcode curlCode)7539646dec5SDamjan Jovanovic void CurlSession::processResponse( CurlRequest &curlRequest, CURLcode curlCode )
7549646dec5SDamjan Jovanovic throw( DAVException )
7559646dec5SDamjan Jovanovic {
7569646dec5SDamjan Jovanovic long statusCode = 0;
7579646dec5SDamjan Jovanovic CURLcode curlRes;
7589646dec5SDamjan Jovanovic curlRes = curl_easy_getinfo( m_pCurl, CURLINFO_RESPONSE_CODE, &statusCode );
7599646dec5SDamjan Jovanovic if ( curlRes != 0 || statusCode == 0 )
7609646dec5SDamjan Jovanovic statusCode = curlRequest.getStatusCode();
7619646dec5SDamjan Jovanovic
7629646dec5SDamjan Jovanovic // check header according:
7639646dec5SDamjan Jovanovic // http://tools.ietf.org/html/rfc7231#section-7.4.2
7649646dec5SDamjan Jovanovic // need to do this so we can adjust the protocol accordingly
7659646dec5SDamjan Jovanovic const CurlRequest::Header *server = curlRequest.findResponseHeader( "server" );
7669646dec5SDamjan Jovanovic if ( server != NULL )
7679646dec5SDamjan Jovanovic m_aServerHeaderField = server->value;
7689646dec5SDamjan Jovanovic
7699646dec5SDamjan Jovanovic if ( curlCode != 0 )
7709646dec5SDamjan Jovanovic {
7719646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::WARNING, "Curl request failed with CURLcode $1$", (sal_Int64)curlCode );
7725f005af5SArrigo Marchiori DAVException::ExceptionCode exCode = DAVException::DAV_HTTP_ERROR;
7735f005af5SArrigo Marchiori rtl::OUString exData;
7745f005af5SArrigo Marchiori switch (curlCode) {
7755f005af5SArrigo Marchiori case CURLE_COULDNT_RESOLVE_HOST:
7765f005af5SArrigo Marchiori exCode = DAVException::DAV_HTTP_LOOKUP;
7775f005af5SArrigo Marchiori exData = CurlUri::makeConnectionEndPointString( getHostName(),
7785f005af5SArrigo Marchiori getPort() );
7795f005af5SArrigo Marchiori break;
7805f005af5SArrigo Marchiori case CURLE_COULDNT_CONNECT:
7815f005af5SArrigo Marchiori exCode = DAVException::DAV_HTTP_CONNECT;
7825f005af5SArrigo Marchiori exData = CurlUri::makeConnectionEndPointString( getHostName(),
7835f005af5SArrigo Marchiori getPort() );
7845f005af5SArrigo Marchiori break;
7855f005af5SArrigo Marchiori case CURLE_OPERATION_TIMEDOUT:
7865f005af5SArrigo Marchiori exCode = DAVException::DAV_HTTP_TIMEOUT;
7875f005af5SArrigo Marchiori exData = CurlUri::makeConnectionEndPointString( getHostName(),
7885f005af5SArrigo Marchiori getPort() );
7895f005af5SArrigo Marchiori break;
7905f005af5SArrigo Marchiori case CURLE_LOGIN_DENIED:
7915f005af5SArrigo Marchiori case CURLE_AUTH_ERROR:
7925f005af5SArrigo Marchiori exCode = DAVException::DAV_HTTP_AUTH;
7935f005af5SArrigo Marchiori exData = CurlUri::makeConnectionEndPointString( getHostName(),
7945f005af5SArrigo Marchiori getPort() );
7955f005af5SArrigo Marchiori break;
7965f005af5SArrigo Marchiori default:
7975f005af5SArrigo Marchiori {
7985f005af5SArrigo Marchiori const char *s = curl_easy_strerror(curlCode);
7995f005af5SArrigo Marchiori exCode = DAVException::DAV_HTTP_ERROR;
8005f005af5SArrigo Marchiori exData = ::rtl::OUString(s, strlen(s),
8015f005af5SArrigo Marchiori RTL_TEXTENCODING_UTF8);
8025f005af5SArrigo Marchiori break;
8035f005af5SArrigo Marchiori }
8045f005af5SArrigo Marchiori }
8055f005af5SArrigo Marchiori throw DAVException( exCode, exData );
8069646dec5SDamjan Jovanovic }
8079646dec5SDamjan Jovanovic
8089646dec5SDamjan Jovanovic rtl::OUString reasonPhrase = rtl::OStringToOUString( curlRequest.getReasonPhrase(), RTL_TEXTENCODING_UTF8 );
8099646dec5SDamjan Jovanovic if ( statusCode != 0 && statusCode / 100 != 2 )
8109646dec5SDamjan Jovanovic {
8119646dec5SDamjan Jovanovic switch (statusCode)
8129646dec5SDamjan Jovanovic {
8139646dec5SDamjan Jovanovic case SC_MOVED_PERMANENTLY: // 301
8149646dec5SDamjan Jovanovic case SC_MOVED_TEMPORARILY: // 302
8159646dec5SDamjan Jovanovic case SC_SEE_OTHER: // 303
8169646dec5SDamjan Jovanovic case SC_TEMPORARY_REDIRECT: // 307
8179646dec5SDamjan Jovanovic {
8189646dec5SDamjan Jovanovic // new location for certain redirections
8199646dec5SDamjan Jovanovic
8209646dec5SDamjan Jovanovic const CurlRequest::Header *location = curlRequest.findResponseHeader( "location" );
8219646dec5SDamjan Jovanovic if ( location != NULL )
8229646dec5SDamjan Jovanovic {
8239646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::FINE, "HTTP $1$ response with new location = $2$",
8249646dec5SDamjan Jovanovic statusCode, location->value );
8259646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_HTTP_REDIRECT,
8269646dec5SDamjan Jovanovic rtl::OStringToOUString( location->value, RTL_TEXTENCODING_UTF8 ) );
8279646dec5SDamjan Jovanovic }
8289646dec5SDamjan Jovanovic break;
8299646dec5SDamjan Jovanovic }
8309646dec5SDamjan Jovanovic case SC_UNAUTHORIZED: // 401
8319646dec5SDamjan Jovanovic case SC_PROXY_AUTHENTICATION_REQUIRED: // 407
8329646dec5SDamjan Jovanovic {
8339646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_HTTP_ERROR,
8349646dec5SDamjan Jovanovic reasonPhrase,
8359646dec5SDamjan Jovanovic statusCode );
8369646dec5SDamjan Jovanovic break;
8379646dec5SDamjan Jovanovic }
8389646dec5SDamjan Jovanovic case SC_REQUEST_ENTITY_TOO_LARGE: // 413
8399646dec5SDamjan Jovanovic {
8409646dec5SDamjan Jovanovic if ( m_bTransferEncodingSwitched )
8419646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_HTTP_ERROR,
8429646dec5SDamjan Jovanovic reasonPhrase,
8439646dec5SDamjan Jovanovic statusCode );
8449646dec5SDamjan Jovanovic m_bTransferEncodingSwitched = true;
8459646dec5SDamjan Jovanovic curlRequest.setChunkedEncoding( !curlRequest.isChunkedEncoding() );
8469646dec5SDamjan Jovanovic break;
8479646dec5SDamjan Jovanovic }
8489646dec5SDamjan Jovanovic case SC_LOCKED: // 423
8499646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_LOCKED,
8509646dec5SDamjan Jovanovic reasonPhrase,
8519646dec5SDamjan Jovanovic statusCode );
8529646dec5SDamjan Jovanovic default:
8539646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_HTTP_ERROR,
8549646dec5SDamjan Jovanovic reasonPhrase,
8559646dec5SDamjan Jovanovic statusCode );
8569646dec5SDamjan Jovanovic }
8579646dec5SDamjan Jovanovic }
8589646dec5SDamjan Jovanovic }
8599646dec5SDamjan Jovanovic
responseHeadersToDAVResource(const std::vector<CurlRequest::Header> & responseHeaders,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource)8609646dec5SDamjan Jovanovic static void responseHeadersToDAVResource( const std::vector< CurlRequest::Header> &responseHeaders,
8619646dec5SDamjan Jovanovic const std::vector< ::rtl::OUString > &inHeaderNames,
8629646dec5SDamjan Jovanovic DAVResource &ioResource )
8639646dec5SDamjan Jovanovic {
8649646dec5SDamjan Jovanovic std::vector< CurlRequest::Header >::const_iterator it( responseHeaders.begin() );
8659646dec5SDamjan Jovanovic const std::vector< CurlRequest::Header >::const_iterator end( responseHeaders.end() );
8669646dec5SDamjan Jovanovic while ( it != end )
8679646dec5SDamjan Jovanovic {
8689646dec5SDamjan Jovanovic bool storeHeader = false;
8699646dec5SDamjan Jovanovic if ( inHeaderNames.size() == 0 )
8709646dec5SDamjan Jovanovic storeHeader = true;
8719646dec5SDamjan Jovanovic else
8729646dec5SDamjan Jovanovic {
8739646dec5SDamjan Jovanovic std::vector< ::rtl::OUString >::const_iterator reqIt( inHeaderNames.begin() );
8749646dec5SDamjan Jovanovic const std::vector< ::rtl::OUString >::const_iterator reqEnd( inHeaderNames.end() );
8759646dec5SDamjan Jovanovic while ( reqIt != reqEnd )
8769646dec5SDamjan Jovanovic {
8779646dec5SDamjan Jovanovic // header names are case insensitive
8789646dec5SDamjan Jovanovic if ( (*reqIt).equalsIgnoreAsciiCase( rtl::OStringToOUString( (*it).name, RTL_TEXTENCODING_UTF8 ) ) )
8799646dec5SDamjan Jovanovic {
8809646dec5SDamjan Jovanovic storeHeader = true;
8819646dec5SDamjan Jovanovic break;
8829646dec5SDamjan Jovanovic }
8839646dec5SDamjan Jovanovic else
8849646dec5SDamjan Jovanovic {
8859646dec5SDamjan Jovanovic ++reqIt;
8869646dec5SDamjan Jovanovic }
8879646dec5SDamjan Jovanovic }
8889646dec5SDamjan Jovanovic }
8899646dec5SDamjan Jovanovic
8909646dec5SDamjan Jovanovic if ( storeHeader )
8919646dec5SDamjan Jovanovic {
8929646dec5SDamjan Jovanovic DAVPropertyValue thePropertyValue;
8939646dec5SDamjan Jovanovic thePropertyValue.IsCaseSensitive = false;
8949646dec5SDamjan Jovanovic thePropertyValue.Name = rtl::OStringToOUString( (*it).name, RTL_TEXTENCODING_UTF8 );
8959646dec5SDamjan Jovanovic thePropertyValue.Value <<= rtl::OStringToOUString( (*it).value, RTL_TEXTENCODING_UTF8 );
8969646dec5SDamjan Jovanovic ioResource.properties.push_back( thePropertyValue );
8979646dec5SDamjan Jovanovic }
8989646dec5SDamjan Jovanovic
8999646dec5SDamjan Jovanovic it++;
9009646dec5SDamjan Jovanovic }
9019646dec5SDamjan Jovanovic }
9029646dec5SDamjan Jovanovic
9039646dec5SDamjan Jovanovic // -------------------------------------------------------------------
9049646dec5SDamjan Jovanovic // PROPFIND - allprop & named
9059646dec5SDamjan Jovanovic // -------------------------------------------------------------------
9069646dec5SDamjan Jovanovic
propfind(CurlRequest & curlRequest,const rtl::OUString & inPath,const Depth inDepth,const std::vector<::rtl::OUString> * inPropNames,const bool onlyPropertyNames,const DAVRequestEnvironment & rEnv)9079646dec5SDamjan Jovanovic void CurlSession::propfind( CurlRequest &curlRequest,
9089646dec5SDamjan Jovanovic const rtl::OUString &inPath,
9099646dec5SDamjan Jovanovic const Depth inDepth,
9109646dec5SDamjan Jovanovic const std::vector< ::rtl::OUString > * inPropNames,
9119646dec5SDamjan Jovanovic const bool onlyPropertyNames,
9129646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
9139646dec5SDamjan Jovanovic {
9149646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
9159646dec5SDamjan Jovanovic
9169646dec5SDamjan Jovanovic if ( inDepth == DAVZERO )
9179646dec5SDamjan Jovanovic curlRequest.addHeader( "Depth", "0" );
9189646dec5SDamjan Jovanovic else if ( inDepth == DAVONE )
9199646dec5SDamjan Jovanovic curlRequest.addHeader( "Depth", "1" );
9209646dec5SDamjan Jovanovic else if ( inDepth == DAVINFINITY )
9219646dec5SDamjan Jovanovic curlRequest.addHeader( "Depth", "infinity" );
9229646dec5SDamjan Jovanovic
9239646dec5SDamjan Jovanovic rtl::OString xml = PropfindRequest::generatePROPFINDRequestBody( inPropNames, onlyPropertyNames );
9249646dec5SDamjan Jovanovic if ( xml.getLength() > 0 )
9259646dec5SDamjan Jovanovic {
9269646dec5SDamjan Jovanovic curlRequest.addHeader( "Content-Type", "application/xml" );
9279646dec5SDamjan Jovanovic curlRequest.setRequestBody( xml.getStr(), xml.getLength() );
9289646dec5SDamjan Jovanovic }
9299646dec5SDamjan Jovanovic
9309646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
9319646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
9329646dec5SDamjan Jovanovic
9339646dec5SDamjan Jovanovic CURLcode rc = curlRequest.propfind( m_aUri, inPath );
9349646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
9359646dec5SDamjan Jovanovic }
9369646dec5SDamjan Jovanovic
PROPFIND(const rtl::OUString & inPath,const Depth inDepth,const std::vector<rtl::OUString> & inPropNames,std::vector<DAVResource> & ioResources,const DAVRequestEnvironment & rEnv)9379646dec5SDamjan Jovanovic void CurlSession::PROPFIND( const rtl::OUString & inPath,
9389646dec5SDamjan Jovanovic const Depth inDepth,
9399646dec5SDamjan Jovanovic const std::vector< rtl::OUString > & inPropNames,
9409646dec5SDamjan Jovanovic std::vector< DAVResource > & ioResources,
9419646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
9429646dec5SDamjan Jovanovic throw ( DAVException )
9439646dec5SDamjan Jovanovic {
9449646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "PROPFIND line $1$", (sal_Int32)__LINE__ );
9459646dec5SDamjan Jovanovic
9469646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
9479646dec5SDamjan Jovanovic
9489646dec5SDamjan Jovanovic Init( rEnv );
9499646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
9509646dec5SDamjan Jovanovic
9519646dec5SDamjan Jovanovic propfind( curlRequest, inPath, inDepth, &inPropNames, false, rEnv );
9529646dec5SDamjan Jovanovic
9539646dec5SDamjan Jovanovic const std::vector< DAVResource > rResources( parseWebDAVPropFindResponse( curlRequest.getResponseBody().get() ) );
9549646dec5SDamjan Jovanovic std::vector< DAVResource > *pIoResources = &ioResources;
9559646dec5SDamjan Jovanovic *pIoResources = rResources;
9569646dec5SDamjan Jovanovic }
9579646dec5SDamjan Jovanovic
9589646dec5SDamjan Jovanovic // -------------------------------------------------------------------
9599646dec5SDamjan Jovanovic // PROPFIND - propnames
9609646dec5SDamjan Jovanovic // -------------------------------------------------------------------
PROPFIND(const rtl::OUString & inPath,const Depth inDepth,std::vector<DAVResourceInfo> & ioResInfo,const DAVRequestEnvironment & rEnv)9619646dec5SDamjan Jovanovic void CurlSession::PROPFIND( const rtl::OUString & inPath,
9629646dec5SDamjan Jovanovic const Depth inDepth,
9639646dec5SDamjan Jovanovic std::vector< DAVResourceInfo > & ioResInfo,
9649646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
9659646dec5SDamjan Jovanovic throw( DAVException )
9669646dec5SDamjan Jovanovic {
9679646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "PROPFIND line $1$", (sal_Int32)__LINE__ );
9689646dec5SDamjan Jovanovic
9699646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
9709646dec5SDamjan Jovanovic
9719646dec5SDamjan Jovanovic Init( rEnv );
9729646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
9739646dec5SDamjan Jovanovic
9749646dec5SDamjan Jovanovic propfind( curlRequest, inPath, inDepth, NULL, true, rEnv );
9759646dec5SDamjan Jovanovic
9769646dec5SDamjan Jovanovic const std::vector< DAVResourceInfo > rResInfo( parseWebDAVPropNameResponse( curlRequest.getResponseBody().get() ) );
9779646dec5SDamjan Jovanovic std::vector< DAVResourceInfo > *pIoResInfo = &ioResInfo;
9789646dec5SDamjan Jovanovic *pIoResInfo = rResInfo;
9799646dec5SDamjan Jovanovic }
9809646dec5SDamjan Jovanovic
9819646dec5SDamjan Jovanovic // -------------------------------------------------------------------
9829646dec5SDamjan Jovanovic // PROPPATCH
9839646dec5SDamjan Jovanovic // -------------------------------------------------------------------
PROPPATCH(const rtl::OUString & inPath,const std::vector<ProppatchValue> & inValues,const DAVRequestEnvironment & rEnv)9849646dec5SDamjan Jovanovic void CurlSession::PROPPATCH( const rtl::OUString & inPath,
9859646dec5SDamjan Jovanovic const std::vector< ProppatchValue > & inValues,
9869646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
9879646dec5SDamjan Jovanovic throw( DAVException )
9889646dec5SDamjan Jovanovic {
9899646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "PROPPATCH line $1$", (sal_Int32)__LINE__ );
9909646dec5SDamjan Jovanovic
9919646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
9929646dec5SDamjan Jovanovic
9939646dec5SDamjan Jovanovic Init( rEnv );
9949646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
9959646dec5SDamjan Jovanovic
9969646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
9979646dec5SDamjan Jovanovic
9989646dec5SDamjan Jovanovic // check whether a lock on this resource is already owned
9999646dec5SDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) );
10009646dec5SDamjan Jovanovic ucb::Lock inLock;
10019646dec5SDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
10029646dec5SDamjan Jovanovic if ( pLock )
10039646dec5SDamjan Jovanovic {
10049646dec5SDamjan Jovanovic inLock = pLock->getLock();
10059646dec5SDamjan Jovanovic }
10069646dec5SDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 )
10079646dec5SDamjan Jovanovic {
10089646dec5SDamjan Jovanovic curlRequest.addHeader( "If",
10099646dec5SDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
10109646dec5SDamjan Jovanovic }
10119646dec5SDamjan Jovanovic
10129646dec5SDamjan Jovanovic rtl::OString xml = ProppatchRequest::generatePROPPATCHRequestBody( inValues );
10139646dec5SDamjan Jovanovic if ( xml.getLength() > 0 )
10149646dec5SDamjan Jovanovic {
10159646dec5SDamjan Jovanovic curlRequest.addHeader( "Content-Type", "application/xml" );
10169646dec5SDamjan Jovanovic curlRequest.setRequestBody( xml.getStr(), xml.getLength() );
10179646dec5SDamjan Jovanovic }
10189646dec5SDamjan Jovanovic
10199646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
10209646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
10219646dec5SDamjan Jovanovic
10229646dec5SDamjan Jovanovic CURLcode rc = curlRequest.proppatch( m_aUri, inPath );
10239646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
10249646dec5SDamjan Jovanovic }
10259646dec5SDamjan Jovanovic
10269646dec5SDamjan Jovanovic // -------------------------------------------------------------------
10279646dec5SDamjan Jovanovic // HEAD
10289646dec5SDamjan Jovanovic // -------------------------------------------------------------------
HEAD(const::rtl::OUString & inPath,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource,const DAVRequestEnvironment & rEnv)10299646dec5SDamjan Jovanovic void CurlSession::HEAD( const ::rtl::OUString & inPath,
10309646dec5SDamjan Jovanovic const std::vector< ::rtl::OUString > & inHeaderNames,
10319646dec5SDamjan Jovanovic DAVResource & ioResource,
10329646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
10339646dec5SDamjan Jovanovic throw( DAVException )
10349646dec5SDamjan Jovanovic {
10359646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "HEAD line $1$", (sal_Int32)__LINE__ );
10369646dec5SDamjan Jovanovic
10379646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
10389646dec5SDamjan Jovanovic
10399646dec5SDamjan Jovanovic Init(rEnv );
10409646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
10419646dec5SDamjan Jovanovic
10429646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
10439646dec5SDamjan Jovanovic
10449646dec5SDamjan Jovanovic ioResource.uri = inPath;
10459646dec5SDamjan Jovanovic ioResource.properties.clear();
10469646dec5SDamjan Jovanovic
10479646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
10489646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
10499646dec5SDamjan Jovanovic
10509646dec5SDamjan Jovanovic CURLcode rc = curlRequest.head( m_aUri, inPath );
10519646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
10529646dec5SDamjan Jovanovic responseHeadersToDAVResource( curlRequest.getResponseHeaders(), inHeaderNames, ioResource );
10539646dec5SDamjan Jovanovic }
10549646dec5SDamjan Jovanovic
10559646dec5SDamjan Jovanovic // -------------------------------------------------------------------
10569646dec5SDamjan Jovanovic // GET
10579646dec5SDamjan Jovanovic // -------------------------------------------------------------------
10589646dec5SDamjan Jovanovic uno::Reference< io::XInputStream >
GET(const rtl::OUString & inPath,const DAVRequestEnvironment & rEnv)10599646dec5SDamjan Jovanovic CurlSession::GET( const rtl::OUString & inPath,
10609646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
10619646dec5SDamjan Jovanovic throw ( DAVException )
10629646dec5SDamjan Jovanovic {
10639646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ );
10649646dec5SDamjan Jovanovic
10659646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
10669646dec5SDamjan Jovanovic
10679646dec5SDamjan Jovanovic Init( rEnv );
10689646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
10699646dec5SDamjan Jovanovic
10709646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
10719646dec5SDamjan Jovanovic
10729646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
10739646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
10749646dec5SDamjan Jovanovic
10759646dec5SDamjan Jovanovic CURLcode rc = curlRequest.get( m_aUri, inPath );
10769646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
10779646dec5SDamjan Jovanovic
10789646dec5SDamjan Jovanovic return uno::Reference< io::XInputStream >( curlRequest.getResponseBody().get() );
10799646dec5SDamjan Jovanovic }
10809646dec5SDamjan Jovanovic
10819646dec5SDamjan Jovanovic // -------------------------------------------------------------------
10829646dec5SDamjan Jovanovic // GET
10839646dec5SDamjan Jovanovic // -------------------------------------------------------------------
GET(const rtl::OUString & inPath,uno::Reference<io::XOutputStream> & ioOutputStream,const DAVRequestEnvironment & rEnv)10849646dec5SDamjan Jovanovic void CurlSession::GET( const rtl::OUString & inPath,
10859646dec5SDamjan Jovanovic uno::Reference< io::XOutputStream > & ioOutputStream,
10869646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
10879646dec5SDamjan Jovanovic throw ( DAVException )
10889646dec5SDamjan Jovanovic {
10899646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ );
10909646dec5SDamjan Jovanovic
10919646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
10929646dec5SDamjan Jovanovic
10939646dec5SDamjan Jovanovic Init( rEnv );
10949646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
10959646dec5SDamjan Jovanovic
10969646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
10979646dec5SDamjan Jovanovic
10989646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
10999646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
11009646dec5SDamjan Jovanovic
11019646dec5SDamjan Jovanovic curlRequest.saveResponseBodyTo( ioOutputStream );
11029646dec5SDamjan Jovanovic CURLcode rc = curlRequest.get( m_aUri, inPath );
11039646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
11049646dec5SDamjan Jovanovic }
11059646dec5SDamjan Jovanovic
11069646dec5SDamjan Jovanovic // -------------------------------------------------------------------
11079646dec5SDamjan Jovanovic // GET
11089646dec5SDamjan Jovanovic // -------------------------------------------------------------------
11099646dec5SDamjan Jovanovic uno::Reference< io::XInputStream >
GET(const rtl::OUString & inPath,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource,const DAVRequestEnvironment & rEnv)11109646dec5SDamjan Jovanovic CurlSession::GET( const rtl::OUString & inPath,
11119646dec5SDamjan Jovanovic const std::vector< ::rtl::OUString > & inHeaderNames,
11129646dec5SDamjan Jovanovic DAVResource & ioResource,
11139646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
11149646dec5SDamjan Jovanovic throw ( DAVException )
11159646dec5SDamjan Jovanovic {
11169646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ );
11179646dec5SDamjan Jovanovic
11189646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
11199646dec5SDamjan Jovanovic
11209646dec5SDamjan Jovanovic Init( rEnv );
11219646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
11229646dec5SDamjan Jovanovic
11239646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
11249646dec5SDamjan Jovanovic
11259646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
11269646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
11279646dec5SDamjan Jovanovic
11289646dec5SDamjan Jovanovic CURLcode rc = curlRequest.get( m_aUri, inPath );
11299646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
11309646dec5SDamjan Jovanovic responseHeadersToDAVResource( curlRequest.getResponseHeaders(), inHeaderNames, ioResource );
11319646dec5SDamjan Jovanovic
11329646dec5SDamjan Jovanovic return uno::Reference< io::XInputStream >( curlRequest.getResponseBody().get() );
11339646dec5SDamjan Jovanovic }
11349646dec5SDamjan Jovanovic
11359646dec5SDamjan Jovanovic
11369646dec5SDamjan Jovanovic // -------------------------------------------------------------------
11379646dec5SDamjan Jovanovic // GET
11389646dec5SDamjan Jovanovic // -------------------------------------------------------------------
GET(const rtl::OUString & inPath,uno::Reference<io::XOutputStream> & ioOutputStream,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource,const DAVRequestEnvironment & rEnv)11399646dec5SDamjan Jovanovic void CurlSession::GET( const rtl::OUString & inPath,
11409646dec5SDamjan Jovanovic uno::Reference< io::XOutputStream > & ioOutputStream,
11419646dec5SDamjan Jovanovic const std::vector< ::rtl::OUString > & inHeaderNames,
11429646dec5SDamjan Jovanovic DAVResource & ioResource,
11439646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
11449646dec5SDamjan Jovanovic throw ( DAVException )
11459646dec5SDamjan Jovanovic {
11469646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "GET line $1$", (sal_Int32)__LINE__ );
11479646dec5SDamjan Jovanovic
11489646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
11499646dec5SDamjan Jovanovic
11509646dec5SDamjan Jovanovic Init( rEnv );
11519646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
11529646dec5SDamjan Jovanovic
11539646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
11549646dec5SDamjan Jovanovic
11559646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
11569646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
11579646dec5SDamjan Jovanovic
11589646dec5SDamjan Jovanovic curlRequest.saveResponseBodyTo( ioOutputStream );
11599646dec5SDamjan Jovanovic CURLcode rc = curlRequest.get( m_aUri, inPath );
11609646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
11619646dec5SDamjan Jovanovic responseHeadersToDAVResource( curlRequest.getResponseHeaders(), inHeaderNames, ioResource );
11629646dec5SDamjan Jovanovic }
11639646dec5SDamjan Jovanovic
11649646dec5SDamjan Jovanovic // -------------------------------------------------------------------
11659646dec5SDamjan Jovanovic // PUT
11669646dec5SDamjan Jovanovic // -------------------------------------------------------------------
PUT(const rtl::OUString & inPath,const uno::Reference<io::XInputStream> & inInputStream,const DAVRequestEnvironment & rEnv)11679646dec5SDamjan Jovanovic void CurlSession::PUT( const rtl::OUString & inPath,
11689646dec5SDamjan Jovanovic const uno::Reference< io::XInputStream > & inInputStream,
11699646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
11709646dec5SDamjan Jovanovic throw ( DAVException )
11719646dec5SDamjan Jovanovic {
11729646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "PUT line $1$", (sal_Int32)__LINE__ );
11739646dec5SDamjan Jovanovic
11749646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
11759646dec5SDamjan Jovanovic
11769646dec5SDamjan Jovanovic Init( rEnv );
11779646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
11789646dec5SDamjan Jovanovic
11799646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
11809646dec5SDamjan Jovanovic
11819646dec5SDamjan Jovanovic uno::Sequence< sal_Int8 > aDataToSend;
11829646dec5SDamjan Jovanovic if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
11839646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_INVALID_ARG );
11849646dec5SDamjan Jovanovic curlRequest.setRequestBody( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
11859646dec5SDamjan Jovanovic aDataToSend.getLength() );
11869646dec5SDamjan Jovanovic
11879646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
11889646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
11899646dec5SDamjan Jovanovic
11909646dec5SDamjan Jovanovic // check whether a lock on this resource is already owned
11919646dec5SDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) );
11929646dec5SDamjan Jovanovic ucb::Lock inLock;
11939646dec5SDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
11949646dec5SDamjan Jovanovic if ( pLock )
11959646dec5SDamjan Jovanovic {
11969646dec5SDamjan Jovanovic inLock = pLock->getLock();
11979646dec5SDamjan Jovanovic }
11989646dec5SDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 )
11999646dec5SDamjan Jovanovic {
12009646dec5SDamjan Jovanovic curlRequest.addHeader( "If",
12019646dec5SDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
12029646dec5SDamjan Jovanovic }
12039646dec5SDamjan Jovanovic
12049646dec5SDamjan Jovanovic CURLcode rc = curlRequest.put( m_aUri, inPath );
12059646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
12069646dec5SDamjan Jovanovic }
12079646dec5SDamjan Jovanovic
12089646dec5SDamjan Jovanovic // -------------------------------------------------------------------
12099646dec5SDamjan Jovanovic // POST
12109646dec5SDamjan Jovanovic // -------------------------------------------------------------------
12119646dec5SDamjan 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)12129646dec5SDamjan Jovanovic CurlSession::POST( const rtl::OUString & inPath,
12139646dec5SDamjan Jovanovic const rtl::OUString & rContentType,
12149646dec5SDamjan Jovanovic const rtl::OUString & rReferer,
12159646dec5SDamjan Jovanovic const uno::Reference< io::XInputStream > & inInputStream,
12169646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
12179646dec5SDamjan Jovanovic throw ( DAVException )
12189646dec5SDamjan Jovanovic {
12199646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "POST line $1$", (sal_Int32)__LINE__ );
12209646dec5SDamjan Jovanovic
12219646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
12229646dec5SDamjan Jovanovic
12239646dec5SDamjan Jovanovic Init( rEnv );
12249646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
12259646dec5SDamjan Jovanovic
12269646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
12279646dec5SDamjan Jovanovic
12289646dec5SDamjan Jovanovic uno::Sequence< sal_Int8 > aDataToSend;
12299646dec5SDamjan Jovanovic if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
12309646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_INVALID_ARG );
12319646dec5SDamjan Jovanovic curlRequest.setRequestBody( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
12329646dec5SDamjan Jovanovic aDataToSend.getLength() );
12339646dec5SDamjan Jovanovic
12349646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
12359646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
12369646dec5SDamjan Jovanovic
12379646dec5SDamjan Jovanovic if ( !rContentType.isEmpty() )
12389646dec5SDamjan Jovanovic curlRequest.addHeader( "Content-Type", rtl::OUStringToOString( rContentType, RTL_TEXTENCODING_UTF8 ).getStr() );
12399646dec5SDamjan Jovanovic if ( !rReferer.isEmpty() )
12409646dec5SDamjan Jovanovic curlRequest.addHeader( "Referer", rtl::OUStringToOString( rReferer, RTL_TEXTENCODING_UTF8 ).getStr() );
12419646dec5SDamjan Jovanovic
12429646dec5SDamjan Jovanovic // check whether a lock on this resource is already owned
12439646dec5SDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) );
12449646dec5SDamjan Jovanovic ucb::Lock inLock;
12459646dec5SDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
12469646dec5SDamjan Jovanovic if ( pLock )
12479646dec5SDamjan Jovanovic {
12489646dec5SDamjan Jovanovic inLock = pLock->getLock();
12499646dec5SDamjan Jovanovic }
12509646dec5SDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 )
12519646dec5SDamjan Jovanovic {
12529646dec5SDamjan Jovanovic curlRequest.addHeader( "If",
12539646dec5SDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
12549646dec5SDamjan Jovanovic }
12559646dec5SDamjan Jovanovic
12569646dec5SDamjan Jovanovic CURLcode rc = curlRequest.post( m_aUri, inPath );
12579646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
12589646dec5SDamjan Jovanovic return uno::Reference< io::XInputStream >( curlRequest.getResponseBody().get() );
12599646dec5SDamjan Jovanovic }
12609646dec5SDamjan Jovanovic
12619646dec5SDamjan Jovanovic // -------------------------------------------------------------------
12629646dec5SDamjan Jovanovic // POST
12639646dec5SDamjan 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)12649646dec5SDamjan Jovanovic void CurlSession::POST( const rtl::OUString & inPath,
12659646dec5SDamjan Jovanovic const rtl::OUString & rContentType,
12669646dec5SDamjan Jovanovic const rtl::OUString & rReferer,
12679646dec5SDamjan Jovanovic const uno::Reference< io::XInputStream > & inInputStream,
12689646dec5SDamjan Jovanovic uno::Reference< io::XOutputStream > & oOutputStream,
12699646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
12709646dec5SDamjan Jovanovic throw ( DAVException )
12719646dec5SDamjan Jovanovic {
12729646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "POST line $1$", (sal_Int32)__LINE__ );
12739646dec5SDamjan Jovanovic
12749646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
12759646dec5SDamjan Jovanovic
12769646dec5SDamjan Jovanovic Init( rEnv );
12779646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
12789646dec5SDamjan Jovanovic
12799646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
12809646dec5SDamjan Jovanovic
12819646dec5SDamjan Jovanovic uno::Sequence< sal_Int8 > aDataToSend;
12829646dec5SDamjan Jovanovic if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) )
12839646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_INVALID_ARG );
12849646dec5SDamjan Jovanovic curlRequest.setRequestBody( reinterpret_cast< const char * >( aDataToSend.getConstArray() ),
12859646dec5SDamjan Jovanovic aDataToSend.getLength() );
12869646dec5SDamjan Jovanovic
12879646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
12889646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
12899646dec5SDamjan Jovanovic
12909646dec5SDamjan Jovanovic if ( !rContentType.isEmpty() )
12919646dec5SDamjan Jovanovic curlRequest.addHeader( "Content-Type", rtl::OUStringToOString( rContentType, RTL_TEXTENCODING_UTF8 ).getStr() );
12929646dec5SDamjan Jovanovic if ( !rReferer.isEmpty() )
12939646dec5SDamjan Jovanovic curlRequest.addHeader( "Referer", rtl::OUStringToOString( rReferer, RTL_TEXTENCODING_UTF8 ).getStr() );
12949646dec5SDamjan Jovanovic
12959646dec5SDamjan Jovanovic // check whether a lock on this resource is already owned
12969646dec5SDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) );
12979646dec5SDamjan Jovanovic ucb::Lock inLock;
12989646dec5SDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
12999646dec5SDamjan Jovanovic if ( pLock )
13009646dec5SDamjan Jovanovic {
13019646dec5SDamjan Jovanovic inLock = pLock->getLock();
13029646dec5SDamjan Jovanovic }
13039646dec5SDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 )
13049646dec5SDamjan Jovanovic {
13059646dec5SDamjan Jovanovic curlRequest.addHeader( "If",
13069646dec5SDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
13079646dec5SDamjan Jovanovic }
13089646dec5SDamjan Jovanovic
13099646dec5SDamjan Jovanovic curlRequest.saveResponseBodyTo( oOutputStream );
13109646dec5SDamjan Jovanovic CURLcode rc = curlRequest.post( m_aUri, inPath );
13119646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
13129646dec5SDamjan Jovanovic }
13139646dec5SDamjan Jovanovic
13149646dec5SDamjan Jovanovic // -------------------------------------------------------------------
13159646dec5SDamjan Jovanovic // MKCOL
13169646dec5SDamjan Jovanovic // -------------------------------------------------------------------
MKCOL(const rtl::OUString & inPath,const DAVRequestEnvironment & rEnv)13179646dec5SDamjan Jovanovic void CurlSession::MKCOL( const rtl::OUString & inPath,
13189646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
13199646dec5SDamjan Jovanovic throw ( DAVException )
13209646dec5SDamjan Jovanovic {
13219646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "MKCOL line $1$", (sal_Int32)__LINE__ );
13229646dec5SDamjan Jovanovic
13239646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
13249646dec5SDamjan Jovanovic
13259646dec5SDamjan Jovanovic Init( rEnv );
13269646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
13279646dec5SDamjan Jovanovic
13289646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
13299646dec5SDamjan Jovanovic
13309646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
13319646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
13329646dec5SDamjan Jovanovic
13339646dec5SDamjan Jovanovic // check whether a lock on this resource is already owned
13349646dec5SDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) );
13359646dec5SDamjan Jovanovic ucb::Lock inLock;
13369646dec5SDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
13379646dec5SDamjan Jovanovic if ( pLock )
13389646dec5SDamjan Jovanovic {
13399646dec5SDamjan Jovanovic inLock = pLock->getLock();
13409646dec5SDamjan Jovanovic }
13419646dec5SDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 )
13429646dec5SDamjan Jovanovic {
13439646dec5SDamjan Jovanovic curlRequest.addHeader( "If",
13449646dec5SDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
13459646dec5SDamjan Jovanovic }
13469646dec5SDamjan Jovanovic
13479646dec5SDamjan Jovanovic CURLcode rc = curlRequest.mkcol( m_aUri, inPath );
13489646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
13499646dec5SDamjan Jovanovic }
13509646dec5SDamjan Jovanovic
13519646dec5SDamjan Jovanovic // -------------------------------------------------------------------
13529646dec5SDamjan Jovanovic // COPY
13539646dec5SDamjan Jovanovic // -------------------------------------------------------------------
COPY(const rtl::OUString & inSourceURL,const rtl::OUString & inDestinationURL,const DAVRequestEnvironment & rEnv,sal_Bool inOverWrite)13549646dec5SDamjan Jovanovic void CurlSession::COPY( const rtl::OUString & inSourceURL,
13559646dec5SDamjan Jovanovic const rtl::OUString & inDestinationURL,
13569646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv,
13579646dec5SDamjan Jovanovic sal_Bool inOverWrite )
13589646dec5SDamjan Jovanovic throw ( DAVException )
13599646dec5SDamjan Jovanovic {
13609646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "COPY line $1$", (sal_Int32)__LINE__ );
13619646dec5SDamjan Jovanovic
13629646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
13639646dec5SDamjan Jovanovic
13649646dec5SDamjan Jovanovic Init( rEnv );
13659646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
13669646dec5SDamjan Jovanovic
13679646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
13689646dec5SDamjan Jovanovic
13699646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
13709646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
13719646dec5SDamjan Jovanovic
13729646dec5SDamjan Jovanovic curlRequest.addHeader( "Destination", rtl::OUStringToOString( inDestinationURL, RTL_TEXTENCODING_UTF8 ).getStr() );
13739646dec5SDamjan Jovanovic curlRequest.addHeader( "Overwrite", inOverWrite? "T" : "F" );
13749646dec5SDamjan Jovanovic
13759646dec5SDamjan Jovanovic // check whether a lock on the destination resource is already owned
13769646dec5SDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inDestinationURL ) );
13779646dec5SDamjan Jovanovic ucb::Lock inLock;
13789646dec5SDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
13799646dec5SDamjan Jovanovic if ( pLock )
13809646dec5SDamjan Jovanovic {
13819646dec5SDamjan Jovanovic inLock = pLock->getLock();
13829646dec5SDamjan Jovanovic }
13839646dec5SDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 )
13849646dec5SDamjan Jovanovic {
13859646dec5SDamjan Jovanovic curlRequest.addHeader( "If",
13869646dec5SDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
13879646dec5SDamjan Jovanovic }
13889646dec5SDamjan Jovanovic
13899646dec5SDamjan Jovanovic CURLcode rc = curlRequest.copy( m_aUri, CurlUri( inSourceURL ).GetPath() );
13909646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
13919646dec5SDamjan Jovanovic }
13929646dec5SDamjan Jovanovic
13939646dec5SDamjan Jovanovic // -------------------------------------------------------------------
13949646dec5SDamjan Jovanovic // MOVE
13959646dec5SDamjan Jovanovic // -------------------------------------------------------------------
MOVE(const rtl::OUString & inSourceURL,const rtl::OUString & inDestinationURL,const DAVRequestEnvironment & rEnv,sal_Bool inOverWrite)13969646dec5SDamjan Jovanovic void CurlSession::MOVE( const rtl::OUString & inSourceURL,
13979646dec5SDamjan Jovanovic const rtl::OUString & inDestinationURL,
13989646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv,
13999646dec5SDamjan Jovanovic sal_Bool inOverWrite )
14009646dec5SDamjan Jovanovic throw ( DAVException )
14019646dec5SDamjan Jovanovic {
14029646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "MOVE line $1$", (sal_Int32)__LINE__ );
14039646dec5SDamjan Jovanovic
14049646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
14059646dec5SDamjan Jovanovic
14069646dec5SDamjan Jovanovic Init( rEnv );
14079646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
14089646dec5SDamjan Jovanovic
14099646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
14109646dec5SDamjan Jovanovic
14119646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
14129646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
14139646dec5SDamjan Jovanovic
14149646dec5SDamjan Jovanovic curlRequest.addHeader( "Destination", rtl::OUStringToOString( inDestinationURL, RTL_TEXTENCODING_UTF8 ).getStr() );
14159646dec5SDamjan Jovanovic curlRequest.addHeader( "Overwrite", inOverWrite? "T" : "F" );
14169646dec5SDamjan Jovanovic
14179646dec5SDamjan Jovanovic // check whether a lock on the destination resource is already owned
14189646dec5SDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inDestinationURL ) );
14199646dec5SDamjan Jovanovic ucb::Lock inLock;
14209646dec5SDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
14219646dec5SDamjan Jovanovic if ( pLock )
14229646dec5SDamjan Jovanovic {
14239646dec5SDamjan Jovanovic inLock = pLock->getLock();
14249646dec5SDamjan Jovanovic }
14259646dec5SDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 )
14269646dec5SDamjan Jovanovic {
14279646dec5SDamjan Jovanovic curlRequest.addHeader( "If",
14289646dec5SDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
14299646dec5SDamjan Jovanovic }
14309646dec5SDamjan Jovanovic
14319646dec5SDamjan Jovanovic CURLcode rc = curlRequest.copy( m_aUri, CurlUri( inSourceURL ).GetPath() );
14329646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
14339646dec5SDamjan Jovanovic }
14349646dec5SDamjan Jovanovic
14359646dec5SDamjan Jovanovic // -------------------------------------------------------------------
14369646dec5SDamjan Jovanovic // DESTROY
14379646dec5SDamjan Jovanovic // -------------------------------------------------------------------
DESTROY(const rtl::OUString & inPath,const DAVRequestEnvironment & rEnv)14389646dec5SDamjan Jovanovic void CurlSession::DESTROY( const rtl::OUString & inPath,
14399646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
14409646dec5SDamjan Jovanovic throw ( DAVException )
14419646dec5SDamjan Jovanovic {
14429646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "DESTROY line $1$", (sal_Int32)__LINE__ );
14439646dec5SDamjan Jovanovic
14449646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
14459646dec5SDamjan Jovanovic
14469646dec5SDamjan Jovanovic Init( rEnv );
14479646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
14489646dec5SDamjan Jovanovic
14499646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
14509646dec5SDamjan Jovanovic
14519646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
14529646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
14539646dec5SDamjan Jovanovic
14549646dec5SDamjan Jovanovic // check whether a lock on this resource is already owned
14559646dec5SDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) );
14569646dec5SDamjan Jovanovic ucb::Lock inLock;
14579646dec5SDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
14589646dec5SDamjan Jovanovic if ( pLock )
14599646dec5SDamjan Jovanovic {
14609646dec5SDamjan Jovanovic inLock = pLock->getLock();
14619646dec5SDamjan Jovanovic }
14629646dec5SDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 )
14639646dec5SDamjan Jovanovic {
14649646dec5SDamjan Jovanovic curlRequest.addHeader( "If",
14659646dec5SDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
14669646dec5SDamjan Jovanovic }
14679646dec5SDamjan Jovanovic
14689646dec5SDamjan Jovanovic CURLcode rc = curlRequest.delete_( m_aUri, inPath );
14699646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
14709646dec5SDamjan Jovanovic }
14719646dec5SDamjan Jovanovic
14729646dec5SDamjan Jovanovic // -------------------------------------------------------------------
14739646dec5SDamjan Jovanovic
14749646dec5SDamjan Jovanovic namespace
14759646dec5SDamjan Jovanovic {
lastChanceToSendRefreshRequest(TimeValue const & rStart,sal_Int32 timeout)14769646dec5SDamjan Jovanovic sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart,
14779646dec5SDamjan Jovanovic sal_Int32 timeout )
14789646dec5SDamjan Jovanovic {
14799646dec5SDamjan Jovanovic TimeValue aEnd;
14809646dec5SDamjan Jovanovic osl_getSystemTime( &aEnd );
14819646dec5SDamjan Jovanovic
14829646dec5SDamjan Jovanovic // Try to estimate a safe absolute time for sending the
14839646dec5SDamjan Jovanovic // lock refresh request.
14849646dec5SDamjan Jovanovic sal_Int32 lastChanceToSendRefreshRequest = DAVINFINITY;
14859646dec5SDamjan Jovanovic if ( timeout != DAVINFINITY )
14869646dec5SDamjan Jovanovic {
14879646dec5SDamjan Jovanovic sal_Int32 calltime = aEnd.Seconds - rStart.Seconds;
14889646dec5SDamjan Jovanovic if ( calltime <= timeout )
14899646dec5SDamjan Jovanovic {
14909646dec5SDamjan Jovanovic lastChanceToSendRefreshRequest
14919646dec5SDamjan Jovanovic = aEnd.Seconds + timeout - calltime;
14929646dec5SDamjan Jovanovic }
14939646dec5SDamjan Jovanovic else
14949646dec5SDamjan Jovanovic {
14959646dec5SDamjan Jovanovic OSL_TRACE( "No chance to refresh lock before timeout!" );
14969646dec5SDamjan Jovanovic }
14979646dec5SDamjan Jovanovic }
14989646dec5SDamjan Jovanovic return lastChanceToSendRefreshRequest;
14999646dec5SDamjan Jovanovic }
15009646dec5SDamjan Jovanovic
15019646dec5SDamjan Jovanovic } // namespace
15029646dec5SDamjan Jovanovic
15039646dec5SDamjan Jovanovic // -------------------------------------------------------------------
15049646dec5SDamjan Jovanovic // LOCK (set new lock)
15059646dec5SDamjan Jovanovic // -------------------------------------------------------------------
LOCK(const::rtl::OUString & inPath,ucb::Lock & inLock,const DAVRequestEnvironment & rEnv)15069646dec5SDamjan Jovanovic void CurlSession::LOCK( const ::rtl::OUString & inPath,
15079646dec5SDamjan Jovanovic ucb::Lock & inLock,
15089646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
15099646dec5SDamjan Jovanovic throw ( DAVException )
15109646dec5SDamjan Jovanovic {
15119646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "LOCK line $1$", (sal_Int32)__LINE__ );
15129646dec5SDamjan Jovanovic
15139646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
15149646dec5SDamjan Jovanovic
15159646dec5SDamjan Jovanovic // before locking, search in the lock store if we already own a lock for this resource
15169646dec5SDamjan Jovanovic // if present, return with exception DAV_LOCKED_SELF
15179646dec5SDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) );
15189646dec5SDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
15199646dec5SDamjan Jovanovic if ( pLock )
15209646dec5SDamjan Jovanovic {
15219646dec5SDamjan Jovanovic // already present, meaning already locked by the same AOO session and already in the lockstore
15229646dec5SDamjan Jovanovic // just return, nothing to do
15239646dec5SDamjan Jovanovic return;
15249646dec5SDamjan Jovanovic }
15259646dec5SDamjan Jovanovic
15269646dec5SDamjan Jovanovic Init( rEnv );
15279646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
15289646dec5SDamjan Jovanovic
15299646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
15309646dec5SDamjan Jovanovic
15319646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
15329646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
15339646dec5SDamjan Jovanovic
15349646dec5SDamjan Jovanovic if ( inLock.Timeout == -1 )
15359646dec5SDamjan Jovanovic curlRequest.addHeader( "Timeout", "Infinite" );
15369646dec5SDamjan Jovanovic else
15379646dec5SDamjan Jovanovic curlRequest.addHeader( "Timeout", "Second-" + rtl::OString::valueOf( inLock.Timeout ) );
15389646dec5SDamjan Jovanovic
15399646dec5SDamjan Jovanovic switch ( inLock.Depth )
15409646dec5SDamjan Jovanovic {
15419646dec5SDamjan Jovanovic //i126305 TODO investigate on this case...
15429646dec5SDamjan Jovanovic case ucb::LockDepth_MAKE_FIXED_SIZE:
15439646dec5SDamjan Jovanovic
15449646dec5SDamjan Jovanovic case ucb::LockDepth_ZERO:
15459646dec5SDamjan Jovanovic curlRequest.addHeader( "Depth", "0" );
15469646dec5SDamjan Jovanovic break;
15479646dec5SDamjan Jovanovic case ucb::LockDepth_ONE:
15489646dec5SDamjan Jovanovic curlRequest.addHeader( "Depth", "1" );
15499646dec5SDamjan Jovanovic break;
15509646dec5SDamjan Jovanovic case ucb::LockDepth_INFINITY:
15519646dec5SDamjan Jovanovic curlRequest.addHeader( "Depth", "infinity" );
15529646dec5SDamjan Jovanovic break;
15539646dec5SDamjan Jovanovic }
15549646dec5SDamjan Jovanovic
15559646dec5SDamjan Jovanovic rtl::OString xml = LockRequest::generateRequestBody( inLock );
15569646dec5SDamjan Jovanovic curlRequest.addHeader( "Content-Type", "application/xml" );
15579646dec5SDamjan Jovanovic curlRequest.setRequestBody( xml.getStr(), xml.getLength() );
15589646dec5SDamjan Jovanovic
15599646dec5SDamjan Jovanovic TimeValue startCall;
15609646dec5SDamjan Jovanovic osl_getSystemTime( &startCall );
15619646dec5SDamjan Jovanovic
15629646dec5SDamjan Jovanovic CURLcode rc = curlRequest.lock( m_aUri, inPath );
15639646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
15649646dec5SDamjan Jovanovic
15659646dec5SDamjan Jovanovic // the returned property, a sequence of locks
15669646dec5SDamjan Jovanovic // only the first is used
15679646dec5SDamjan Jovanovic const DAVPropertyValue outLock( parseWebDAVLockResponse( curlRequest.getResponseBody().get() ) );
15689646dec5SDamjan Jovanovic if(outLock.Name.compareToAscii(RTL_CONSTASCII_STRINGPARAM( "DAV:lockdiscovery" )) == 0 )
15699646dec5SDamjan Jovanovic {
15709646dec5SDamjan Jovanovic // got a lock, use only the first returned
15719646dec5SDamjan Jovanovic uno::Sequence< ucb::Lock > aLocks;
15729646dec5SDamjan Jovanovic outLock.Value >>= aLocks;
15739646dec5SDamjan Jovanovic ucb::Lock aLock = aLocks[0];
15749646dec5SDamjan Jovanovic
15759646dec5SDamjan Jovanovic CurlLock* aNewLock = new CurlLock( aLock, aUri, inPath );
15769646dec5SDamjan Jovanovic // add the store the new lock
15779646dec5SDamjan Jovanovic m_aCurlLockStore.addLock(aNewLock,this,
15789646dec5SDamjan Jovanovic lastChanceToSendRefreshRequest(
15799646dec5SDamjan Jovanovic startCall, static_cast< sal_Int32 >(aLock.Timeout) ) );
15809646dec5SDamjan Jovanovic }
15819646dec5SDamjan Jovanovic }
15829646dec5SDamjan Jovanovic
15839646dec5SDamjan Jovanovic // -------------------------------------------------------------------
15849646dec5SDamjan Jovanovic // LOCK (refresh existing lock from DAVResourceAccess)
15859646dec5SDamjan Jovanovic // -------------------------------------------------------------------
LOCK(const::rtl::OUString &,sal_Int64 nTimeout,const DAVRequestEnvironment &)15869646dec5SDamjan Jovanovic sal_Int64 CurlSession::LOCK( const ::rtl::OUString & /*inPath*/,
15879646dec5SDamjan Jovanovic sal_Int64 nTimeout,
15889646dec5SDamjan Jovanovic const DAVRequestEnvironment & /*rEnv*/ )
15899646dec5SDamjan Jovanovic throw ( DAVException )
15909646dec5SDamjan Jovanovic {
15919646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "LOCK line $1$", (sal_Int32)__LINE__ );
15929646dec5SDamjan Jovanovic
15939646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
15949646dec5SDamjan Jovanovic
15959646dec5SDamjan Jovanovic return nTimeout;
15969646dec5SDamjan Jovanovic /*
15979646dec5SDamjan Jovanovic // Try to get the neon lock from lock store
15989646dec5SDamjan Jovanovic CurlLock * theLock
15999646dec5SDamjan Jovanovic = m_aCurlLockStore.findByUri( makeAbsoluteURL( inPath ) );
16009646dec5SDamjan Jovanovic if ( !theLock )
16019646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_NOT_LOCKED );
16029646dec5SDamjan Jovanovic
16039646dec5SDamjan Jovanovic Init( rEnv );
16049646dec5SDamjan Jovanovic
16059646dec5SDamjan Jovanovic // refresh existing lock.
16069646dec5SDamjan Jovanovic theLock->timeout = static_cast< long >( nTimeout );
16079646dec5SDamjan Jovanovic
16089646dec5SDamjan Jovanovic TimeValue startCall;
16099646dec5SDamjan Jovanovic osl_getSystemTime( &startCall );
16109646dec5SDamjan Jovanovic
16119646dec5SDamjan Jovanovic int theRetVal = ne_lock_refresh( m_pHttpSession, theLock );
16129646dec5SDamjan Jovanovic
16139646dec5SDamjan Jovanovic if ( theRetVal == NE_OK )
16149646dec5SDamjan Jovanovic {
16159646dec5SDamjan Jovanovic m_aCurlLockStore.updateLock( theLock,
16169646dec5SDamjan Jovanovic lastChanceToSendRefreshRequest(
16179646dec5SDamjan Jovanovic startCall, theLock->timeout ) );
16189646dec5SDamjan Jovanovic }
16199646dec5SDamjan Jovanovic
16209646dec5SDamjan Jovanovic HandleError( theRetVal, inPath, rEnv );
16219646dec5SDamjan Jovanovic
16229646dec5SDamjan Jovanovic return theLock->timeout;
16239646dec5SDamjan Jovanovic */
16249646dec5SDamjan Jovanovic }
16259646dec5SDamjan Jovanovic
16269646dec5SDamjan Jovanovic // -------------------------------------------------------------------
16279646dec5SDamjan Jovanovic // LOCK (refresh existing lock from CurlLockStore)
16289646dec5SDamjan Jovanovic // -------------------------------------------------------------------
LOCK(CurlLock * pLock,sal_Int32 & rlastChanceToSendRefreshRequest)16299646dec5SDamjan Jovanovic bool CurlSession::LOCK( CurlLock * pLock,
16309646dec5SDamjan Jovanovic sal_Int32 & rlastChanceToSendRefreshRequest )
16319646dec5SDamjan Jovanovic {
16329646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "LOCK line $1$", (sal_Int32)__LINE__ );
16339646dec5SDamjan Jovanovic
16349646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
16359646dec5SDamjan Jovanovic
16369646dec5SDamjan Jovanovic Init();
16379646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
16389646dec5SDamjan Jovanovic
16399646dec5SDamjan Jovanovic const ucb::Lock & inLock = pLock->getLock();
16409646dec5SDamjan Jovanovic rtl::OUString inPath = pLock->getResourcePath();
16419646dec5SDamjan Jovanovic
16429646dec5SDamjan Jovanovic if ( inLock.Timeout == -1 )
16439646dec5SDamjan Jovanovic curlRequest.addHeader( "Timeout", "Infinite" );
16449646dec5SDamjan Jovanovic else
16459646dec5SDamjan Jovanovic curlRequest.addHeader( "Timeout", "Second-" + rtl::OString::valueOf( inLock.Timeout ) );
16469646dec5SDamjan Jovanovic
16479646dec5SDamjan Jovanovic switch ( inLock.Depth )
16489646dec5SDamjan Jovanovic {
16499646dec5SDamjan Jovanovic //i126305 TODO investigate on this case...
16509646dec5SDamjan Jovanovic case ucb::LockDepth_MAKE_FIXED_SIZE:
16519646dec5SDamjan Jovanovic
16529646dec5SDamjan Jovanovic case ucb::LockDepth_ZERO:
16539646dec5SDamjan Jovanovic curlRequest.addHeader( "Depth", "0" );
16549646dec5SDamjan Jovanovic break;
16559646dec5SDamjan Jovanovic case ucb::LockDepth_ONE:
16569646dec5SDamjan Jovanovic curlRequest.addHeader( "Depth", "1" );
16579646dec5SDamjan Jovanovic break;
16589646dec5SDamjan Jovanovic case ucb::LockDepth_INFINITY:
16599646dec5SDamjan Jovanovic curlRequest.addHeader( "Depth", "infinity" );
16609646dec5SDamjan Jovanovic break;
16619646dec5SDamjan Jovanovic }
16629646dec5SDamjan Jovanovic
16639646dec5SDamjan Jovanovic if ( inLock.LockTokens.getLength() > 0 )
16649646dec5SDamjan Jovanovic {
16659646dec5SDamjan Jovanovic curlRequest.addHeader( "If",
16669646dec5SDamjan Jovanovic ( "(<" + rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">)" ).getStr() );
16679646dec5SDamjan Jovanovic }
16689646dec5SDamjan Jovanovic
16699646dec5SDamjan Jovanovic rtl::OString xml = LockRequest::generateRequestBody( inLock );
16709646dec5SDamjan Jovanovic curlRequest.addHeader( "Content-Type", "application/xml" );
16719646dec5SDamjan Jovanovic curlRequest.setRequestBody( xml.getStr(), xml.getLength() );
16729646dec5SDamjan Jovanovic
16739646dec5SDamjan Jovanovic TimeValue startCall;
16749646dec5SDamjan Jovanovic osl_getSystemTime( &startCall );
16759646dec5SDamjan Jovanovic
16769646dec5SDamjan Jovanovic CURLcode rc = curlRequest.lock( m_aUri, inPath );
16779646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
16789646dec5SDamjan Jovanovic
16799646dec5SDamjan Jovanovic // the returned property, a sequence of locks
16809646dec5SDamjan Jovanovic // only the first is used
16819646dec5SDamjan Jovanovic const DAVPropertyValue outLock( parseWebDAVLockResponse( curlRequest.getResponseBody().get() ) );
16829646dec5SDamjan Jovanovic uno::Sequence< ucb::Lock > aLocks;
16839646dec5SDamjan Jovanovic outLock.Value >>= aLocks;
16849646dec5SDamjan Jovanovic ucb::Lock aLock = aLocks[0];
16859646dec5SDamjan Jovanovic
16869646dec5SDamjan Jovanovic // if ok, update the lastchance refresh time in lock
16879646dec5SDamjan Jovanovic rlastChanceToSendRefreshRequest
16889646dec5SDamjan Jovanovic = lastChanceToSendRefreshRequest( startCall, static_cast< sal_Int32 >(aLock.Timeout) );
16899646dec5SDamjan Jovanovic
16909646dec5SDamjan Jovanovic return true;
16919646dec5SDamjan Jovanovic }
16929646dec5SDamjan Jovanovic
16939646dec5SDamjan Jovanovic // -------------------------------------------------------------------
16949646dec5SDamjan Jovanovic // UNLOCK called from external (DAVResourceAccess)
16959646dec5SDamjan Jovanovic // -------------------------------------------------------------------
UNLOCK(const::rtl::OUString & inPath,const DAVRequestEnvironment & rEnv)16969646dec5SDamjan Jovanovic void CurlSession::UNLOCK( const ::rtl::OUString & inPath,
16979646dec5SDamjan Jovanovic const DAVRequestEnvironment & rEnv )
16989646dec5SDamjan Jovanovic throw ( DAVException )
16999646dec5SDamjan Jovanovic {
17009646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "UNLOCK line $1$", (sal_Int32)__LINE__ );
17019646dec5SDamjan Jovanovic
17029646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
17039646dec5SDamjan Jovanovic
17049646dec5SDamjan Jovanovic rtl::OUString aUri( composeCurrentUri( inPath ) );
17059646dec5SDamjan Jovanovic CurlLock * pLock = m_aCurlLockStore.findByUri( aUri );
17069646dec5SDamjan Jovanovic if ( !pLock )
17079646dec5SDamjan Jovanovic {
17089646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_NOT_LOCKED );
17099646dec5SDamjan Jovanovic }
17109646dec5SDamjan Jovanovic
17119646dec5SDamjan Jovanovic Init( rEnv );
17129646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
17139646dec5SDamjan Jovanovic
17149646dec5SDamjan Jovanovic addEnvironmentRequestHeaders( curlRequest, rEnv );
17159646dec5SDamjan Jovanovic
17169646dec5SDamjan Jovanovic CredentialsData credsData( this, curlRequest, rEnv );
17179646dec5SDamjan Jovanovic curlRequest.setProvideCredentialsCallback( Curl_ProvideCredentials, &credsData );
17189646dec5SDamjan Jovanovic
17199646dec5SDamjan Jovanovic ucb::Lock inLock = pLock->getLock();
17209646dec5SDamjan Jovanovic curlRequest.addHeader( "Lock-Token",
17219646dec5SDamjan Jovanovic ( "<" + rtl::OUStringToOString( inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">" ).getStr() );
17229646dec5SDamjan Jovanovic
17239646dec5SDamjan Jovanovic // remove lock from lockstore
17249646dec5SDamjan Jovanovic // so, if something goes wrong, we don't refresh it anymore
17259646dec5SDamjan Jovanovic m_aCurlLockStore.removeLock( pLock );
17269646dec5SDamjan Jovanovic delete pLock;
17279646dec5SDamjan Jovanovic
17289646dec5SDamjan Jovanovic CURLcode rc = curlRequest.unlock( m_aUri, inPath );
17299646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
17309646dec5SDamjan Jovanovic }
17319646dec5SDamjan Jovanovic
17329646dec5SDamjan Jovanovic // -------------------------------------------------------------------
17339646dec5SDamjan Jovanovic // UNLOCK (called from CurlLockStore)
17349646dec5SDamjan Jovanovic // -------------------------------------------------------------------
UNLOCK(CurlLock * pLock)17359646dec5SDamjan Jovanovic bool CurlSession::UNLOCK( CurlLock * pLock )
17369646dec5SDamjan Jovanovic {
17379646dec5SDamjan Jovanovic m_aLogger.log( LogLevel::INFO, "UNLOCK line $1$", (sal_Int32)__LINE__ );
17389646dec5SDamjan Jovanovic
17399646dec5SDamjan Jovanovic osl::Guard< osl::Mutex > theGuard( m_aMutex );
17409646dec5SDamjan Jovanovic
17419646dec5SDamjan Jovanovic Init();
17429646dec5SDamjan Jovanovic CurlRequest curlRequest( m_pCurl );
17439646dec5SDamjan Jovanovic
17449646dec5SDamjan Jovanovic rtl::OUString inPath = pLock->getResourcePath();
17459646dec5SDamjan Jovanovic ucb::Lock inLock = pLock->getLock();
17469646dec5SDamjan Jovanovic curlRequest.addHeader( "Lock-Token",
17479646dec5SDamjan Jovanovic ( "<" + rtl::OUStringToOString( inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ) + ">" ).getStr() );
17489646dec5SDamjan Jovanovic
17499646dec5SDamjan Jovanovic CURLcode rc = curlRequest.unlock( m_aUri, inPath );
17509646dec5SDamjan Jovanovic processResponse( curlRequest, rc );
17519646dec5SDamjan Jovanovic return true;
17529646dec5SDamjan Jovanovic }
17539646dec5SDamjan Jovanovic
17549646dec5SDamjan Jovanovic // -------------------------------------------------------------------
abort()17559646dec5SDamjan Jovanovic void CurlSession::abort()
17569646dec5SDamjan Jovanovic throw ( DAVException )
17579646dec5SDamjan Jovanovic {
17589646dec5SDamjan Jovanovic // 11.11.09 (tkr): The following code lines causing crashes if
17599646dec5SDamjan Jovanovic // closing a ongoing connection. It turned out that this existing
17609646dec5SDamjan Jovanovic // solution doesn't work in multi-threading environments.
17619646dec5SDamjan Jovanovic // So I disabled them in 3.2. . Issue #73893# should fix it in OOo 3.3.
17629646dec5SDamjan Jovanovic //if ( m_pHttpSession )
17639646dec5SDamjan Jovanovic // ne_close_connection( m_pHttpSession );
17649646dec5SDamjan Jovanovic }
17659646dec5SDamjan Jovanovic
17669646dec5SDamjan Jovanovic // -------------------------------------------------------------------
getProxySettings() const17679646dec5SDamjan Jovanovic const ucbhelper::InternetProxyServer & CurlSession::getProxySettings() const
17689646dec5SDamjan Jovanovic {
17699646dec5SDamjan Jovanovic if ( m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) ) ||
17709646dec5SDamjan Jovanovic m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) ) )
17719646dec5SDamjan Jovanovic {
17729646dec5SDamjan Jovanovic return m_rProxyDecider.getProxy( m_aUri.GetScheme(),
17739646dec5SDamjan Jovanovic m_aUri.GetHost(),
17749646dec5SDamjan Jovanovic m_aUri.GetPort() );
17759646dec5SDamjan Jovanovic }
17769646dec5SDamjan Jovanovic else
17779646dec5SDamjan Jovanovic {
17789646dec5SDamjan Jovanovic // TODO: figure out, if this case can occur
17799646dec5SDamjan Jovanovic return m_rProxyDecider.getProxy( m_aUri.GetScheme(),
17809646dec5SDamjan Jovanovic rtl::OUString() /* not used */,
17819646dec5SDamjan Jovanovic -1 /* not used */ );
17829646dec5SDamjan Jovanovic }
17839646dec5SDamjan Jovanovic }
17849646dec5SDamjan Jovanovic
17859646dec5SDamjan Jovanovic /*
17869646dec5SDamjan Jovanovic // -------------------------------------------------------------------
17879646dec5SDamjan Jovanovic namespace {
17889646dec5SDamjan Jovanovic
17899646dec5SDamjan Jovanovic bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks,
17909646dec5SDamjan Jovanovic const char * token )
17919646dec5SDamjan Jovanovic {
17929646dec5SDamjan Jovanovic for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n )
17939646dec5SDamjan Jovanovic {
17949646dec5SDamjan Jovanovic const uno::Sequence< rtl::OUString > & rTokens
17959646dec5SDamjan Jovanovic = rLocks[ n ].LockTokens;
17969646dec5SDamjan Jovanovic for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m )
17979646dec5SDamjan Jovanovic {
17989646dec5SDamjan Jovanovic if ( rTokens[ m ].equalsAscii( token ) )
17999646dec5SDamjan Jovanovic return true;
18009646dec5SDamjan Jovanovic }
18019646dec5SDamjan Jovanovic }
18029646dec5SDamjan Jovanovic return false;
18039646dec5SDamjan Jovanovic }
18049646dec5SDamjan Jovanovic
18059646dec5SDamjan Jovanovic } // namespace
18069646dec5SDamjan Jovanovic */
18079646dec5SDamjan Jovanovic
18089646dec5SDamjan Jovanovic // -------------------------------------------------------------------
18099646dec5SDamjan Jovanovic // This method doesn't seem to be used.
18109646dec5SDamjan Jovanovic // In any case the default behavior is to ask a lock with a life of 3 minutes
18119646dec5SDamjan Jovanovic // it will then be refreshed automatically (see CurlLockStore class)
18129646dec5SDamjan Jovanovic // In case of AOO crash the lock will expire by itself
removeExpiredLocktoken(const rtl::OUString &,const DAVRequestEnvironment &)18139646dec5SDamjan Jovanovic bool CurlSession::removeExpiredLocktoken( const rtl::OUString & /*inURL*/,
18149646dec5SDamjan Jovanovic const DAVRequestEnvironment & /*rEnv*/ )
18159646dec5SDamjan Jovanovic {
18169646dec5SDamjan Jovanovic return true;
18179646dec5SDamjan Jovanovic /*
18189646dec5SDamjan Jovanovic CurlLock * theLock = m_aCurlLockStore.findByUri( inURL );
18199646dec5SDamjan Jovanovic if ( !theLock )
18209646dec5SDamjan Jovanovic return false;
18219646dec5SDamjan Jovanovic
18229646dec5SDamjan Jovanovic // do a lockdiscovery to check whether this lock is still valid.
18239646dec5SDamjan Jovanovic try
18249646dec5SDamjan Jovanovic {
18259646dec5SDamjan Jovanovic // @@@ Alternative: use ne_lock_discover() => less overhead
18269646dec5SDamjan Jovanovic
18279646dec5SDamjan Jovanovic std::vector< DAVResource > aResources;
18289646dec5SDamjan Jovanovic std::vector< rtl::OUString > aPropNames;
18299646dec5SDamjan Jovanovic aPropNames.push_back( DAVProperties::LOCKDISCOVERY );
18309646dec5SDamjan Jovanovic
18319646dec5SDamjan Jovanovic PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv );
18329646dec5SDamjan Jovanovic
18339646dec5SDamjan Jovanovic if ( aResources.size() == 0 )
18349646dec5SDamjan Jovanovic return false;
18359646dec5SDamjan Jovanovic
18369646dec5SDamjan Jovanovic std::vector< DAVPropertyValue >::const_iterator it
18379646dec5SDamjan Jovanovic = aResources[ 0 ].properties.begin();
18389646dec5SDamjan Jovanovic std::vector< DAVPropertyValue >::const_iterator end
18399646dec5SDamjan Jovanovic = aResources[ 0 ].properties.end();
18409646dec5SDamjan Jovanovic
18419646dec5SDamjan Jovanovic while ( it != end )
18429646dec5SDamjan Jovanovic {
18439646dec5SDamjan Jovanovic if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) )
18449646dec5SDamjan Jovanovic {
18459646dec5SDamjan Jovanovic uno::Sequence< ucb::Lock > aLocks;
18469646dec5SDamjan Jovanovic if ( !( (*it).Value >>= aLocks ) )
18479646dec5SDamjan Jovanovic return false;
18489646dec5SDamjan Jovanovic
18499646dec5SDamjan Jovanovic if ( !containsLocktoken( aLocks, theLock->token ) )
18509646dec5SDamjan Jovanovic {
18519646dec5SDamjan Jovanovic // expired!
18529646dec5SDamjan Jovanovic break;
18539646dec5SDamjan Jovanovic }
18549646dec5SDamjan Jovanovic
18559646dec5SDamjan Jovanovic // still valid.
18569646dec5SDamjan Jovanovic return false;
18579646dec5SDamjan Jovanovic }
18589646dec5SDamjan Jovanovic ++it;
18599646dec5SDamjan Jovanovic }
18609646dec5SDamjan Jovanovic
18619646dec5SDamjan Jovanovic // No lockdiscovery prop in propfind result / locktoken not found
18629646dec5SDamjan Jovanovic // in propfind result -> not locked
18639646dec5SDamjan Jovanovic OSL_TRACE( "CurlSession::removeExpiredLocktoken: Removing "
18649646dec5SDamjan Jovanovic " expired lock token for %s. token: %s",
18659646dec5SDamjan Jovanovic rtl::OUStringToOString( inURL,
18669646dec5SDamjan Jovanovic RTL_TEXTENCODING_UTF8 ).getStr(),
18679646dec5SDamjan Jovanovic theLock->token );
18689646dec5SDamjan Jovanovic
18699646dec5SDamjan Jovanovic m_aCurlLockStore.removeLock( theLock );
18709646dec5SDamjan Jovanovic ne_lock_destroy( theLock );
18719646dec5SDamjan Jovanovic return true;
18729646dec5SDamjan Jovanovic }
18739646dec5SDamjan Jovanovic catch ( DAVException const & )
18749646dec5SDamjan Jovanovic {
18759646dec5SDamjan Jovanovic }
18769646dec5SDamjan Jovanovic return false;
18779646dec5SDamjan Jovanovic */
18789646dec5SDamjan Jovanovic }
18799646dec5SDamjan Jovanovic
18809646dec5SDamjan Jovanovic // -------------------------------------------------------------------
18819646dec5SDamjan Jovanovic // static
18829646dec5SDamjan Jovanovic bool
getDataFromInputStream(const uno::Reference<io::XInputStream> & xStream,uno::Sequence<sal_Int8> & rData,bool bAppendTrailingZeroByte)18839646dec5SDamjan Jovanovic CurlSession::getDataFromInputStream(
18849646dec5SDamjan Jovanovic const uno::Reference< io::XInputStream > & xStream,
18859646dec5SDamjan Jovanovic uno::Sequence< sal_Int8 > & rData,
18869646dec5SDamjan Jovanovic bool bAppendTrailingZeroByte )
18879646dec5SDamjan Jovanovic {
18889646dec5SDamjan Jovanovic if ( xStream.is() )
18899646dec5SDamjan Jovanovic {
18909646dec5SDamjan Jovanovic uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY );
18919646dec5SDamjan Jovanovic if ( xSeekable.is() )
18929646dec5SDamjan Jovanovic {
18939646dec5SDamjan Jovanovic try
18949646dec5SDamjan Jovanovic {
18959646dec5SDamjan Jovanovic sal_Int32 nSize
18969646dec5SDamjan Jovanovic = sal::static_int_cast<sal_Int32>(xSeekable->getLength());
18979646dec5SDamjan Jovanovic sal_Int32 nRead
18989646dec5SDamjan Jovanovic = xStream->readBytes( rData, nSize );
18999646dec5SDamjan Jovanovic
19009646dec5SDamjan Jovanovic if ( nRead == nSize )
19019646dec5SDamjan Jovanovic {
19029646dec5SDamjan Jovanovic if ( bAppendTrailingZeroByte )
19039646dec5SDamjan Jovanovic {
19049646dec5SDamjan Jovanovic rData.realloc( nSize + 1 );
19059646dec5SDamjan Jovanovic rData[ nSize ] = sal_Int8( 0 );
19069646dec5SDamjan Jovanovic }
19079646dec5SDamjan Jovanovic return true;
19089646dec5SDamjan Jovanovic }
19099646dec5SDamjan Jovanovic }
19109646dec5SDamjan Jovanovic catch ( io::NotConnectedException const & )
19119646dec5SDamjan Jovanovic {
19129646dec5SDamjan Jovanovic // readBytes
19139646dec5SDamjan Jovanovic }
19149646dec5SDamjan Jovanovic catch ( io::BufferSizeExceededException const & )
19159646dec5SDamjan Jovanovic {
19169646dec5SDamjan Jovanovic // readBytes
19179646dec5SDamjan Jovanovic }
19189646dec5SDamjan Jovanovic catch ( io::IOException const & )
19199646dec5SDamjan Jovanovic {
19209646dec5SDamjan Jovanovic // getLength, readBytes
19219646dec5SDamjan Jovanovic }
19229646dec5SDamjan Jovanovic }
19239646dec5SDamjan Jovanovic else
19249646dec5SDamjan Jovanovic {
19259646dec5SDamjan Jovanovic try
19269646dec5SDamjan Jovanovic {
19279646dec5SDamjan Jovanovic uno::Sequence< sal_Int8 > aBuffer;
19289646dec5SDamjan Jovanovic sal_Int32 nPos = 0;
19299646dec5SDamjan Jovanovic
19309646dec5SDamjan Jovanovic sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 );
19319646dec5SDamjan Jovanovic while ( nRead > 0 )
19329646dec5SDamjan Jovanovic {
19339646dec5SDamjan Jovanovic if ( rData.getLength() < ( nPos + nRead ) )
19349646dec5SDamjan Jovanovic rData.realloc( nPos + nRead );
19359646dec5SDamjan Jovanovic
19369646dec5SDamjan Jovanovic aBuffer.realloc( nRead );
19379646dec5SDamjan Jovanovic rtl_copyMemory( (void*)( rData.getArray() + nPos ),
19389646dec5SDamjan Jovanovic (const void*)aBuffer.getConstArray(),
19399646dec5SDamjan Jovanovic nRead );
19409646dec5SDamjan Jovanovic nPos += nRead;
19419646dec5SDamjan Jovanovic
19429646dec5SDamjan Jovanovic aBuffer.realloc( 0 );
19439646dec5SDamjan Jovanovic nRead = xStream->readSomeBytes( aBuffer, 65536 );
19449646dec5SDamjan Jovanovic }
19459646dec5SDamjan Jovanovic
19469646dec5SDamjan Jovanovic if ( bAppendTrailingZeroByte )
19479646dec5SDamjan Jovanovic {
19489646dec5SDamjan Jovanovic rData.realloc( nPos + 1 );
19499646dec5SDamjan Jovanovic rData[ nPos ] = sal_Int8( 0 );
19509646dec5SDamjan Jovanovic }
19519646dec5SDamjan Jovanovic return true;
19529646dec5SDamjan Jovanovic }
19539646dec5SDamjan Jovanovic catch ( io::NotConnectedException const & )
19549646dec5SDamjan Jovanovic {
19559646dec5SDamjan Jovanovic // readBytes
19569646dec5SDamjan Jovanovic }
19579646dec5SDamjan Jovanovic catch ( io::BufferSizeExceededException const & )
19589646dec5SDamjan Jovanovic {
19599646dec5SDamjan Jovanovic // readBytes
19609646dec5SDamjan Jovanovic }
19619646dec5SDamjan Jovanovic catch ( io::IOException const & )
19629646dec5SDamjan Jovanovic {
19639646dec5SDamjan Jovanovic // readBytes
19649646dec5SDamjan Jovanovic }
19659646dec5SDamjan Jovanovic }
19669646dec5SDamjan Jovanovic }
19679646dec5SDamjan Jovanovic return false;
19689646dec5SDamjan Jovanovic }
19699646dec5SDamjan Jovanovic
19709646dec5SDamjan Jovanovic // ---------------------------------------------------------------------
19719646dec5SDamjan Jovanovic sal_Bool
isDomainMatch(rtl::OUString certHostName)19729646dec5SDamjan Jovanovic CurlSession::isDomainMatch( rtl::OUString certHostName )
19739646dec5SDamjan Jovanovic {
19749646dec5SDamjan Jovanovic rtl::OUString hostName = getHostName();
19759646dec5SDamjan Jovanovic
19769646dec5SDamjan Jovanovic if (hostName.equalsIgnoreAsciiCase( certHostName ) )
19779646dec5SDamjan Jovanovic return sal_True;
19789646dec5SDamjan Jovanovic
19799646dec5SDamjan Jovanovic if ( 0 == certHostName.indexOf( rtl::OUString::createFromAscii( "*" ) ) &&
19809646dec5SDamjan Jovanovic hostName.getLength() >= certHostName.getLength() )
19819646dec5SDamjan Jovanovic {
19829646dec5SDamjan Jovanovic rtl::OUString cmpStr = certHostName.copy( 1 );
19839646dec5SDamjan Jovanovic
19849646dec5SDamjan Jovanovic if ( hostName.matchIgnoreAsciiCase(
19859646dec5SDamjan Jovanovic cmpStr, hostName.getLength() - cmpStr.getLength() ) )
19869646dec5SDamjan Jovanovic return sal_True;
19879646dec5SDamjan Jovanovic }
19889646dec5SDamjan Jovanovic return sal_False;
19899646dec5SDamjan Jovanovic }
1990