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