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