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 uno::Reference< io::XInputStream > DAVResourceAccess::GET( 470 DAVRequestHeaders &rRequestHeaders, 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 uno::Reference< io::XInputStream > xStream; 479 int errorCount = 0; 480 bool bRetry; 481 do 482 { 483 bRetry = false; 484 try 485 { 486 getUserRequestHeaders( xEnv, 487 getRequestURI(), 488 rtl::OUString::createFromAscii( "GET" ), 489 rRequestHeaders ); 490 491 xStream = m_xSession->GET( getRequestURI(), 492 rHeaderNames, 493 rResource, 494 DAVRequestEnvironment( 495 getRequestURI(), 496 new DAVAuthListener_Impl( 497 xEnv, m_aURL ), 498 rRequestHeaders, 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 return xStream; 511 } 512 513 //========================================================================= 514 void DAVResourceAccess::GET( 515 uno::Reference< io::XOutputStream > & rStream, 516 const std::vector< rtl::OUString > & rHeaderNames, 517 DAVResource & rResource, 518 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 519 throw( DAVException ) 520 { 521 initialize(); 522 523 bool bRetry; 524 int errorCount = 0; 525 do 526 { 527 bRetry = false; 528 try 529 { 530 DAVRequestHeaders aHeaders; 531 getUserRequestHeaders( xEnv, 532 getRequestURI(), 533 rtl::OUString::createFromAscii( "GET" ), 534 aHeaders ); 535 536 m_xSession->GET( getRequestURI(), 537 rStream, 538 rHeaderNames, 539 rResource, 540 DAVRequestEnvironment( 541 getRequestURI(), 542 new DAVAuthListener_Impl( xEnv, m_aURL ), 543 aHeaders, xEnv ) ); 544 } 545 catch ( DAVException & e ) 546 { 547 errorCount++; 548 bRetry = handleException( e, errorCount ); 549 if ( !bRetry ) 550 throw; 551 } 552 } 553 while ( bRetry ); 554 } 555 556 //========================================================================= 557 void DAVResourceAccess::abort() 558 throw( DAVException ) 559 { 560 // 17.11.09 (tkr): abort currently disabled caused by issue i106766 561 // initialize(); 562 // m_xSession->abort(); 563 OSL_TRACE( "Not implemented. -> #i106766#" ); 564 } 565 566 //========================================================================= 567 namespace { 568 569 void resetInputStream( const uno::Reference< io::XInputStream > & rStream ) 570 throw( DAVException ) 571 { 572 try 573 { 574 uno::Reference< io::XSeekable > xSeekable( 575 rStream, uno::UNO_QUERY ); 576 if ( xSeekable.is() ) 577 { 578 xSeekable->seek( 0 ); 579 return; 580 } 581 } 582 catch ( lang::IllegalArgumentException const & ) 583 { 584 } 585 catch ( io::IOException const & ) 586 { 587 } 588 589 throw DAVException( DAVException::DAV_INVALID_ARG ); 590 } 591 592 } // namespace 593 594 //========================================================================= 595 void DAVResourceAccess::PUT( 596 const uno::Reference< io::XInputStream > & rStream, 597 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 598 throw( DAVException ) 599 { 600 initialize(); 601 602 // Make stream seekable, if it not. Needed, if request must be retried. 603 uno::Reference< io::XInputStream > xSeekableStream 604 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( 605 rStream, m_xSMgr ); 606 607 int errorCount = 0; 608 bool bRetry = false; 609 do 610 { 611 if ( bRetry ) 612 resetInputStream( xSeekableStream ); 613 614 bRetry = false; 615 try 616 { 617 DAVRequestHeaders aHeaders; 618 getUserRequestHeaders( xEnv, 619 getRequestURI(), 620 rtl::OUString::createFromAscii( "PUT" ), 621 aHeaders ); 622 623 m_xSession->PUT( getRequestURI(), 624 xSeekableStream, 625 DAVRequestEnvironment( 626 getRequestURI(), 627 new DAVAuthListener_Impl( xEnv, m_aURL ), 628 aHeaders, xEnv ) ); 629 } 630 catch ( DAVException & e ) 631 { 632 errorCount++; 633 bRetry = handleException( e, errorCount ); 634 if ( !bRetry ) 635 throw; 636 } 637 } 638 while ( bRetry ); 639 } 640 641 //========================================================================= 642 uno::Reference< io::XInputStream > DAVResourceAccess::POST( 643 const rtl::OUString & rContentType, 644 const rtl::OUString & rReferer, 645 const uno::Reference< io::XInputStream > & rInputStream, 646 const uno::Reference< ucb::XCommandEnvironment >& xEnv ) 647 throw ( DAVException ) 648 { 649 initialize(); 650 651 // Make stream seekable, if it not. Needed, if request must be retried. 652 uno::Reference< io::XInputStream > xSeekableStream 653 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( 654 rInputStream, m_xSMgr ); 655 656 uno::Reference< io::XInputStream > xStream; 657 int errorCount = 0; 658 bool bRetry = false; 659 do 660 { 661 if ( bRetry ) 662 { 663 resetInputStream( xSeekableStream ); 664 bRetry = false; 665 } 666 667 try 668 { 669 DAVRequestHeaders aHeaders; 670 getUserRequestHeaders( xEnv, 671 getRequestURI(), 672 rtl::OUString::createFromAscii( "POST" ), 673 aHeaders ); 674 675 xStream = m_xSession->POST( getRequestURI(), 676 rContentType, 677 rReferer, 678 xSeekableStream, 679 DAVRequestEnvironment( 680 getRequestURI(), 681 new DAVAuthListener_Impl( 682 xEnv, m_aURL ), 683 aHeaders, xEnv ) ); 684 } 685 catch ( DAVException & e ) 686 { 687 errorCount++; 688 bRetry = handleException( e, errorCount ); 689 if ( !bRetry ) 690 throw; 691 692 if ( e.getError() == DAVException::DAV_HTTP_REDIRECT ) 693 { 694 // #i74980# - Upon POST redirect, do a GET. 695 return GET( xEnv ); 696 } 697 } 698 } 699 while ( bRetry ); 700 701 return xStream; 702 } 703 704 //========================================================================= 705 void DAVResourceAccess::POST( 706 const rtl::OUString & rContentType, 707 const rtl::OUString & rReferer, 708 const uno::Reference< io::XInputStream > & rInputStream, 709 uno::Reference< io::XOutputStream > & rOutputStream, 710 const uno::Reference< ucb::XCommandEnvironment >& xEnv ) 711 throw ( DAVException ) 712 { 713 initialize(); 714 715 // Make stream seekable, if it not. Needed, if request must be retried. 716 uno::Reference< io::XInputStream > xSeekableStream 717 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( 718 rInputStream, m_xSMgr ); 719 720 int errorCount = 0; 721 bool bRetry = false; 722 do 723 { 724 if ( bRetry ) 725 { 726 resetInputStream( xSeekableStream ); 727 bRetry = false; 728 } 729 730 try 731 { 732 DAVRequestHeaders aHeaders; 733 getUserRequestHeaders( xEnv, 734 getRequestURI(), 735 rtl::OUString::createFromAscii( "POST" ), 736 aHeaders ); 737 738 m_xSession->POST( getRequestURI(), 739 rContentType, 740 rReferer, 741 xSeekableStream, 742 rOutputStream, 743 DAVRequestEnvironment( 744 getRequestURI(), 745 new DAVAuthListener_Impl( xEnv, m_aURL ), 746 aHeaders, xEnv ) ); 747 } 748 catch ( DAVException & e ) 749 { 750 errorCount++; 751 bRetry = handleException( e, errorCount ); 752 if ( !bRetry ) 753 throw; 754 755 if ( e.getError() == DAVException::DAV_HTTP_REDIRECT ) 756 { 757 // #i74980# - Upon POST redirect, do a GET. 758 GET( rOutputStream, xEnv ); 759 return; 760 } 761 } 762 } 763 while ( bRetry ); 764 } 765 766 //========================================================================= 767 void DAVResourceAccess::MKCOL( 768 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 769 throw( DAVException ) 770 { 771 initialize(); 772 773 int errorCount = 0; 774 bool bRetry; 775 do 776 { 777 bRetry = false; 778 try 779 { 780 DAVRequestHeaders aHeaders; 781 getUserRequestHeaders( xEnv, 782 getRequestURI(), 783 rtl::OUString::createFromAscii( "MKCOL" ), 784 aHeaders ); 785 786 m_xSession->MKCOL( getRequestURI(), 787 DAVRequestEnvironment( 788 getRequestURI(), 789 new DAVAuthListener_Impl( xEnv, m_aURL ), 790 aHeaders, xEnv ) ); 791 } 792 catch ( DAVException & e ) 793 { 794 errorCount++; 795 bRetry = handleException( e, errorCount ); 796 if ( !bRetry ) 797 throw; 798 } 799 } 800 while ( bRetry ); 801 } 802 803 //========================================================================= 804 void DAVResourceAccess::COPY( 805 const ::rtl::OUString & rSourcePath, 806 const ::rtl::OUString & rDestinationURI, 807 sal_Bool bOverwrite, 808 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 809 throw( DAVException ) 810 { 811 initialize(); 812 813 int errorCount = 0; 814 bool bRetry; 815 do 816 { 817 bRetry = false; 818 try 819 { 820 DAVRequestHeaders aHeaders; 821 getUserRequestHeaders( xEnv, 822 getRequestURI(), 823 rtl::OUString::createFromAscii( "COPY" ), 824 aHeaders ); 825 826 m_xSession->COPY( rSourcePath, 827 rDestinationURI, 828 DAVRequestEnvironment( 829 getRequestURI(), 830 new DAVAuthListener_Impl( xEnv, m_aURL ), 831 aHeaders, xEnv ), 832 bOverwrite ); 833 } 834 catch ( DAVException & e ) 835 { 836 errorCount++; 837 bRetry = handleException( e, errorCount ); 838 if ( !bRetry ) 839 throw; 840 } 841 } 842 while ( bRetry ); 843 } 844 845 //========================================================================= 846 void DAVResourceAccess::MOVE( 847 const ::rtl::OUString & rSourcePath, 848 const ::rtl::OUString & rDestinationURI, 849 sal_Bool bOverwrite, 850 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 851 throw( DAVException ) 852 { 853 initialize(); 854 855 int errorCount = 0; 856 bool bRetry; 857 do 858 { 859 bRetry = false; 860 try 861 { 862 DAVRequestHeaders aHeaders; 863 getUserRequestHeaders( xEnv, 864 getRequestURI(), 865 rtl::OUString::createFromAscii( "MOVE" ), 866 aHeaders ); 867 868 m_xSession->MOVE( rSourcePath, 869 rDestinationURI, 870 DAVRequestEnvironment( 871 getRequestURI(), 872 new DAVAuthListener_Impl( xEnv, m_aURL ), 873 aHeaders, xEnv ), 874 bOverwrite ); 875 } 876 catch ( DAVException & e ) 877 { 878 errorCount++; 879 bRetry = handleException( e, errorCount ); 880 if ( !bRetry ) 881 throw; 882 } 883 } 884 while ( bRetry ); 885 } 886 887 //========================================================================= 888 void DAVResourceAccess::DESTROY( 889 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 890 throw( DAVException ) 891 { 892 initialize(); 893 894 int errorCount = 0; 895 bool bRetry; 896 do 897 { 898 bRetry = false; 899 try 900 { 901 DAVRequestHeaders aHeaders; 902 getUserRequestHeaders( xEnv, 903 getRequestURI(), 904 rtl::OUString::createFromAscii( 905 "DESTROY" ), 906 aHeaders ); 907 908 m_xSession->DESTROY( getRequestURI(), 909 DAVRequestEnvironment( 910 getRequestURI(), 911 new DAVAuthListener_Impl( xEnv, m_aURL ), 912 aHeaders, xEnv ) ); 913 } 914 catch ( DAVException & e ) 915 { 916 errorCount++; 917 bRetry = handleException( e, errorCount ); 918 if ( !bRetry ) 919 throw; 920 } 921 } 922 while ( bRetry ); 923 } 924 925 //========================================================================= 926 // set new lock. 927 void DAVResourceAccess::LOCK( 928 ucb::Lock & inLock, 929 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 930 throw ( DAVException ) 931 { 932 initialize(); 933 934 int errorCount = 0; 935 bool bRetry; 936 do 937 { 938 bRetry = false; 939 try 940 { 941 DAVRequestHeaders aHeaders; 942 getUserRequestHeaders( xEnv, 943 getRequestURI(), 944 rtl::OUString::createFromAscii( "LOCK" ), 945 aHeaders ); 946 947 m_xSession->LOCK( getRequestURI(), 948 inLock, 949 DAVRequestEnvironment( 950 getRequestURI(), 951 new DAVAuthListener_Impl( xEnv, m_aURL ), 952 aHeaders, xEnv ) ); 953 } 954 catch ( DAVException & e ) 955 { 956 errorCount++; 957 bRetry = handleException( e, errorCount ); 958 if ( !bRetry ) 959 throw; 960 } 961 } 962 while ( bRetry ); 963 } 964 965 #if 0 // currently not used, but please don't remove code 966 //========================================================================= 967 // refresh existing lock. 968 sal_Int64 DAVResourceAccess::LOCK( 969 sal_Int64 nTimeout, 970 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 971 throw ( DAVException ) 972 { 973 initialize(); 974 975 sal_Int64 nNewTimeout = 0; 976 int errorCount = 0; 977 bool bRetry; 978 do 979 { 980 bRetry = false; 981 try 982 { 983 DAVRequestHeaders aHeaders; 984 getUserRequestHeaders( xEnv, 985 getRequestURI(), 986 rtl::OUString::createFromAscii( "LOCK" ), 987 aHeaders ); 988 989 nNewTimeout = m_xSession->LOCK( getRequestURI(), 990 nTimeout, 991 DAVRequestEnvironment( 992 getRequestURI(), 993 new DAVAuthListener_Impl( 994 xEnv, m_aURL ), 995 aHeaders, xEnv ) ); 996 } 997 catch ( DAVException & e ) 998 { 999 errorCount++; 1000 bRetry = handleException( e, errorCount ); 1001 if ( !bRetry ) 1002 throw; 1003 } 1004 } 1005 while ( bRetry ); 1006 1007 return nNewTimeout; 1008 } 1009 #endif 1010 1011 //========================================================================= 1012 void DAVResourceAccess::UNLOCK( 1013 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 1014 throw ( DAVException ) 1015 { 1016 initialize(); 1017 1018 int errorCount = 0; 1019 bool bRetry; 1020 do 1021 { 1022 bRetry = false; 1023 try 1024 { 1025 DAVRequestHeaders aHeaders; 1026 getUserRequestHeaders( xEnv, 1027 getRequestURI(), 1028 rtl::OUString::createFromAscii( "UNLOCK" ), 1029 aHeaders ); 1030 1031 m_xSession->UNLOCK( getRequestURI(), 1032 DAVRequestEnvironment( 1033 getRequestURI(), 1034 new DAVAuthListener_Impl( xEnv, m_aURL ), 1035 aHeaders, xEnv ) ); 1036 } 1037 catch ( DAVException & e ) 1038 { 1039 errorCount++; 1040 bRetry = handleException( e, errorCount ); 1041 if ( !bRetry ) 1042 throw; 1043 } 1044 } 1045 while ( bRetry ); 1046 } 1047 1048 //========================================================================= 1049 void DAVResourceAccess::setURL( const rtl::OUString & rNewURL ) 1050 throw( DAVException ) 1051 { 1052 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1053 m_aURL = rNewURL; 1054 m_aPath = rtl::OUString(); // Next initialize() will create new session. 1055 } 1056 1057 //========================================================================= 1058 // init dav session and path 1059 void DAVResourceAccess::initialize() 1060 throw ( DAVException ) 1061 { 1062 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1063 if ( m_aPath.getLength() == 0 ) 1064 { 1065 SerfUri aURI( m_aURL ); 1066 rtl::OUString aPath( aURI.GetPath() ); 1067 1068 /* #134089# - Check URI */ 1069 if ( !aPath.getLength() ) 1070 throw DAVException( DAVException::DAV_INVALID_ARG ); 1071 1072 /* #134089# - Check URI */ 1073 if ( !aURI.GetHost().getLength() ) 1074 throw DAVException( DAVException::DAV_INVALID_ARG ); 1075 1076 if ( !m_xSession.is() || !m_xSession->CanUse( m_aURL ) ) 1077 { 1078 m_xSession.clear(); 1079 1080 // create new webdav session 1081 m_xSession 1082 = m_xSessionFactory->createDAVSession( m_aURL, m_xSMgr ); 1083 1084 if ( !m_xSession.is() ) 1085 return; 1086 } 1087 1088 // Own URI is needed for redirect cycle detection. 1089 m_aRedirectURIs.push_back( aURI ); 1090 1091 // Success. 1092 m_aPath = aPath; 1093 1094 // Not only the path has to be encoded 1095 m_aURL = aURI.GetURI(); 1096 } 1097 } 1098 1099 //========================================================================= 1100 const rtl::OUString & DAVResourceAccess::getRequestURI() const 1101 { 1102 OSL_ENSURE( m_xSession.is(), 1103 "DAVResourceAccess::getRequestURI - Not initialized!" ); 1104 1105 // In case a proxy is used we have to use the absolute URI for a request. 1106 if ( m_xSession->UsesProxy() ) 1107 return m_aURL; 1108 1109 return m_aPath; 1110 } 1111 1112 //========================================================================= 1113 // static 1114 void DAVResourceAccess::getUserRequestHeaders( 1115 const uno::Reference< ucb::XCommandEnvironment > & xEnv, 1116 const rtl::OUString & rURI, 1117 const rtl::OUString & rMethod, 1118 DAVRequestHeaders & rRequestHeaders ) 1119 { 1120 if ( xEnv.is() ) 1121 { 1122 uno::Reference< ucb::XWebDAVCommandEnvironment > xDAVEnv( 1123 xEnv, uno::UNO_QUERY ); 1124 1125 if ( xDAVEnv.is() ) 1126 { 1127 uno::Sequence< beans::NamedValue > aRequestHeaders 1128 = xDAVEnv->getUserRequestHeaders( rURI, rMethod ); 1129 1130 for ( sal_Int32 n = 0; n < aRequestHeaders.getLength(); ++n ) 1131 { 1132 rtl::OUString aValue; 1133 sal_Bool isString = aRequestHeaders[ n ].Value >>= aValue; 1134 1135 if ( !isString ) 1136 { 1137 OSL_ENSURE( isString, 1138 "DAVResourceAccess::getUserRequestHeaders :" 1139 "Value is not a string! Ignoring..." ); 1140 } 1141 1142 rRequestHeaders.push_back( 1143 DAVRequestHeader( aRequestHeaders[ n ].Name, aValue ) ); 1144 } 1145 } 1146 } 1147 } 1148 1149 //========================================================================= 1150 sal_Bool DAVResourceAccess::detectRedirectCycle( 1151 const rtl::OUString& rRedirectURL ) 1152 throw ( DAVException ) 1153 { 1154 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1155 1156 SerfUri aUri( rRedirectURL ); 1157 1158 std::vector< SerfUri >::const_iterator it = m_aRedirectURIs.begin(); 1159 std::vector< SerfUri >::const_iterator end = m_aRedirectURIs.end(); 1160 1161 while ( it != end ) 1162 { 1163 if ( aUri == (*it) ) 1164 return sal_True; 1165 1166 it++; 1167 } 1168 1169 return sal_False; 1170 } 1171 1172 //========================================================================= 1173 void DAVResourceAccess::resetUri() 1174 { 1175 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1176 if ( m_aRedirectURIs.size() > 0 ) 1177 { 1178 std::vector< SerfUri >::const_iterator it = m_aRedirectURIs.begin(); 1179 1180 SerfUri aUri( (*it) ); 1181 m_aRedirectURIs.clear(); 1182 setURL ( aUri.GetURI() ); 1183 initialize(); 1184 } 1185 } 1186 1187 //========================================================================= 1188 sal_Bool DAVResourceAccess::handleException( DAVException & e, int errorCount ) 1189 throw ( DAVException ) 1190 { 1191 switch ( e.getError() ) 1192 { 1193 case DAVException::DAV_HTTP_REDIRECT: 1194 if ( !detectRedirectCycle( e.getData() ) ) 1195 { 1196 // set new URL and path. 1197 setURL( e.getData() ); 1198 initialize(); 1199 return sal_True; 1200 } 1201 return sal_False; 1202 // --> tkr #67048# copy & paste images doesn't display. 1203 // if we have a bad connection try again. Up to three times. 1204 case DAVException::DAV_HTTP_ERROR: 1205 // retry up to three times, if not a client-side error. 1206 if ( ( e.getStatus() < 400 || e.getStatus() >= 500 || 1207 e.getStatus() == 413 ) && 1208 errorCount < 3 ) 1209 { 1210 return sal_True; 1211 } 1212 return sal_False; 1213 // <-- 1214 // --> tkr: if connection has said retry then retry! 1215 case DAVException::DAV_HTTP_RETRY: 1216 return sal_True; 1217 // <-- 1218 default: 1219 return sal_False; // Abort 1220 } 1221 } 1222