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