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