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