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