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 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_ucb.hxx" 26 27 #include "osl/diagnose.h" 28 29 #include "com/sun/star/task/XInteractionAbort.hpp" 30 #include "com/sun/star/ucb/XWebDAVCommandEnvironment.hpp" 31 32 #include "ucbhelper/simpleauthenticationrequest.hxx" 33 #include "comphelper/seekableinput.hxx" 34 35 #include "DAVAuthListenerImpl.hxx" 36 #include "DAVResourceAccess.hxx" 37 38 using namespace http_dav_ucp; 39 using namespace com::sun::star; 40 41 //========================================================================= 42 //========================================================================= 43 // 44 // DAVAuthListener_Impl Implementation. 45 // 46 //========================================================================= 47 //========================================================================= 48 49 //========================================================================= 50 // virtual 51 int DAVAuthListener_Impl::authenticate( 52 const ::rtl::OUString & inRealm, 53 const ::rtl::OUString & inHostName, 54 ::rtl::OUString & inoutUserName, 55 ::rtl::OUString & outPassWord, 56 sal_Bool bCanUseSystemCredentials, 57 sal_Bool bUsePreviousCredentials ) 58 { 59 if ( m_xEnv.is() ) 60 { 61 uno::Reference< task::XInteractionHandler > xIH 62 = m_xEnv->getInteractionHandler(); 63 64 if ( xIH.is() ) 65 { 66 // Providing previously retrieved credentials will cause the password 67 // container to reject these. Thus, the credential input dialog will be shown again. 68 // #102871# - Supply username and password from previous try. 69 // Password container service depends on this! 70 if ( inoutUserName.getLength() == 0 && bUsePreviousCredentials ) 71 inoutUserName = m_aPrevUsername; 72 73 if ( outPassWord.getLength() == 0 && bUsePreviousCredentials ) 74 outPassWord = m_aPrevPassword; 75 76 rtl::Reference< ucbhelper::SimpleAuthenticationRequest > xRequest 77 = new ucbhelper::SimpleAuthenticationRequest( 78 m_aURL, inHostName, inRealm, inoutUserName, 79 outPassWord, ::rtl::OUString(), 80 true /*bAllowPersistentStoring*/, 81 bCanUseSystemCredentials ); 82 xIH->handle( xRequest.get() ); 83 84 rtl::Reference< ucbhelper::InteractionContinuation > xSelection 85 = xRequest->getSelection(); 86 87 if ( xSelection.is() ) 88 { 89 // Handler handled the request. 90 uno::Reference< task::XInteractionAbort > xAbort( 91 xSelection.get(), uno::UNO_QUERY ); 92 if ( !xAbort.is() ) 93 { 94 const rtl::Reference< 95 ucbhelper::InteractionSupplyAuthentication > & xSupp 96 = xRequest->getAuthenticationSupplier(); 97 98 sal_Bool bUseSystemCredentials = sal_False; 99 100 if ( bCanUseSystemCredentials ) 101 bUseSystemCredentials 102 = xSupp->getUseSystemCredentials(); 103 104 if ( bUseSystemCredentials ) 105 { 106 // This is the (strange) way to tell neon to use 107 // system credentials. 108 inoutUserName = rtl::OUString(); 109 outPassWord = rtl::OUString(); 110 } 111 else 112 { 113 inoutUserName = xSupp->getUserName(); 114 outPassWord = xSupp->getPassword(); 115 } 116 117 // #102871# - Remember username and password. 118 m_aPrevUsername = inoutUserName; 119 m_aPrevPassword = outPassWord; 120 121 // go on. 122 return 0; 123 } 124 } 125 } 126 } 127 // Abort. 128 return -1; 129 } 130 131 //========================================================================= 132 //========================================================================= 133 // 134 // DAVResourceAccess Implementation. 135 // 136 //========================================================================= 137 //========================================================================= 138 139 //========================================================================= 140 DAVResourceAccess::DAVResourceAccess( 141 const uno::Reference< lang::XMultiServiceFactory > & rSMgr, 142 rtl::Reference< DAVSessionFactory > const & rSessionFactory, 143 const rtl::OUString & rURL ) 144 : m_aURL( rURL ), 145 m_xSessionFactory( rSessionFactory ), 146 m_xSMgr( rSMgr ) 147 { 148 } 149 150 //========================================================================= 151 DAVResourceAccess::DAVResourceAccess( const DAVResourceAccess & rOther ) 152 : m_aURL( rOther.m_aURL ), 153 m_aPath( rOther.m_aPath ), 154 m_xSession( rOther.m_xSession ), 155 m_xSessionFactory( rOther.m_xSessionFactory ), 156 m_xSMgr( rOther.m_xSMgr ), 157 m_aRedirectURIs( rOther.m_aRedirectURIs ) 158 { 159 } 160 161 //========================================================================= 162 DAVResourceAccess & DAVResourceAccess::operator=( 163 const DAVResourceAccess & rOther ) 164 { 165 m_aURL = rOther.m_aURL; 166 m_aPath = rOther.m_aPath; 167 m_xSession = rOther.m_xSession; 168 m_xSessionFactory = rOther.m_xSessionFactory; 169 m_xSMgr = rOther.m_xSMgr; 170 m_aRedirectURIs = rOther.m_aRedirectURIs; 171 172 return *this; 173 } 174 175 //========================================================================= 176 void DAVResourceAccess::PROPFIND( 177 const Depth nDepth, 178 const std::vector< rtl::OUString > & rPropertyNames, 179 std::vector< DAVResource > & rResources, 180 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 181 throw( DAVException ) 182 { 183 initialize(); 184 185 int errorCount = 0; 186 bool bRetry; 187 do 188 { 189 bRetry = false; 190 try 191 { 192 DAVRequestHeaders aHeaders; 193 194 getUserRequestHeaders( xEnv, 195 getRequestURI(), 196 rtl::OUString::createFromAscii( 197 "PROPFIND" ), 198 aHeaders ); 199 200 m_xSession->PROPFIND( getRequestURI(), 201 nDepth, 202 rPropertyNames, 203 rResources, 204 DAVRequestEnvironment( 205 getRequestURI(), 206 new DAVAuthListener_Impl( xEnv, m_aURL ), 207 aHeaders, xEnv ) ); 208 } 209 catch ( DAVException & e ) 210 { 211 errorCount++; 212 bRetry = handleException( e, errorCount ); 213 if ( !bRetry ) 214 throw; 215 } 216 } 217 while ( bRetry ); 218 } 219 220 //========================================================================= 221 void DAVResourceAccess::PROPFIND( 222 const Depth nDepth, 223 std::vector< DAVResourceInfo > & rResInfo, 224 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 225 throw( DAVException ) 226 { 227 initialize(); 228 229 int errorCount = 0; 230 bool bRetry; 231 do 232 { 233 bRetry = false; 234 try 235 { 236 DAVRequestHeaders aHeaders; 237 getUserRequestHeaders( xEnv, 238 getRequestURI(), 239 rtl::OUString::createFromAscii( 240 "PROPFIND" ), 241 aHeaders ); 242 243 m_xSession->PROPFIND( getRequestURI(), 244 nDepth, 245 rResInfo, 246 DAVRequestEnvironment( 247 getRequestURI(), 248 new DAVAuthListener_Impl( xEnv, m_aURL ), 249 aHeaders, xEnv ) ) ; 250 } 251 catch ( DAVException & e ) 252 { 253 errorCount++; 254 bRetry = handleException( e, errorCount ); 255 if ( !bRetry ) 256 throw; 257 } 258 } 259 while ( bRetry ); 260 } 261 262 //========================================================================= 263 void DAVResourceAccess::PROPPATCH( 264 const std::vector< ProppatchValue >& rValues, 265 const uno::Reference< ucb::XCommandEnvironment >& xEnv ) 266 throw( DAVException ) 267 { 268 initialize(); 269 270 int errorCount = 0; 271 bool bRetry; 272 do 273 { 274 bRetry = false; 275 try 276 { 277 DAVRequestHeaders aHeaders; 278 getUserRequestHeaders( xEnv, 279 getRequestURI(), 280 rtl::OUString::createFromAscii( 281 "PROPPATCH" ), 282 aHeaders ); 283 284 m_xSession->PROPPATCH( getRequestURI(), 285 rValues, 286 DAVRequestEnvironment( 287 getRequestURI(), 288 new DAVAuthListener_Impl( xEnv, m_aURL ), 289 aHeaders, xEnv ) ); 290 } 291 catch ( DAVException & e ) 292 { 293 errorCount++; 294 bRetry = handleException( e, errorCount ); 295 if ( !bRetry ) 296 throw; 297 } 298 } 299 while ( bRetry ); 300 } 301 302 //========================================================================= 303 void DAVResourceAccess::HEAD( 304 const std::vector< rtl::OUString > & rHeaderNames, 305 DAVResource & rResource, 306 const uno::Reference< ucb::XCommandEnvironment >& xEnv ) 307 throw( DAVException ) 308 { 309 initialize(); 310 311 int errorCount = 0; 312 bool bRetry; 313 do 314 { 315 bRetry = false; 316 try 317 { 318 DAVRequestHeaders aHeaders; 319 getUserRequestHeaders( xEnv, 320 getRequestURI(), 321 rtl::OUString::createFromAscii( "HEAD" ), 322 aHeaders ); 323 324 m_xSession->HEAD( getRequestURI(), 325 rHeaderNames, 326 rResource, 327 DAVRequestEnvironment( 328 getRequestURI(), 329 new DAVAuthListener_Impl( xEnv, m_aURL ), 330 aHeaders, xEnv ) ); 331 } 332 catch ( DAVException & e ) 333 { 334 errorCount++; 335 bRetry = handleException( e, errorCount ); 336 if ( !bRetry ) 337 throw; 338 } 339 } 340 while ( bRetry ); 341 } 342 343 //========================================================================= 344 uno::Reference< io::XInputStream > DAVResourceAccess::GET( 345 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 346 throw( DAVException ) 347 { 348 initialize(); 349 350 uno::Reference< io::XInputStream > xStream; 351 int errorCount = 0; 352 bool bRetry; 353 do 354 { 355 bRetry = false; 356 try 357 { 358 DAVRequestHeaders aHeaders; 359 getUserRequestHeaders( xEnv, 360 getRequestURI(), 361 rtl::OUString::createFromAscii( "GET" ), 362 aHeaders ); 363 364 xStream = m_xSession->GET( getRequestURI(), 365 DAVRequestEnvironment( 366 getRequestURI(), 367 new DAVAuthListener_Impl( 368 xEnv, m_aURL ), 369 aHeaders, xEnv ) ); 370 } 371 catch ( DAVException & e ) 372 { 373 errorCount++; 374 bRetry = handleException( e, errorCount ); 375 if ( !bRetry ) 376 throw; 377 } 378 } 379 while ( bRetry ); 380 381 return xStream; 382 } 383 384 //========================================================================= 385 void DAVResourceAccess::GET( 386 uno::Reference< io::XOutputStream > & rStream, 387 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 388 throw( DAVException ) 389 { 390 initialize(); 391 392 int errorCount = 0; 393 bool bRetry; 394 do 395 { 396 bRetry = false; 397 try 398 { 399 DAVRequestHeaders aHeaders; 400 getUserRequestHeaders( xEnv, 401 getRequestURI(), 402 rtl::OUString::createFromAscii( "GET" ), 403 aHeaders ); 404 405 m_xSession->GET( getRequestURI(), 406 rStream, 407 DAVRequestEnvironment( 408 getRequestURI(), 409 new DAVAuthListener_Impl( xEnv, m_aURL ), 410 aHeaders, xEnv ) ); 411 } 412 catch ( DAVException & e ) 413 { 414 errorCount++; 415 bRetry = handleException( e, errorCount ); 416 if ( !bRetry ) 417 throw; 418 } 419 } 420 while ( bRetry ); 421 } 422 423 //========================================================================= 424 uno::Reference< io::XInputStream > DAVResourceAccess::GET( 425 const std::vector< rtl::OUString > & rHeaderNames, 426 DAVResource & rResource, 427 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 428 throw( DAVException ) 429 { 430 initialize(); 431 432 uno::Reference< io::XInputStream > xStream; 433 int errorCount = 0; 434 bool bRetry; 435 do 436 { 437 bRetry = false; 438 try 439 { 440 DAVRequestHeaders aHeaders; 441 getUserRequestHeaders( xEnv, 442 getRequestURI(), 443 rtl::OUString::createFromAscii( "GET" ), 444 aHeaders ); 445 446 xStream = m_xSession->GET( getRequestURI(), 447 rHeaderNames, 448 rResource, 449 DAVRequestEnvironment( 450 getRequestURI(), 451 new DAVAuthListener_Impl( 452 xEnv, m_aURL ), 453 aHeaders, xEnv ) ); 454 } 455 catch ( DAVException & e ) 456 { 457 errorCount++; 458 bRetry = handleException( e, errorCount ); 459 if ( !bRetry ) 460 throw; 461 } 462 } 463 while ( bRetry ); 464 465 return xStream; 466 } 467 468 //========================================================================= 469 void DAVResourceAccess::GET( 470 uno::Reference< io::XOutputStream > & rStream, 471 const std::vector< rtl::OUString > & rHeaderNames, 472 DAVResource & rResource, 473 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 474 throw( DAVException ) 475 { 476 initialize(); 477 478 bool bRetry; 479 int errorCount = 0; 480 do 481 { 482 bRetry = false; 483 try 484 { 485 DAVRequestHeaders aHeaders; 486 getUserRequestHeaders( xEnv, 487 getRequestURI(), 488 rtl::OUString::createFromAscii( "GET" ), 489 aHeaders ); 490 491 m_xSession->GET( getRequestURI(), 492 rStream, 493 rHeaderNames, 494 rResource, 495 DAVRequestEnvironment( 496 getRequestURI(), 497 new DAVAuthListener_Impl( xEnv, m_aURL ), 498 aHeaders, xEnv ) ); 499 } 500 catch ( DAVException & e ) 501 { 502 errorCount++; 503 bRetry = handleException( e, errorCount ); 504 if ( !bRetry ) 505 throw; 506 } 507 } 508 while ( bRetry ); 509 } 510 511 //========================================================================= 512 void DAVResourceAccess::abort() 513 throw( DAVException ) 514 { 515 // 17.11.09 (tkr): abort currently disabled caused by issue i106766 516 // initialize(); 517 // m_xSession->abort(); 518 OSL_TRACE( "Not implemented. -> #i106766#" ); 519 } 520 521 //========================================================================= 522 namespace { 523 524 void resetInputStream( const uno::Reference< io::XInputStream > & rStream ) 525 throw( DAVException ) 526 { 527 try 528 { 529 uno::Reference< io::XSeekable > xSeekable( 530 rStream, uno::UNO_QUERY ); 531 if ( xSeekable.is() ) 532 { 533 xSeekable->seek( 0 ); 534 return; 535 } 536 } 537 catch ( lang::IllegalArgumentException const & ) 538 { 539 } 540 catch ( io::IOException const & ) 541 { 542 } 543 544 throw DAVException( DAVException::DAV_INVALID_ARG ); 545 } 546 547 } // namespace 548 549 //========================================================================= 550 void DAVResourceAccess::PUT( 551 const uno::Reference< io::XInputStream > & rStream, 552 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 553 throw( DAVException ) 554 { 555 initialize(); 556 557 // Make stream seekable, if it not. Needed, if request must be retried. 558 uno::Reference< io::XInputStream > xSeekableStream 559 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( 560 rStream, m_xSMgr ); 561 562 int errorCount = 0; 563 bool bRetry = false; 564 do 565 { 566 if ( bRetry ) 567 resetInputStream( xSeekableStream ); 568 569 bRetry = false; 570 try 571 { 572 DAVRequestHeaders aHeaders; 573 getUserRequestHeaders( xEnv, 574 getRequestURI(), 575 rtl::OUString::createFromAscii( "PUT" ), 576 aHeaders ); 577 578 m_xSession->PUT( getRequestURI(), 579 xSeekableStream, 580 DAVRequestEnvironment( 581 getRequestURI(), 582 new DAVAuthListener_Impl( xEnv, m_aURL ), 583 aHeaders, xEnv ) ); 584 } 585 catch ( DAVException & e ) 586 { 587 errorCount++; 588 bRetry = handleException( e, errorCount ); 589 if ( !bRetry ) 590 throw; 591 } 592 } 593 while ( bRetry ); 594 } 595 596 //========================================================================= 597 uno::Reference< io::XInputStream > DAVResourceAccess::POST( 598 const rtl::OUString & rContentType, 599 const rtl::OUString & rReferer, 600 const uno::Reference< io::XInputStream > & rInputStream, 601 const uno::Reference< ucb::XCommandEnvironment >& xEnv ) 602 throw ( DAVException ) 603 { 604 initialize(); 605 606 // Make stream seekable, if it not. Needed, if request must be retried. 607 uno::Reference< io::XInputStream > xSeekableStream 608 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( 609 rInputStream, m_xSMgr ); 610 611 uno::Reference< io::XInputStream > xStream; 612 int errorCount = 0; 613 bool bRetry = false; 614 do 615 { 616 if ( bRetry ) 617 { 618 resetInputStream( xSeekableStream ); 619 bRetry = false; 620 } 621 622 try 623 { 624 DAVRequestHeaders aHeaders; 625 getUserRequestHeaders( xEnv, 626 getRequestURI(), 627 rtl::OUString::createFromAscii( "POST" ), 628 aHeaders ); 629 630 xStream = m_xSession->POST( getRequestURI(), 631 rContentType, 632 rReferer, 633 xSeekableStream, 634 DAVRequestEnvironment( 635 getRequestURI(), 636 new DAVAuthListener_Impl( 637 xEnv, m_aURL ), 638 aHeaders, xEnv ) ); 639 } 640 catch ( DAVException & e ) 641 { 642 errorCount++; 643 bRetry = handleException( e, errorCount ); 644 if ( !bRetry ) 645 throw; 646 647 if ( e.getError() == DAVException::DAV_HTTP_REDIRECT ) 648 { 649 // #i74980# - Upon POST redirect, do a GET. 650 return GET( xEnv ); 651 } 652 } 653 } 654 while ( bRetry ); 655 656 return xStream; 657 } 658 659 //========================================================================= 660 void DAVResourceAccess::POST( 661 const rtl::OUString & rContentType, 662 const rtl::OUString & rReferer, 663 const uno::Reference< io::XInputStream > & rInputStream, 664 uno::Reference< io::XOutputStream > & rOutputStream, 665 const uno::Reference< ucb::XCommandEnvironment >& xEnv ) 666 throw ( DAVException ) 667 { 668 initialize(); 669 670 // Make stream seekable, if it not. Needed, if request must be retried. 671 uno::Reference< io::XInputStream > xSeekableStream 672 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( 673 rInputStream, m_xSMgr ); 674 675 int errorCount = 0; 676 bool bRetry = false; 677 do 678 { 679 if ( bRetry ) 680 { 681 resetInputStream( xSeekableStream ); 682 bRetry = false; 683 } 684 685 try 686 { 687 DAVRequestHeaders aHeaders; 688 getUserRequestHeaders( xEnv, 689 getRequestURI(), 690 rtl::OUString::createFromAscii( "POST" ), 691 aHeaders ); 692 693 m_xSession->POST( getRequestURI(), 694 rContentType, 695 rReferer, 696 xSeekableStream, 697 rOutputStream, 698 DAVRequestEnvironment( 699 getRequestURI(), 700 new DAVAuthListener_Impl( xEnv, m_aURL ), 701 aHeaders, xEnv ) ); 702 } 703 catch ( DAVException & e ) 704 { 705 errorCount++; 706 bRetry = handleException( e, errorCount ); 707 if ( !bRetry ) 708 throw; 709 710 if ( e.getError() == DAVException::DAV_HTTP_REDIRECT ) 711 { 712 // #i74980# - Upon POST redirect, do a GET. 713 GET( rOutputStream, xEnv ); 714 return; 715 } 716 } 717 } 718 while ( bRetry ); 719 } 720 721 //========================================================================= 722 void DAVResourceAccess::MKCOL( 723 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 724 throw( DAVException ) 725 { 726 initialize(); 727 728 int errorCount = 0; 729 bool bRetry; 730 do 731 { 732 bRetry = false; 733 try 734 { 735 DAVRequestHeaders aHeaders; 736 getUserRequestHeaders( xEnv, 737 getRequestURI(), 738 rtl::OUString::createFromAscii( "MKCOL" ), 739 aHeaders ); 740 741 m_xSession->MKCOL( getRequestURI(), 742 DAVRequestEnvironment( 743 getRequestURI(), 744 new DAVAuthListener_Impl( xEnv, m_aURL ), 745 aHeaders, xEnv ) ); 746 } 747 catch ( DAVException & e ) 748 { 749 errorCount++; 750 bRetry = handleException( e, errorCount ); 751 if ( !bRetry ) 752 throw; 753 } 754 } 755 while ( bRetry ); 756 } 757 758 //========================================================================= 759 void DAVResourceAccess::COPY( 760 const ::rtl::OUString & rSourcePath, 761 const ::rtl::OUString & rDestinationURI, 762 sal_Bool bOverwrite, 763 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 764 throw( DAVException ) 765 { 766 initialize(); 767 768 int errorCount = 0; 769 bool bRetry; 770 do 771 { 772 bRetry = false; 773 try 774 { 775 DAVRequestHeaders aHeaders; 776 getUserRequestHeaders( xEnv, 777 getRequestURI(), 778 rtl::OUString::createFromAscii( "COPY" ), 779 aHeaders ); 780 781 m_xSession->COPY( rSourcePath, 782 rDestinationURI, 783 DAVRequestEnvironment( 784 getRequestURI(), 785 new DAVAuthListener_Impl( xEnv, m_aURL ), 786 aHeaders, xEnv ), 787 bOverwrite ); 788 } 789 catch ( DAVException & e ) 790 { 791 errorCount++; 792 bRetry = handleException( e, errorCount ); 793 if ( !bRetry ) 794 throw; 795 } 796 } 797 while ( bRetry ); 798 } 799 800 //========================================================================= 801 void DAVResourceAccess::MOVE( 802 const ::rtl::OUString & rSourcePath, 803 const ::rtl::OUString & rDestinationURI, 804 sal_Bool bOverwrite, 805 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 806 throw( DAVException ) 807 { 808 initialize(); 809 810 int errorCount = 0; 811 bool bRetry; 812 do 813 { 814 bRetry = false; 815 try 816 { 817 DAVRequestHeaders aHeaders; 818 getUserRequestHeaders( xEnv, 819 getRequestURI(), 820 rtl::OUString::createFromAscii( "MOVE" ), 821 aHeaders ); 822 823 m_xSession->MOVE( rSourcePath, 824 rDestinationURI, 825 DAVRequestEnvironment( 826 getRequestURI(), 827 new DAVAuthListener_Impl( xEnv, m_aURL ), 828 aHeaders, xEnv ), 829 bOverwrite ); 830 } 831 catch ( DAVException & e ) 832 { 833 errorCount++; 834 bRetry = handleException( e, errorCount ); 835 if ( !bRetry ) 836 throw; 837 } 838 } 839 while ( bRetry ); 840 } 841 842 //========================================================================= 843 void DAVResourceAccess::DESTROY( 844 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 845 throw( DAVException ) 846 { 847 initialize(); 848 849 int errorCount = 0; 850 bool bRetry; 851 do 852 { 853 bRetry = false; 854 try 855 { 856 DAVRequestHeaders aHeaders; 857 getUserRequestHeaders( xEnv, 858 getRequestURI(), 859 rtl::OUString::createFromAscii( 860 "DESTROY" ), 861 aHeaders ); 862 863 m_xSession->DESTROY( getRequestURI(), 864 DAVRequestEnvironment( 865 getRequestURI(), 866 new DAVAuthListener_Impl( xEnv, m_aURL ), 867 aHeaders, xEnv ) ); 868 } 869 catch ( DAVException & e ) 870 { 871 errorCount++; 872 bRetry = handleException( e, errorCount ); 873 if ( !bRetry ) 874 throw; 875 } 876 } 877 while ( bRetry ); 878 } 879 880 //========================================================================= 881 // set new lock. 882 void DAVResourceAccess::LOCK( 883 ucb::Lock & inLock, 884 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 885 throw ( DAVException ) 886 { 887 initialize(); 888 889 int errorCount = 0; 890 bool bRetry; 891 do 892 { 893 bRetry = false; 894 try 895 { 896 DAVRequestHeaders aHeaders; 897 getUserRequestHeaders( xEnv, 898 getRequestURI(), 899 rtl::OUString::createFromAscii( "LOCK" ), 900 aHeaders ); 901 902 m_xSession->LOCK( getRequestURI(), 903 inLock, 904 DAVRequestEnvironment( 905 getRequestURI(), 906 new DAVAuthListener_Impl( xEnv, m_aURL ), 907 aHeaders, xEnv ) ); 908 } 909 catch ( DAVException & e ) 910 { 911 errorCount++; 912 bRetry = handleException( e, errorCount ); 913 if ( !bRetry ) 914 throw; 915 } 916 } 917 while ( bRetry ); 918 } 919 920 #if 0 // currently not used, but please don't remove code 921 //========================================================================= 922 // refresh existing lock. 923 sal_Int64 DAVResourceAccess::LOCK( 924 sal_Int64 nTimeout, 925 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 926 throw ( DAVException ) 927 { 928 initialize(); 929 930 sal_Int64 nNewTimeout = 0; 931 int errorCount = 0; 932 bool bRetry; 933 do 934 { 935 bRetry = false; 936 try 937 { 938 DAVRequestHeaders aHeaders; 939 getUserRequestHeaders( xEnv, 940 getRequestURI(), 941 rtl::OUString::createFromAscii( "LOCK" ), 942 aHeaders ); 943 944 nNewTimeout = m_xSession->LOCK( getRequestURI(), 945 nTimeout, 946 DAVRequestEnvironment( 947 getRequestURI(), 948 new DAVAuthListener_Impl( 949 xEnv, m_aURL ), 950 aHeaders, xEnv ) ); 951 } 952 catch ( DAVException & e ) 953 { 954 errorCount++; 955 bRetry = handleException( e, errorCount ); 956 if ( !bRetry ) 957 throw; 958 } 959 } 960 while ( bRetry ); 961 962 return nNewTimeout; 963 } 964 #endif 965 966 //========================================================================= 967 void DAVResourceAccess::UNLOCK( 968 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 969 throw ( DAVException ) 970 { 971 initialize(); 972 973 int errorCount = 0; 974 bool bRetry; 975 do 976 { 977 bRetry = false; 978 try 979 { 980 DAVRequestHeaders aHeaders; 981 getUserRequestHeaders( xEnv, 982 getRequestURI(), 983 rtl::OUString::createFromAscii( "UNLOCK" ), 984 aHeaders ); 985 986 m_xSession->UNLOCK( getRequestURI(), 987 DAVRequestEnvironment( 988 getRequestURI(), 989 new DAVAuthListener_Impl( xEnv, m_aURL ), 990 aHeaders, xEnv ) ); 991 } 992 catch ( DAVException & e ) 993 { 994 errorCount++; 995 bRetry = handleException( e, errorCount ); 996 if ( !bRetry ) 997 throw; 998 } 999 } 1000 while ( bRetry ); 1001 } 1002 1003 //========================================================================= 1004 void DAVResourceAccess::setURL( const rtl::OUString & rNewURL ) 1005 throw( DAVException ) 1006 { 1007 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1008 m_aURL = rNewURL; 1009 m_aPath = rtl::OUString(); // Next initialize() will create new session. 1010 } 1011 1012 //========================================================================= 1013 // init dav session and path 1014 void DAVResourceAccess::initialize() 1015 throw ( DAVException ) 1016 { 1017 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1018 if ( m_aPath.getLength() == 0 ) 1019 { 1020 SerfUri aURI( m_aURL ); 1021 rtl::OUString aPath( aURI.GetPath() ); 1022 1023 /* #134089# - Check URI */ 1024 if ( !aPath.getLength() ) 1025 throw DAVException( DAVException::DAV_INVALID_ARG ); 1026 1027 /* #134089# - Check URI */ 1028 if ( !aURI.GetHost().getLength() ) 1029 throw DAVException( DAVException::DAV_INVALID_ARG ); 1030 1031 if ( !m_xSession.is() || !m_xSession->CanUse( m_aURL ) ) 1032 { 1033 m_xSession.clear(); 1034 1035 // create new webdav session 1036 m_xSession 1037 = m_xSessionFactory->createDAVSession( m_aURL, m_xSMgr ); 1038 1039 if ( !m_xSession.is() ) 1040 return; 1041 } 1042 1043 // Own URI is needed for redirect cycle detection. 1044 m_aRedirectURIs.push_back( aURI ); 1045 1046 // Success. 1047 m_aPath = aPath; 1048 1049 // Not only the path has to be encoded 1050 m_aURL = aURI.GetURI(); 1051 } 1052 } 1053 1054 //========================================================================= 1055 const rtl::OUString & DAVResourceAccess::getRequestURI() const 1056 { 1057 OSL_ENSURE( m_xSession.is(), 1058 "DAVResourceAccess::getRequestURI - Not initialized!" ); 1059 1060 // In case a proxy is used we have to use the absolute URI for a request. 1061 if ( m_xSession->UsesProxy() ) 1062 return m_aURL; 1063 1064 return m_aPath; 1065 } 1066 1067 //========================================================================= 1068 // static 1069 void DAVResourceAccess::getUserRequestHeaders( 1070 const uno::Reference< ucb::XCommandEnvironment > & xEnv, 1071 const rtl::OUString & rURI, 1072 const rtl::OUString & rMethod, 1073 DAVRequestHeaders & rRequestHeaders ) 1074 { 1075 if ( xEnv.is() ) 1076 { 1077 uno::Reference< ucb::XWebDAVCommandEnvironment > xDAVEnv( 1078 xEnv, uno::UNO_QUERY ); 1079 1080 if ( xDAVEnv.is() ) 1081 { 1082 uno::Sequence< beans::NamedValue > aRequestHeaders 1083 = xDAVEnv->getUserRequestHeaders( rURI, rMethod ); 1084 1085 for ( sal_Int32 n = 0; n < aRequestHeaders.getLength(); ++n ) 1086 { 1087 rtl::OUString aValue; 1088 sal_Bool isString = aRequestHeaders[ n ].Value >>= aValue; 1089 1090 if ( !isString ) 1091 { 1092 OSL_ENSURE( isString, 1093 "DAVResourceAccess::getUserRequestHeaders :" 1094 "Value is not a string! Ignoring..." ); 1095 } 1096 1097 rRequestHeaders.push_back( 1098 DAVRequestHeader( aRequestHeaders[ n ].Name, aValue ) ); 1099 } 1100 } 1101 } 1102 } 1103 1104 //========================================================================= 1105 sal_Bool DAVResourceAccess::detectRedirectCycle( 1106 const rtl::OUString& rRedirectURL ) 1107 throw ( DAVException ) 1108 { 1109 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1110 1111 SerfUri aUri( rRedirectURL ); 1112 1113 std::vector< SerfUri >::const_iterator it = m_aRedirectURIs.begin(); 1114 std::vector< SerfUri >::const_iterator end = m_aRedirectURIs.end(); 1115 1116 while ( it != end ) 1117 { 1118 if ( aUri == (*it) ) 1119 return sal_True; 1120 1121 it++; 1122 } 1123 1124 return sal_False; 1125 } 1126 1127 //========================================================================= 1128 void DAVResourceAccess::resetUri() 1129 { 1130 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1131 if ( m_aRedirectURIs.size() > 0 ) 1132 { 1133 std::vector< SerfUri >::const_iterator it = m_aRedirectURIs.begin(); 1134 1135 SerfUri aUri( (*it) ); 1136 m_aRedirectURIs.clear(); 1137 setURL ( aUri.GetURI() ); 1138 initialize(); 1139 } 1140 } 1141 1142 //========================================================================= 1143 sal_Bool DAVResourceAccess::handleException( DAVException & e, int errorCount ) 1144 throw ( DAVException ) 1145 { 1146 switch ( e.getError() ) 1147 { 1148 case DAVException::DAV_HTTP_REDIRECT: 1149 if ( !detectRedirectCycle( e.getData() ) ) 1150 { 1151 // set new URL and path. 1152 setURL( e.getData() ); 1153 initialize(); 1154 return sal_True; 1155 } 1156 return sal_False; 1157 // --> tkr #67048# copy & paste images doesn't display. 1158 // if we have a bad connection try again. Up to three times. 1159 case DAVException::DAV_HTTP_ERROR: 1160 // retry up to three times, if not a client-side error. 1161 if ( ( e.getStatus() < 400 || e.getStatus() >= 500 ) && 1162 errorCount < 3 ) 1163 { 1164 return sal_True; 1165 } 1166 return sal_False; 1167 // <-- 1168 // --> tkr: if connection has said retry then retry! 1169 case DAVException::DAV_HTTP_RETRY: 1170 return sal_True; 1171 // <-- 1172 default: 1173 return sal_False; // Abort 1174 } 1175 } 1176