1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_ucb.hxx" 24 25 #include <hash_map> 26 #include <vector> 27 #include <string.h> 28 #include <rtl/string.h> 29 #include "comphelper/sequence.hxx" 30 #include "ucbhelper/simplecertificatevalidationrequest.hxx" 31 32 #include "AprEnv.hxx" 33 #include <apr_strings.h> 34 35 #include "DAVAuthListener.hxx" 36 #include "SerfTypes.hxx" 37 #include "SerfSession.hxx" 38 #include "SerfUri.hxx" 39 #include "SerfRequestProcessor.hxx" 40 #include "SerfCallbacks.hxx" 41 #include "SerfInputStream.hxx" 42 #include "UCBDeadPropertyValue.hxx" 43 44 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp> 45 #include <com/sun/star/security/XCertificate.hpp> 46 #include <com/sun/star/security/CertificateValidity.hpp> 47 #include <com/sun/star/security/CertificateContainerStatus.hpp> 48 #include <com/sun/star/security/CertificateContainer.hpp> 49 #include <com/sun/star/security/XCertificateContainer.hpp> 50 #include <com/sun/star/security/CertAltNameEntry.hpp> 51 #include <com/sun/star/security/XSanExtension.hpp> 52 #define OID_SUBJECT_ALTERNATIVE_NAME "2.5.29.17" 53 54 #include <com/sun/star/ucb/Lock.hpp> 55 #include <com/sun/star/xml/crypto/XSEInitializer.hpp> 56 57 using namespace com::sun::star; 58 using namespace http_dav_ucp; 59 60 61 // ------------------------------------------------------------------- 62 // static members! 63 //SerfLockStore SerfSession::m_aSerfLockStore; 64 65 // ------------------------------------------------------------------- 66 // Constructor 67 // ------------------------------------------------------------------- 68 SerfSession::SerfSession( 69 const rtl::Reference< DAVSessionFactory > & rSessionFactory, 70 const rtl::OUString& inUri, 71 const ucbhelper::InternetProxyDecider & rProxyDecider ) 72 throw ( DAVException ) 73 : DAVSession( rSessionFactory ) 74 , m_aMutex() 75 , m_aUri( inUri ) 76 , m_aProxyName() 77 , m_nProxyPort( 0 ) 78 , m_pSerfConnection( 0 ) 79 , m_pSerfContext( 0 ) 80 , m_bIsHeadRequestInProgress( false ) 81 , m_bUseChunkedEncoding( false ) 82 , m_bNoOfTransferEncodingSwitches( 0 ) 83 , m_rProxyDecider( rProxyDecider ) 84 , m_aEnv() 85 { 86 m_pSerfContext = serf_context_create( getAprPool() ); 87 88 m_pSerfBucket_Alloc = serf_bucket_allocator_create( getAprPool(), NULL, NULL ); 89 } 90 91 // ------------------------------------------------------------------- 92 // Destructor 93 // ------------------------------------------------------------------- 94 SerfSession::~SerfSession( ) 95 { 96 if ( m_pSerfConnection ) 97 { 98 serf_connection_close( m_pSerfConnection ); 99 m_pSerfConnection = 0; 100 } 101 } 102 103 // ------------------------------------------------------------------- 104 void SerfSession::Init( const DAVRequestEnvironment & rEnv ) 105 throw ( DAVException ) 106 { 107 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 108 m_aEnv = rEnv; 109 Init(); 110 } 111 112 // ------------------------------------------------------------------- 113 void SerfSession::Init() 114 throw ( DAVException ) 115 { 116 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 117 118 bool bCreateNewSession = false; 119 120 if ( m_pSerfConnection == 0 ) 121 { 122 const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings(); 123 124 m_aProxyName = rProxyCfg.aName; 125 m_nProxyPort = rProxyCfg.nPort; 126 127 // Not yet initialized. Create new session. 128 bCreateNewSession = true; 129 } 130 else 131 { 132 const ucbhelper::InternetProxyServer & rProxyCfg = getProxySettings(); 133 134 if ( ( rProxyCfg.aName != m_aProxyName ) 135 || ( rProxyCfg.nPort != m_nProxyPort ) ) 136 { 137 m_aProxyName = rProxyCfg.aName; 138 m_nProxyPort = rProxyCfg.nPort; 139 140 // new session needed, destroy old first 141 serf_connection_close( m_pSerfConnection ); 142 m_pSerfConnection = 0; 143 bCreateNewSession = true; 144 } 145 } 146 147 if ( bCreateNewSession ) 148 { 149 // TODO - close_connection callback 150 apr_status_t status = serf_connection_create2( &m_pSerfConnection, 151 m_pSerfContext, 152 *(m_aUri.getAprUri()), 153 Serf_ConnectSetup, this, 154 0 /* close connection callback */, 0 /* close connection baton */, 155 getAprPool() ); 156 157 if ( m_pSerfConnection == 0 ||status != APR_SUCCESS ) 158 { 159 throw DAVException( DAVException::DAV_SESSION_CREATE, 160 SerfUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) ); 161 } 162 163 // Register the session with the lock store 164 // m_aSerfLockStore.registerSession( m_pSerfConnection ); 165 166 if ( m_aProxyName.getLength() ) 167 { 168 apr_sockaddr_t *proxy_address = NULL; 169 status = apr_sockaddr_info_get( &proxy_address, 170 rtl::OUStringToOString( m_aProxyName, RTL_TEXTENCODING_UTF8 ).getStr(), 171 APR_UNSPEC, 172 static_cast<apr_port_t>(m_nProxyPort), 173 0, getAprPool() ); 174 175 if ( status != APR_SUCCESS ) 176 { 177 throw DAVException( DAVException::DAV_SESSION_CREATE, 178 SerfUri::makeConnectionEndPointString( m_aUri.GetHost(), m_aUri.GetPort() ) ); 179 } 180 181 serf_config_proxy( m_pSerfContext, proxy_address ); 182 } 183 184 185 serf_config_credentials_callback( m_pSerfContext, Serf_Credentials ); 186 187 m_bUseChunkedEncoding = isSSLNeeded(); 188 } 189 } 190 191 apr_pool_t* SerfSession::getAprPool() 192 { 193 return apr_environment::AprEnv::getAprEnv()->getAprPool(); 194 } 195 196 serf_bucket_alloc_t* SerfSession::getSerfBktAlloc() 197 { 198 return m_pSerfBucket_Alloc; 199 } 200 201 serf_context_t* SerfSession::getSerfContext() 202 { 203 return m_pSerfContext; 204 } 205 206 SerfConnection* SerfSession::getSerfConnection() 207 { 208 return m_pSerfConnection; 209 } 210 211 bool SerfSession::isHeadRequestInProgress() 212 { 213 return m_bIsHeadRequestInProgress; 214 } 215 216 bool SerfSession::isSSLNeeded() 217 { 218 return m_aUri.GetScheme().equalsIgnoreAsciiCase( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "https" ) ) ); 219 } 220 221 char* SerfSession::getHostinfo() 222 { 223 return m_aUri.getAprUri()->hostinfo; 224 } 225 226 227 // ------------------------------------------------------------------- 228 // virtual 229 sal_Bool SerfSession::CanUse( const rtl::OUString & inUri ) 230 { 231 try 232 { 233 SerfUri theUri( inUri ); 234 if ( ( theUri.GetPort() == m_aUri.GetPort() ) && 235 ( theUri.GetHost() == m_aUri.GetHost() ) && 236 ( theUri.GetScheme() == m_aUri.GetScheme() ) ) 237 { 238 return sal_True; 239 } 240 } 241 catch ( DAVException const & ) 242 { 243 return sal_False; 244 } 245 return sal_False; 246 } 247 248 // ------------------------------------------------------------------- 249 // virtual 250 sal_Bool SerfSession::UsesProxy() 251 { 252 Init(); 253 return ( m_aProxyName.getLength() > 0 ); 254 } 255 256 apr_status_t SerfSession::setupSerfConnection( apr_socket_t * inAprSocket, 257 serf_bucket_t **outSerfInputBucket, 258 serf_bucket_t **outSerfOutputBucket, 259 apr_pool_t* /*inAprPool*/ ) 260 { 261 serf_bucket_t *tmpInputBkt; 262 tmpInputBkt = serf_context_bucket_socket_create( getSerfContext(), 263 inAprSocket, 264 getSerfBktAlloc() ); 265 266 if ( isSSLNeeded() ) 267 { 268 tmpInputBkt = serf_bucket_ssl_decrypt_create( tmpInputBkt, 269 0, 270 getSerfBktAlloc() ); 271 /** Set the callback that is called to authenticate the 272 certifcate (chain). 273 */ 274 serf_ssl_server_cert_chain_callback_set( 275 serf_bucket_ssl_decrypt_context_get(tmpInputBkt), 276 NULL, 277 Serf_CertificateChainValidation, 278 this); 279 serf_ssl_set_hostname( serf_bucket_ssl_decrypt_context_get( tmpInputBkt ), 280 getHostinfo() ); 281 282 *outSerfOutputBucket = serf_bucket_ssl_encrypt_create( *outSerfOutputBucket, 283 serf_bucket_ssl_decrypt_context_get( tmpInputBkt ), 284 getSerfBktAlloc() ); 285 } 286 287 *outSerfInputBucket = tmpInputBkt; 288 289 return APR_SUCCESS; 290 } 291 292 apr_status_t SerfSession::provideSerfCredentials( bool bGiveProvidedCredentialsASecondTry, 293 char ** outUsername, 294 char ** outPassword, 295 serf_request_t * /*inRequest*/, 296 int /*inCode*/, 297 const char *inAuthProtocol, 298 const char *inRealm, 299 apr_pool_t *inAprPool ) 300 { 301 DAVAuthListener * pListener = getRequestEnvironment().m_xAuthListener.get(); 302 if ( !pListener ) 303 { 304 // abort 305 return SERF_ERROR_AUTHN_FAILED; 306 } 307 308 rtl::OUString theUserName; 309 rtl::OUString thePassWord; 310 try 311 { 312 SerfUri uri( getRequestEnvironment().m_aRequestURI ); 313 rtl::OUString aUserInfo( uri.GetUserInfo() ); 314 if ( aUserInfo.getLength() ) 315 { 316 sal_Int32 nPos = aUserInfo.indexOf( '@' ); 317 if ( nPos == -1 ) 318 { 319 theUserName = aUserInfo; 320 } 321 else 322 { 323 theUserName = aUserInfo.copy( 0, nPos ); 324 thePassWord = aUserInfo.copy( nPos + 1 ); 325 } 326 } 327 } 328 catch ( DAVException const & ) 329 { 330 // abort 331 return SERF_ERROR_AUTHN_FAILED; 332 } 333 334 const bool bCanUseSystemCreds = ( ( strcasecmp( inAuthProtocol, "NTLM" ) == 0 ) || 335 ( strcasecmp( inAuthProtocol, "Negotiate" ) == 0 ) ); 336 337 int theRetVal = pListener->authenticate( rtl::OUString::createFromAscii( inRealm ), 338 getHostName(), 339 theUserName, 340 thePassWord, 341 bCanUseSystemCreds, 342 bGiveProvidedCredentialsASecondTry ? sal_False : sal_True ); 343 344 if ( theRetVal == 0 ) 345 { 346 *outUsername = apr_pstrdup( inAprPool, rtl::OUStringToOString( theUserName, RTL_TEXTENCODING_UTF8 ).getStr() ); 347 *outPassword = apr_pstrdup( inAprPool, rtl::OUStringToOString( thePassWord, RTL_TEXTENCODING_UTF8 ).getStr() ); 348 } 349 350 return theRetVal != 0 ? SERF_ERROR_AUTHN_FAILED : APR_SUCCESS; 351 } 352 353 namespace { 354 // ------------------------------------------------------------------- 355 // Helper function 356 ::rtl::OUString GetHostnamePart( const ::rtl::OUString& _rRawString ) 357 { 358 ::rtl::OUString sPart; 359 ::rtl::OUString sPartId = ::rtl::OUString::createFromAscii( "CN=" ); 360 sal_Int32 nContStart = _rRawString.indexOf( sPartId ); 361 if ( nContStart != -1 ) 362 { 363 nContStart = nContStart + sPartId.getLength(); 364 sal_Int32 nContEnd 365 = _rRawString.indexOf( sal_Unicode( ',' ), nContStart ); 366 sPart = _rRawString.copy( nContStart, nContEnd - nContStart ); 367 } 368 return sPart; 369 } 370 } // namespace 371 372 373 apr_status_t SerfSession::verifySerfCertificateChain ( 374 int, 375 const serf_ssl_certificate_t * const * pCertificateChainBase64Encoded, 376 int nCertificateChainLength) 377 { 378 // Check arguments. 379 if (pCertificateChainBase64Encoded == NULL || nCertificateChainLength<=0) 380 { 381 OSL_ASSERT(pCertificateChainBase64Encoded != NULL); 382 OSL_ASSERT(nCertificateChainLength>0); 383 return SERF_SSL_CERT_UNKNOWN_FAILURE; 384 } 385 386 // Create some crypto objects to decode and handle the base64 387 // encoded certificate chain. 388 uno::Reference< xml::crypto::XSEInitializer > xSEInitializer; 389 uno::Reference< security::XCertificateContainer > xCertificateContainer; 390 uno::Reference< xml::crypto::XXMLSecurityContext > xSecurityContext; 391 uno::Reference< xml::crypto::XSecurityEnvironment > xSecurityEnv; 392 try 393 { 394 // Create a certificate container. 395 xCertificateContainer = uno::Reference< security::XCertificateContainer >( 396 getMSF()->createInstance( 397 rtl::OUString::createFromAscii( 398 "com.sun.star.security.CertificateContainer" ) ), 399 uno::UNO_QUERY_THROW); 400 401 xSEInitializer = uno::Reference< xml::crypto::XSEInitializer >( 402 getMSF()->createInstance( 403 rtl::OUString::createFromAscii( "com.sun.star.xml.crypto.SEInitializer" ) ), 404 uno::UNO_QUERY_THROW); 405 406 xSecurityContext = xSEInitializer->createSecurityContext( rtl::OUString() ); 407 if (xSecurityContext.is()) 408 xSecurityEnv = xSecurityContext->getSecurityEnvironment(); 409 410 if ( ! xSecurityContext.is() || ! xSecurityEnv.is()) 411 { 412 // Do we have to dispose xSEInitializer or xCertificateContainer? 413 return SERF_SSL_CERT_UNKNOWN_FAILURE; 414 } 415 } 416 catch ( uno::Exception const &) 417 { 418 return SERF_SSL_CERT_UNKNOWN_FAILURE; 419 } 420 421 // Decode the server certificate. 422 const char* sBase64EncodedServerCertificate ( 423 serf_ssl_cert_export( 424 pCertificateChainBase64Encoded[0], 425 getAprPool())); 426 uno::Reference< security::XCertificate > xServerCertificate( 427 xSecurityEnv->createCertificateFromAscii( 428 rtl::OUString::createFromAscii(sBase64EncodedServerCertificate))); 429 if ( ! xServerCertificate.is()) 430 return SERF_SSL_CERT_UNKNOWN_FAILURE; 431 432 // Get the subject from the server certificate. 433 ::rtl::OUString sServerCertificateSubject (xServerCertificate->getSubjectName()); 434 sal_Int32 nIndex = 0; 435 while (nIndex >= 0) 436 { 437 const ::rtl::OUString sToken (sServerCertificateSubject.getToken(0, ',', nIndex)); 438 if (sToken.compareToAscii("CN=", 3) == 0) 439 { 440 sServerCertificateSubject = sToken.copy(3); 441 break; 442 } 443 else if (sToken.compareToAscii(" CN=", 4) == 0) 444 { 445 sServerCertificateSubject = sToken.copy(4); 446 break; 447 } 448 } 449 450 // When the certificate container already contains a (trusted) 451 // entry for the server then we do not have to authenticate any 452 // certificate. 453 const security::CertificateContainerStatus eStatus ( 454 xCertificateContainer->hasCertificate( 455 getHostName(), sServerCertificateSubject ) ); 456 if (eStatus != security::CertificateContainerStatus_NOCERT) 457 { 458 return eStatus == security::CertificateContainerStatus_TRUSTED 459 ? APR_SUCCESS 460 : SERF_SSL_CERT_UNKNOWN_FAILURE; 461 } 462 463 // The shortcut failed, so try to verify the whole chain. This is 464 // done outside the isDomainMatch() block because the result is 465 // used by the interaction handler. 466 std::vector< uno::Reference< security::XCertificate > > aChain; 467 for (nIndex=1; nIndex<nCertificateChainLength; ++nIndex) 468 { 469 const char* sBase64EncodedCertificate ( 470 serf_ssl_cert_export( 471 pCertificateChainBase64Encoded[nIndex], 472 getAprPool())); 473 uno::Reference< security::XCertificate > xCertificate( 474 xSecurityEnv->createCertificateFromAscii( 475 rtl::OUString::createFromAscii(sBase64EncodedCertificate))); 476 if ( ! xCertificate.is()) 477 return SERF_SSL_CERT_UNKNOWN_FAILURE; 478 aChain.push_back(xCertificate); 479 } 480 const sal_Int64 nVerificationResult (xSecurityEnv->verifyCertificate( 481 xServerCertificate, 482 ::comphelper::containerToSequence(aChain))); 483 484 // When the certificate matches the host name then we can use the 485 // result of the verification. 486 bool bHostnameMatchesCertHostnames = false; 487 { 488 uno::Sequence< uno::Reference< security::XCertificateExtension > > extensions = xServerCertificate->getExtensions(); 489 uno::Sequence< security::CertAltNameEntry > altNames; 490 for (sal_Int32 i = 0 ; i < extensions.getLength(); ++i) 491 { 492 uno::Reference< security::XCertificateExtension >element = extensions[i]; 493 494 const rtl::OString aId ( (const sal_Char *)element->getExtensionId().getArray(), element->getExtensionId().getLength()); 495 if ( aId.equals( OID_SUBJECT_ALTERNATIVE_NAME ) ) 496 { 497 uno::Reference< security::XSanExtension > sanExtension ( element, uno::UNO_QUERY ); 498 altNames = sanExtension->getAlternativeNames(); 499 break; 500 } 501 } 502 503 uno::Sequence< ::rtl::OUString > certHostNames(altNames.getLength() + 1); 504 certHostNames[0] = sServerCertificateSubject; 505 for( int n = 0; n < altNames.getLength(); ++n ) 506 { 507 if (altNames[n].Type == security::ExtAltNameType_DNS_NAME) 508 { 509 altNames[n].Value >>= certHostNames[n+1]; 510 } 511 } 512 513 for ( int i = 0; i < certHostNames.getLength() && !bHostnameMatchesCertHostnames; ++i ) 514 { 515 bHostnameMatchesCertHostnames = isDomainMatch( certHostNames[i] ); 516 } 517 518 } 519 if ( bHostnameMatchesCertHostnames ) 520 { 521 522 if (nVerificationResult == 0) 523 { 524 // Certificate (chain) is valid. 525 xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_True); 526 return APR_SUCCESS; 527 } 528 else if ((nVerificationResult & security::CertificateValidity::CHAIN_INCOMPLETE) != 0) 529 { 530 // We do not have enough information for verification, 531 // neither automatically (as we just discovered) nor 532 // manually (so there is no point in showing any dialog.) 533 return SERF_SSL_CERT_UNKNOWN_FAILURE; 534 } 535 else if ((nVerificationResult & 536 (security::CertificateValidity::INVALID | security::CertificateValidity::REVOKED)) != 0) 537 { 538 // Certificate (chain) is invalid. 539 xCertificateContainer->addCertificate(getHostName(), sServerCertificateSubject, sal_False); 540 return SERF_SSL_CERT_UNKNOWN_FAILURE; 541 } 542 else 543 { 544 // For all other we have to ask the user. 545 } 546 } 547 548 // We have not been able to automatically verify (or falsify) the 549 // certificate chain. To resolve this we have to ask the user. 550 const uno::Reference< ucb::XCommandEnvironment > xEnv( getRequestEnvironment().m_xEnv ); 551 if ( xEnv.is() ) 552 { 553 uno::Reference< task::XInteractionHandler > xIH( xEnv->getInteractionHandler() ); 554 if ( xIH.is() ) 555 { 556 rtl::Reference< ucbhelper::SimpleCertificateValidationRequest > 557 xRequest( new ucbhelper::SimpleCertificateValidationRequest( 558 static_cast<sal_Int32>(nVerificationResult), xServerCertificate, getHostName() ) ); 559 xIH->handle( xRequest.get() ); 560 561 rtl::Reference< ucbhelper::InteractionContinuation > xSelection 562 = xRequest->getSelection(); 563 564 if ( xSelection.is() ) 565 { 566 uno::Reference< task::XInteractionApprove > xApprove( xSelection.get(), uno::UNO_QUERY ); 567 if ( xApprove.is() ) 568 { 569 xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_True ); 570 return APR_SUCCESS; 571 } 572 else 573 { 574 // Don't trust cert 575 xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False ); 576 return SERF_SSL_CERT_UNKNOWN_FAILURE; 577 } 578 } 579 } 580 else 581 { 582 // Don't trust cert 583 xCertificateContainer->addCertificate( getHostName(), sServerCertificateSubject, sal_False ); 584 return SERF_SSL_CERT_UNKNOWN_FAILURE; 585 } 586 } 587 588 return SERF_SSL_CERT_UNKNOWN_FAILURE; 589 } 590 591 serf_bucket_t* SerfSession::acceptSerfResponse( serf_request_t * inSerfRequest, 592 serf_bucket_t * inSerfStreamBucket, 593 apr_pool_t* /*inAprPool*/ ) 594 { 595 // get the per-request bucket allocator 596 serf_bucket_alloc_t* SerfBktAlloc = serf_request_get_alloc( inSerfRequest ); 597 598 // create a barrier bucket so the response doesn't eat us! 599 serf_bucket_t *responseBkt = serf_bucket_barrier_create( inSerfStreamBucket, 600 SerfBktAlloc ); 601 602 // create response bucket 603 responseBkt = serf_bucket_response_create( responseBkt, 604 SerfBktAlloc ); 605 606 if ( isHeadRequestInProgress() ) 607 { 608 // advise the response bucket that this was from a HEAD request and that it should not expect to see a response body. 609 serf_bucket_response_set_head( responseBkt ); 610 } 611 612 return responseBkt; 613 } 614 615 SerfRequestProcessor* SerfSession::createReqProc( const rtl::OUString & inPath ) 616 { 617 return new SerfRequestProcessor( *this, 618 inPath, 619 m_bUseChunkedEncoding ); 620 } 621 622 // ------------------------------------------------------------------- 623 // PROPFIND - allprop & named 624 // ------------------------------------------------------------------- 625 void SerfSession::PROPFIND( const rtl::OUString & inPath, 626 const Depth inDepth, 627 const std::vector< rtl::OUString > & inPropNames, 628 std::vector< DAVResource > & ioResources, 629 const DAVRequestEnvironment & rEnv ) 630 throw ( DAVException ) 631 { 632 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 633 634 Init( rEnv ); 635 636 apr_status_t status = APR_SUCCESS; 637 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 638 aReqProc->processPropFind( inDepth, 639 inPropNames, 640 ioResources, 641 status ); 642 643 if ( status == APR_SUCCESS && 644 aReqProc->mpDAVException == 0 && 645 ioResources.empty() ) 646 { 647 m_aEnv = DAVRequestEnvironment(); 648 throw DAVException( DAVException::DAV_HTTP_ERROR, inPath, (sal_uInt16)APR_EGENERAL ); 649 } 650 HandleError( aReqProc ); 651 } 652 653 // ------------------------------------------------------------------- 654 // PROPFIND - propnames 655 // ------------------------------------------------------------------- 656 void SerfSession::PROPFIND( const rtl::OUString & inPath, 657 const Depth inDepth, 658 std::vector< DAVResourceInfo > & ioResInfo, 659 const DAVRequestEnvironment & rEnv ) 660 throw( DAVException ) 661 { 662 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 663 664 Init( rEnv ); 665 666 apr_status_t status = APR_SUCCESS; 667 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 668 aReqProc->processPropFind( inDepth, 669 ioResInfo, 670 status ); 671 672 if ( status == APR_SUCCESS && 673 aReqProc->mpDAVException == 0 && 674 ioResInfo.empty() ) 675 { 676 m_aEnv = DAVRequestEnvironment(); 677 throw DAVException( DAVException::DAV_HTTP_ERROR, inPath, (sal_uInt16)APR_EGENERAL ); 678 } 679 HandleError( aReqProc ); 680 } 681 682 // ------------------------------------------------------------------- 683 // PROPPATCH 684 // ------------------------------------------------------------------- 685 void SerfSession::PROPPATCH( const rtl::OUString & inPath, 686 const std::vector< ProppatchValue > & inValues, 687 const DAVRequestEnvironment & rEnv ) 688 throw( DAVException ) 689 { 690 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 691 692 Init( rEnv ); 693 694 apr_status_t status = APR_SUCCESS; 695 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 696 aReqProc->processPropPatch( inValues, 697 status ); 698 699 HandleError( aReqProc ); 700 } 701 702 // ------------------------------------------------------------------- 703 // HEAD 704 // ------------------------------------------------------------------- 705 void SerfSession::HEAD( const ::rtl::OUString & inPath, 706 const std::vector< ::rtl::OUString > & inHeaderNames, 707 DAVResource & ioResource, 708 const DAVRequestEnvironment & rEnv ) 709 throw( DAVException ) 710 { 711 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 712 713 Init( rEnv ); 714 715 m_bIsHeadRequestInProgress = true; 716 717 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 718 ioResource.uri = inPath; 719 ioResource.properties.clear(); 720 apr_status_t status = APR_SUCCESS; 721 aReqProc->processHead( inHeaderNames, 722 ioResource, 723 status ); 724 725 m_bIsHeadRequestInProgress = false; 726 727 HandleError( aReqProc ); 728 } 729 730 // ------------------------------------------------------------------- 731 // GET 732 // ------------------------------------------------------------------- 733 uno::Reference< io::XInputStream > 734 SerfSession::GET( const rtl::OUString & inPath, 735 const DAVRequestEnvironment & rEnv ) 736 throw ( DAVException ) 737 { 738 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 739 740 Init( rEnv ); 741 742 uno::Reference< SerfInputStream > xInputStream( new SerfInputStream ); 743 apr_status_t status = APR_SUCCESS; 744 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 745 aReqProc->processGet( xInputStream, 746 status ); 747 748 HandleError( aReqProc ); 749 750 return uno::Reference< io::XInputStream >( xInputStream.get() ); 751 } 752 753 // ------------------------------------------------------------------- 754 // GET 755 // ------------------------------------------------------------------- 756 void SerfSession::GET( const rtl::OUString & inPath, 757 uno::Reference< io::XOutputStream > & ioOutputStream, 758 const DAVRequestEnvironment & rEnv ) 759 throw ( DAVException ) 760 { 761 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 762 763 Init( rEnv ); 764 765 apr_status_t status = APR_SUCCESS; 766 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 767 aReqProc->processGet( ioOutputStream, 768 status ); 769 770 HandleError( aReqProc ); 771 } 772 773 // ------------------------------------------------------------------- 774 // GET 775 // ------------------------------------------------------------------- 776 uno::Reference< io::XInputStream > 777 SerfSession::GET( const rtl::OUString & inPath, 778 const std::vector< ::rtl::OUString > & inHeaderNames, 779 DAVResource & ioResource, 780 const DAVRequestEnvironment & rEnv ) 781 throw ( DAVException ) 782 { 783 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 784 785 Init( rEnv ); 786 787 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 788 uno::Reference< SerfInputStream > xInputStream( new SerfInputStream ); 789 ioResource.uri = inPath; 790 ioResource.properties.clear(); 791 apr_status_t status = APR_SUCCESS; 792 aReqProc->processGet( xInputStream, 793 inHeaderNames, 794 ioResource, 795 status ); 796 797 HandleError( aReqProc ); 798 799 return uno::Reference< io::XInputStream >( xInputStream.get() ); 800 } 801 802 803 // ------------------------------------------------------------------- 804 // GET 805 // ------------------------------------------------------------------- 806 void SerfSession::GET( const rtl::OUString & inPath, 807 uno::Reference< io::XOutputStream > & ioOutputStream, 808 const std::vector< ::rtl::OUString > & inHeaderNames, 809 DAVResource & ioResource, 810 const DAVRequestEnvironment & rEnv ) 811 throw ( DAVException ) 812 { 813 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 814 815 Init( rEnv ); 816 817 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 818 ioResource.uri = inPath; 819 ioResource.properties.clear(); 820 apr_status_t status = APR_SUCCESS; 821 aReqProc->processGet( ioOutputStream, 822 inHeaderNames, 823 ioResource, 824 status ); 825 826 HandleError( aReqProc ); 827 } 828 829 // ------------------------------------------------------------------- 830 // PUT 831 // ------------------------------------------------------------------- 832 void SerfSession::PUT( const rtl::OUString & inPath, 833 const uno::Reference< io::XInputStream > & inInputStream, 834 const DAVRequestEnvironment & rEnv ) 835 throw ( DAVException ) 836 { 837 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 838 839 Init( rEnv ); 840 841 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 842 uno::Sequence< sal_Int8 > aDataToSend; 843 if ( !getDataFromInputStream( inInputStream, aDataToSend, false ) ) 844 throw DAVException( DAVException::DAV_INVALID_ARG ); 845 apr_status_t status = APR_SUCCESS; 846 aReqProc->processPut( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), 847 aDataToSend.getLength(), 848 status ); 849 850 HandleError( aReqProc ); 851 } 852 853 // ------------------------------------------------------------------- 854 // POST 855 // ------------------------------------------------------------------- 856 uno::Reference< io::XInputStream > 857 SerfSession::POST( const rtl::OUString & inPath, 858 const rtl::OUString & rContentType, 859 const rtl::OUString & rReferer, 860 const uno::Reference< io::XInputStream > & inInputStream, 861 const DAVRequestEnvironment & rEnv ) 862 throw ( DAVException ) 863 { 864 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 865 866 uno::Sequence< sal_Int8 > aDataToSend; 867 if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) ) 868 { 869 throw DAVException( DAVException::DAV_INVALID_ARG ); 870 } 871 872 Init( rEnv ); 873 874 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 875 uno::Reference< SerfInputStream > xInputStream( new SerfInputStream ); 876 apr_status_t status = APR_SUCCESS; 877 aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), 878 aDataToSend.getLength(), 879 rContentType, 880 rReferer, 881 xInputStream, 882 status ); 883 884 HandleError( aReqProc ); 885 return uno::Reference< io::XInputStream >( xInputStream.get() ); 886 } 887 888 // ------------------------------------------------------------------- 889 // POST 890 // ------------------------------------------------------------------- 891 void SerfSession::POST( const rtl::OUString & inPath, 892 const rtl::OUString & rContentType, 893 const rtl::OUString & rReferer, 894 const uno::Reference< io::XInputStream > & inInputStream, 895 uno::Reference< io::XOutputStream > & oOutputStream, 896 const DAVRequestEnvironment & rEnv ) 897 throw ( DAVException ) 898 { 899 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 900 901 uno::Sequence< sal_Int8 > aDataToSend; 902 if ( !getDataFromInputStream( inInputStream, aDataToSend, true ) ) 903 { 904 throw DAVException( DAVException::DAV_INVALID_ARG ); 905 } 906 907 Init( rEnv ); 908 909 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 910 apr_status_t status = APR_SUCCESS; 911 aReqProc->processPost( reinterpret_cast< const char * >( aDataToSend.getConstArray() ), 912 aDataToSend.getLength(), 913 rContentType, 914 rReferer, 915 oOutputStream, 916 status ); 917 918 HandleError( aReqProc ); 919 } 920 921 // ------------------------------------------------------------------- 922 // MKCOL 923 // ------------------------------------------------------------------- 924 void SerfSession::MKCOL( const rtl::OUString & inPath, 925 const DAVRequestEnvironment & rEnv ) 926 throw ( DAVException ) 927 { 928 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 929 930 Init( rEnv ); 931 932 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 933 apr_status_t status = APR_SUCCESS; 934 aReqProc->processMkCol( status ); 935 936 HandleError( aReqProc ); 937 } 938 939 // ------------------------------------------------------------------- 940 // COPY 941 // ------------------------------------------------------------------- 942 void SerfSession::COPY( const rtl::OUString & inSourceURL, 943 const rtl::OUString & inDestinationURL, 944 const DAVRequestEnvironment & rEnv, 945 sal_Bool inOverWrite ) 946 throw ( DAVException ) 947 { 948 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 949 950 Init( rEnv ); 951 952 SerfUri theSourceUri( inSourceURL ); 953 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) ); 954 apr_status_t status = APR_SUCCESS; 955 aReqProc->processCopy( inDestinationURL, 956 (inOverWrite ? true : false), 957 status ); 958 959 HandleError( aReqProc ); 960 } 961 962 // ------------------------------------------------------------------- 963 // MOVE 964 // ------------------------------------------------------------------- 965 void SerfSession::MOVE( const rtl::OUString & inSourceURL, 966 const rtl::OUString & inDestinationURL, 967 const DAVRequestEnvironment & rEnv, 968 sal_Bool inOverWrite ) 969 throw ( DAVException ) 970 { 971 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 972 973 Init( rEnv ); 974 975 SerfUri theSourceUri( inSourceURL ); 976 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( theSourceUri.GetPath() ) ); 977 apr_status_t status = APR_SUCCESS; 978 aReqProc->processMove( inDestinationURL, 979 (inOverWrite ? true : false), 980 status ); 981 982 HandleError( aReqProc ); 983 } 984 985 // ------------------------------------------------------------------- 986 // DESTROY 987 // ------------------------------------------------------------------- 988 void SerfSession::DESTROY( const rtl::OUString & inPath, 989 const DAVRequestEnvironment & rEnv ) 990 throw ( DAVException ) 991 { 992 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 993 994 Init( rEnv ); 995 996 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 997 apr_status_t status = APR_SUCCESS; 998 aReqProc->processDelete( status ); 999 1000 HandleError( aReqProc ); 1001 } 1002 1003 // ------------------------------------------------------------------- 1004 /* 1005 namespace 1006 { 1007 sal_Int32 lastChanceToSendRefreshRequest( TimeValue const & rStart, 1008 int timeout ) 1009 { 1010 TimeValue aEnd; 1011 osl_getSystemTime( &aEnd ); 1012 1013 // Try to estimate a safe absolute time for sending the 1014 // lock refresh request. 1015 sal_Int32 lastChanceToSendRefreshRequest = -1; 1016 if ( timeout != NE_TIMEOUT_INFINITE ) 1017 { 1018 sal_Int32 calltime = aEnd.Seconds - rStart.Seconds; 1019 if ( calltime <= timeout ) 1020 { 1021 lastChanceToSendRefreshRequest 1022 = aEnd.Seconds + timeout - calltime; 1023 } 1024 else 1025 { 1026 OSL_TRACE( "No chance to refresh lock before timeout!" ); 1027 } 1028 } 1029 return lastChanceToSendRefreshRequest; 1030 } 1031 1032 } // namespace 1033 */ 1034 // ------------------------------------------------------------------- 1035 // LOCK (set new lock) 1036 // ------------------------------------------------------------------- 1037 void SerfSession::LOCK( const ::rtl::OUString & inPath, 1038 ucb::Lock & /*rLock*/, 1039 const DAVRequestEnvironment & rEnv ) 1040 throw ( DAVException ) 1041 { 1042 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 1043 1044 Init( rEnv ); 1045 1046 boost::shared_ptr<SerfRequestProcessor> aReqProc( createReqProc( inPath ) ); 1047 HandleError( aReqProc ); 1048 /* Create a depth zero, exclusive write lock, with default timeout 1049 * (allowing a server to pick a default). token, owner and uri are 1050 * unset. */ 1051 /* 1052 SerfLock * theLock = ne_lock_create(); 1053 1054 // Set the lock uri 1055 ne_uri aUri; 1056 ne_uri_parse( rtl::OUStringToOString( makeAbsoluteURL( inPath ), 1057 RTL_TEXTENCODING_UTF8 ).getStr(), 1058 &aUri ); 1059 theLock->uri = aUri; 1060 1061 // Set the lock depth 1062 switch( rLock.Depth ) 1063 { 1064 case ucb::LockDepth_ZERO: 1065 theLock->depth = NE_DEPTH_ZERO; 1066 break; 1067 case ucb::LockDepth_ONE: 1068 theLock->depth = NE_DEPTH_ONE; 1069 break; 1070 case ucb::LockDepth_INFINITY: 1071 theLock->depth = NE_DEPTH_INFINITE; 1072 break; 1073 default: 1074 throw DAVException( DAVException::DAV_INVALID_ARG ); 1075 } 1076 1077 // Set the lock scope 1078 switch ( rLock.Scope ) 1079 { 1080 case ucb::LockScope_EXCLUSIVE: 1081 theLock->scope = ne_lockscope_exclusive; 1082 break; 1083 case ucb::LockScope_SHARED: 1084 theLock->scope = ne_lockscope_shared; 1085 break; 1086 default: 1087 throw DAVException( DAVException::DAV_INVALID_ARG ); 1088 } 1089 1090 // Set the lock timeout 1091 theLock->timeout = (long)rLock.Timeout; 1092 1093 // Set the lock owner 1094 rtl::OUString aValue; 1095 rLock.Owner >>= aValue; 1096 theLock->owner = 1097 ne_strdup( rtl::OUStringToOString( aValue, 1098 RTL_TEXTENCODING_UTF8 ).getStr() ); 1099 TimeValue startCall; 1100 osl_getSystemTime( &startCall ); 1101 1102 int theRetVal = ne_lock( m_pHttpSession, theLock ); 1103 1104 if ( theRetVal == NE_OK ) 1105 { 1106 m_aSerfLockStore.addLock( theLock, 1107 this, 1108 lastChanceToSendRefreshRequest( 1109 startCall, theLock->timeout ) ); 1110 1111 uno::Sequence< rtl::OUString > aTokens( 1 ); 1112 aTokens[ 0 ] = rtl::OUString::createFromAscii( theLock->token ); 1113 rLock.LockTokens = aTokens; 1114 1115 OSL_TRACE( "SerfSession::LOCK: created lock for %s. token: %s", 1116 rtl::OUStringToOString( makeAbsoluteURL( inPath ), 1117 RTL_TEXTENCODING_UTF8 ).getStr(), 1118 theLock->token ); 1119 } 1120 else 1121 { 1122 ne_lock_destroy( theLock ); 1123 1124 OSL_TRACE( "SerfSession::LOCK: obtaining lock for %s failed!", 1125 rtl::OUStringToOString( makeAbsoluteURL( inPath ), 1126 RTL_TEXTENCODING_UTF8 ).getStr() ); 1127 } 1128 1129 HandleError( theRetVal, inPath, rEnv ); 1130 */ 1131 } 1132 1133 // ------------------------------------------------------------------- 1134 // LOCK (refresh existing lock) 1135 // ------------------------------------------------------------------- 1136 sal_Int64 SerfSession::LOCK( const ::rtl::OUString & /*inPath*/, 1137 sal_Int64 nTimeout, 1138 const DAVRequestEnvironment & /*rEnv*/ ) 1139 throw ( DAVException ) 1140 { 1141 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 1142 1143 return nTimeout; 1144 /* 1145 // Try to get the neon lock from lock store 1146 SerfLock * theLock 1147 = m_aSerfLockStore.findByUri( makeAbsoluteURL( inPath ) ); 1148 if ( !theLock ) 1149 throw DAVException( DAVException::DAV_NOT_LOCKED ); 1150 1151 Init( rEnv ); 1152 1153 // refresh existing lock. 1154 theLock->timeout = static_cast< long >( nTimeout ); 1155 1156 TimeValue startCall; 1157 osl_getSystemTime( &startCall ); 1158 1159 int theRetVal = ne_lock_refresh( m_pHttpSession, theLock ); 1160 1161 if ( theRetVal == NE_OK ) 1162 { 1163 m_aSerfLockStore.updateLock( theLock, 1164 lastChanceToSendRefreshRequest( 1165 startCall, theLock->timeout ) ); 1166 } 1167 1168 HandleError( theRetVal, inPath, rEnv ); 1169 1170 return theLock->timeout; 1171 */ 1172 } 1173 1174 // ------------------------------------------------------------------- 1175 // LOCK (refresh existing lock) 1176 // ------------------------------------------------------------------- 1177 bool SerfSession::LOCK( SerfLock * /*pLock*/, 1178 sal_Int32 & /*rlastChanceToSendRefreshRequest*/ ) 1179 { 1180 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 1181 1182 return true; 1183 /* 1184 // refresh existing lock. 1185 1186 TimeValue startCall; 1187 osl_getSystemTime( &startCall ); 1188 1189 if ( ne_lock_refresh( m_pHttpSession, pLock ) == NE_OK ) 1190 { 1191 rlastChanceToSendRefreshRequest 1192 = lastChanceToSendRefreshRequest( startCall, pLock->timeout ); 1193 1194 OSL_TRACE( "Lock successfully refreshed." ); 1195 return true; 1196 } 1197 else 1198 { 1199 OSL_TRACE( "Lock not refreshed!" ); 1200 return false; 1201 } 1202 */ 1203 } 1204 1205 // ------------------------------------------------------------------- 1206 // UNLOCK 1207 // ------------------------------------------------------------------- 1208 void SerfSession::UNLOCK( const ::rtl::OUString & /*inPath*/, 1209 const DAVRequestEnvironment & /*rEnv*/ ) 1210 throw ( DAVException ) 1211 { 1212 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 1213 1214 /* 1215 // get the neon lock from lock store 1216 SerfLock * theLock 1217 = m_aSerfLockStore.findByUri( makeAbsoluteURL( inPath ) ); 1218 if ( !theLock ) 1219 throw DAVException( DAVException::DAV_NOT_LOCKED ); 1220 1221 Init( rEnv ); 1222 1223 int theRetVal = ne_unlock( m_pHttpSession, theLock ); 1224 1225 if ( theRetVal == NE_OK ) 1226 { 1227 m_aSerfLockStore.removeLock( theLock ); 1228 ne_lock_destroy( theLock ); 1229 } 1230 else 1231 { 1232 OSL_TRACE( "SerfSession::UNLOCK: unlocking of %s failed.", 1233 rtl::OUStringToOString( makeAbsoluteURL( inPath ), 1234 RTL_TEXTENCODING_UTF8 ).getStr() ); 1235 } 1236 1237 HandleError( theRetVal, inPath, rEnv ); 1238 */ 1239 } 1240 1241 // ------------------------------------------------------------------- 1242 // UNLOCK 1243 // ------------------------------------------------------------------- 1244 bool SerfSession::UNLOCK( SerfLock * /*pLock*/ ) 1245 { 1246 osl::Guard< osl::Mutex > theGuard( m_aMutex ); 1247 1248 return true; 1249 /* 1250 if ( ne_unlock( m_pHttpSession, pLock ) == NE_OK ) 1251 { 1252 OSL_TRACE( "UNLOCK succeeded." ); 1253 return true; 1254 } 1255 else 1256 { 1257 OSL_TRACE( "UNLOCK failed!" ); 1258 return false; 1259 } 1260 */ 1261 } 1262 1263 // ------------------------------------------------------------------- 1264 void SerfSession::abort() 1265 throw ( DAVException ) 1266 { 1267 // 11.11.09 (tkr): The following code lines causing crashes if 1268 // closing a ongoing connection. It turned out that this existing 1269 // solution doesn't work in multi-threading environments. 1270 // So I disabled them in 3.2. . Issue #73893# should fix it in OOo 3.3. 1271 //if ( m_pHttpSession ) 1272 // ne_close_connection( m_pHttpSession ); 1273 } 1274 1275 // ------------------------------------------------------------------- 1276 const ucbhelper::InternetProxyServer & SerfSession::getProxySettings() const 1277 { 1278 if ( m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "http" ) ) || 1279 m_aUri.GetScheme().equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "https" ) ) ) 1280 { 1281 return m_rProxyDecider.getProxy( m_aUri.GetScheme(), 1282 m_aUri.GetHost(), 1283 m_aUri.GetPort() ); 1284 } 1285 else 1286 { 1287 // TODO: figure out, if this case can occur 1288 return m_rProxyDecider.getProxy( m_aUri.GetScheme(), 1289 rtl::OUString() /* not used */, 1290 -1 /* not used */ ); 1291 } 1292 } 1293 1294 /* 1295 // ------------------------------------------------------------------- 1296 namespace { 1297 1298 bool containsLocktoken( const uno::Sequence< ucb::Lock > & rLocks, 1299 const char * token ) 1300 { 1301 for ( sal_Int32 n = 0; n < rLocks.getLength(); ++n ) 1302 { 1303 const uno::Sequence< rtl::OUString > & rTokens 1304 = rLocks[ n ].LockTokens; 1305 for ( sal_Int32 m = 0; m < rTokens.getLength(); ++m ) 1306 { 1307 if ( rTokens[ m ].equalsAscii( token ) ) 1308 return true; 1309 } 1310 } 1311 return false; 1312 } 1313 1314 } // namespace 1315 */ 1316 1317 // ------------------------------------------------------------------- 1318 bool SerfSession::removeExpiredLocktoken( const rtl::OUString & /*inURL*/, 1319 const DAVRequestEnvironment & /*rEnv*/ ) 1320 { 1321 return true; 1322 /* 1323 SerfLock * theLock = m_aSerfLockStore.findByUri( inURL ); 1324 if ( !theLock ) 1325 return false; 1326 1327 // do a lockdiscovery to check whether this lock is still valid. 1328 try 1329 { 1330 // @@@ Alternative: use ne_lock_discover() => less overhead 1331 1332 std::vector< DAVResource > aResources; 1333 std::vector< rtl::OUString > aPropNames; 1334 aPropNames.push_back( DAVProperties::LOCKDISCOVERY ); 1335 1336 PROPFIND( rEnv.m_aRequestURI, DAVZERO, aPropNames, aResources, rEnv ); 1337 1338 if ( aResources.size() == 0 ) 1339 return false; 1340 1341 std::vector< DAVPropertyValue >::const_iterator it 1342 = aResources[ 0 ].properties.begin(); 1343 std::vector< DAVPropertyValue >::const_iterator end 1344 = aResources[ 0 ].properties.end(); 1345 1346 while ( it != end ) 1347 { 1348 if ( (*it).Name.equals( DAVProperties::LOCKDISCOVERY ) ) 1349 { 1350 uno::Sequence< ucb::Lock > aLocks; 1351 if ( !( (*it).Value >>= aLocks ) ) 1352 return false; 1353 1354 if ( !containsLocktoken( aLocks, theLock->token ) ) 1355 { 1356 // expired! 1357 break; 1358 } 1359 1360 // still valid. 1361 return false; 1362 } 1363 ++it; 1364 } 1365 1366 // No lockdiscovery prop in propfind result / locktoken not found 1367 // in propfind result -> not locked 1368 OSL_TRACE( "SerfSession::removeExpiredLocktoken: Removing " 1369 " expired lock token for %s. token: %s", 1370 rtl::OUStringToOString( inURL, 1371 RTL_TEXTENCODING_UTF8 ).getStr(), 1372 theLock->token ); 1373 1374 m_aSerfLockStore.removeLock( theLock ); 1375 ne_lock_destroy( theLock ); 1376 return true; 1377 } 1378 catch ( DAVException const & ) 1379 { 1380 } 1381 return false; 1382 */ 1383 } 1384 1385 // ------------------------------------------------------------------- 1386 // HandleError 1387 // Common Error Handler 1388 // ------------------------------------------------------------------- 1389 void SerfSession::HandleError( boost::shared_ptr<SerfRequestProcessor> rReqProc ) 1390 throw ( DAVException ) 1391 { 1392 m_aEnv = DAVRequestEnvironment(); 1393 1394 if ( rReqProc->mpDAVException ) 1395 { 1396 DAVException* mpDAVExp( rReqProc->mpDAVException ); 1397 1398 serf_connection_reset( getSerfConnection() ); 1399 1400 if ( mpDAVExp->getStatus() == 413 && 1401 m_bNoOfTransferEncodingSwitches < 2 ) 1402 { 1403 m_bUseChunkedEncoding = !m_bUseChunkedEncoding; 1404 ++m_bNoOfTransferEncodingSwitches; 1405 } 1406 1407 throw DAVException( mpDAVExp->getError(), 1408 mpDAVExp->getData(), 1409 mpDAVExp->getStatus() ); 1410 } 1411 1412 /* 1413 // Map error code to DAVException. 1414 switch ( nError ) 1415 { 1416 case NE_OK: 1417 return; 1418 1419 case NE_ERROR: // Generic error 1420 { 1421 rtl::OUString aText = rtl::OUString::createFromAscii( 1422 ne_get_error( m_pHttpSession ) ); 1423 1424 sal_uInt16 code = makeStatusCode( aText ); 1425 1426 if ( code == SC_LOCKED ) 1427 { 1428 if ( m_aSerfLockStore.findByUri( 1429 makeAbsoluteURL( inPath ) ) == 0 ) 1430 { 1431 // locked by 3rd party 1432 throw DAVException( DAVException::DAV_LOCKED ); 1433 } 1434 else 1435 { 1436 // locked by ourself 1437 throw DAVException( DAVException::DAV_LOCKED_SELF ); 1438 } 1439 } 1440 1441 // Special handling for 400 and 412 status codes, which may indicate 1442 // that a lock previously obtained by us has been released meanwhile 1443 // by the server. Unfortunately, RFC is not clear at this point, 1444 // thus server implementations behave different... 1445 else if ( code == SC_BAD_REQUEST || code == SC_PRECONDITION_FAILED ) 1446 { 1447 if ( removeExpiredLocktoken( makeAbsoluteURL( inPath ), rEnv ) ) 1448 throw DAVException( DAVException::DAV_LOCK_EXPIRED ); 1449 } 1450 1451 throw DAVException( DAVException::DAV_HTTP_ERROR, aText, code ); 1452 } 1453 case NE_LOOKUP: // Name lookup failed. 1454 throw DAVException( DAVException::DAV_HTTP_LOOKUP, 1455 SerfUri::makeConnectionEndPointString( 1456 m_aHostName, m_nPort ) ); 1457 1458 case NE_AUTH: // User authentication failed on server 1459 throw DAVException( DAVException::DAV_HTTP_AUTH, 1460 SerfUri::makeConnectionEndPointString( 1461 m_aHostName, m_nPort ) ); 1462 1463 case NE_PROXYAUTH: // User authentication failed on proxy 1464 throw DAVException( DAVException::DAV_HTTP_AUTHPROXY, 1465 SerfUri::makeConnectionEndPointString( 1466 m_aProxyName, m_nProxyPort ) ); 1467 1468 case NE_CONNECT: // Could not connect to server 1469 throw DAVException( DAVException::DAV_HTTP_CONNECT, 1470 SerfUri::makeConnectionEndPointString( 1471 m_aHostName, m_nPort ) ); 1472 1473 case NE_TIMEOUT: // Connection timed out 1474 throw DAVException( DAVException::DAV_HTTP_TIMEOUT, 1475 SerfUri::makeConnectionEndPointString( 1476 m_aHostName, m_nPort ) ); 1477 1478 case NE_FAILED: // The precondition failed 1479 throw DAVException( DAVException::DAV_HTTP_FAILED, 1480 SerfUri::makeConnectionEndPointString( 1481 m_aHostName, m_nPort ) ); 1482 1483 case NE_RETRY: // Retry request (ne_end_request ONLY) 1484 throw DAVException( DAVException::DAV_HTTP_RETRY, 1485 SerfUri::makeConnectionEndPointString( 1486 m_aHostName, m_nPort ) ); 1487 1488 case NE_REDIRECT: 1489 { 1490 SerfUri aUri( ne_redirect_location( m_pHttpSession ) ); 1491 throw DAVException( 1492 DAVException::DAV_HTTP_REDIRECT, aUri.GetURI() ); 1493 } 1494 default: 1495 { 1496 OSL_TRACE( "SerfSession::HandleError : Unknown Serf error code!" ); 1497 throw DAVException( DAVException::DAV_HTTP_ERROR, 1498 rtl::OUString::createFromAscii( 1499 ne_get_error( m_pHttpSession ) ) ); 1500 } 1501 } 1502 */ 1503 } 1504 1505 // ------------------------------------------------------------------- 1506 // static 1507 bool 1508 SerfSession::getDataFromInputStream( 1509 const uno::Reference< io::XInputStream > & xStream, 1510 uno::Sequence< sal_Int8 > & rData, 1511 bool bAppendTrailingZeroByte ) 1512 { 1513 if ( xStream.is() ) 1514 { 1515 uno::Reference< io::XSeekable > xSeekable( xStream, uno::UNO_QUERY ); 1516 if ( xSeekable.is() ) 1517 { 1518 try 1519 { 1520 sal_Int32 nSize 1521 = sal::static_int_cast<sal_Int32>(xSeekable->getLength()); 1522 sal_Int32 nRead 1523 = xStream->readBytes( rData, nSize ); 1524 1525 if ( nRead == nSize ) 1526 { 1527 if ( bAppendTrailingZeroByte ) 1528 { 1529 rData.realloc( nSize + 1 ); 1530 rData[ nSize ] = sal_Int8( 0 ); 1531 } 1532 return true; 1533 } 1534 } 1535 catch ( io::NotConnectedException const & ) 1536 { 1537 // readBytes 1538 } 1539 catch ( io::BufferSizeExceededException const & ) 1540 { 1541 // readBytes 1542 } 1543 catch ( io::IOException const & ) 1544 { 1545 // getLength, readBytes 1546 } 1547 } 1548 else 1549 { 1550 try 1551 { 1552 uno::Sequence< sal_Int8 > aBuffer; 1553 sal_Int32 nPos = 0; 1554 1555 sal_Int32 nRead = xStream->readSomeBytes( aBuffer, 65536 ); 1556 while ( nRead > 0 ) 1557 { 1558 if ( rData.getLength() < ( nPos + nRead ) ) 1559 rData.realloc( nPos + nRead ); 1560 1561 aBuffer.realloc( nRead ); 1562 rtl_copyMemory( (void*)( rData.getArray() + nPos ), 1563 (const void*)aBuffer.getConstArray(), 1564 nRead ); 1565 nPos += nRead; 1566 1567 aBuffer.realloc( 0 ); 1568 nRead = xStream->readSomeBytes( aBuffer, 65536 ); 1569 } 1570 1571 if ( bAppendTrailingZeroByte ) 1572 { 1573 rData.realloc( nPos + 1 ); 1574 rData[ nPos ] = sal_Int8( 0 ); 1575 } 1576 return true; 1577 } 1578 catch ( io::NotConnectedException const & ) 1579 { 1580 // readBytes 1581 } 1582 catch ( io::BufferSizeExceededException const & ) 1583 { 1584 // readBytes 1585 } 1586 catch ( io::IOException const & ) 1587 { 1588 // readBytes 1589 } 1590 } 1591 } 1592 return false; 1593 } 1594 1595 // --------------------------------------------------------------------- 1596 sal_Bool 1597 SerfSession::isDomainMatch( rtl::OUString certHostName ) 1598 { 1599 rtl::OUString hostName = getHostName(); 1600 1601 if (hostName.equalsIgnoreAsciiCase( certHostName ) ) 1602 return sal_True; 1603 1604 if ( 0 == certHostName.indexOf( rtl::OUString::createFromAscii( "*" ) ) && 1605 hostName.getLength() >= certHostName.getLength() ) 1606 { 1607 rtl::OUString cmpStr = certHostName.copy( 1 ); 1608 1609 if ( hostName.matchIgnoreAsciiCase( 1610 cmpStr, hostName.getLength() - cmpStr.getLength() ) ) 1611 return sal_True; 1612 } 1613 return sal_False; 1614 } 1615 1616 /* 1617 // --------------------------------------------------------------------- 1618 rtl::OUString SerfSession::makeAbsoluteURL( rtl::OUString const & rURL ) const 1619 { 1620 try 1621 { 1622 // Is URL relative or already absolute? 1623 if ( rURL[ 0 ] != sal_Unicode( '/' ) ) 1624 { 1625 // absolute. 1626 return rtl::OUString( rURL ); 1627 } 1628 else 1629 { 1630 ne_uri aUri; 1631 memset( &aUri, 0, sizeof( aUri ) ); 1632 1633 ne_fill_server_uri( m_pHttpSession, &aUri ); 1634 aUri.path 1635 = ne_strdup( rtl::OUStringToOString( 1636 rURL, RTL_TEXTENCODING_UTF8 ).getStr() ); 1637 SerfUri aSerfUri( &aUri ); 1638 ne_uri_free( &aUri ); 1639 return aSerfUri.GetURI(); 1640 } 1641 } 1642 catch ( DAVException const & ) 1643 { 1644 } 1645 // error. 1646 return rtl::OUString(); 1647 } 1648 */ 1649