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 { 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 //========================================================================= 173 void DAVResourceAccess::PROPFIND( 174 const Depth nDepth, 175 const std::vector< rtl::OUString > & rPropertyNames, 176 std::vector< DAVResource > & rResources, 177 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 178 throw( DAVException ) 179 { 180 initialize(); 181 182 int errorCount = 0; 183 bool bRetry; 184 do 185 { 186 bRetry = false; 187 try 188 { 189 DAVRequestHeaders aHeaders; 190 191 getUserRequestHeaders( xEnv, 192 getRequestURI(), 193 rtl::OUString::createFromAscii( 194 "PROPFIND" ), 195 aHeaders ); 196 197 m_xSession->PROPFIND( getRequestURI(), 198 nDepth, 199 rPropertyNames, 200 rResources, 201 DAVRequestEnvironment( 202 getRequestURI(), 203 new DAVAuthListener_Impl( xEnv, m_aURL ), 204 aHeaders, xEnv ) ); 205 } 206 catch ( DAVException & e ) 207 { 208 errorCount++; 209 bRetry = handleException( e, errorCount ); 210 if ( !bRetry ) 211 throw; 212 } 213 } 214 while ( bRetry ); 215 } 216 217 //========================================================================= 218 void DAVResourceAccess::PROPFIND( 219 const Depth nDepth, 220 std::vector< DAVResourceInfo > & rResInfo, 221 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 222 throw( DAVException ) 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 rtl::OUString::createFromAscii( 237 "PROPFIND" ), 238 aHeaders ); 239 240 m_xSession->PROPFIND( getRequestURI(), 241 nDepth, 242 rResInfo, 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::PROPPATCH( 261 const std::vector< ProppatchValue >& rValues, 262 const uno::Reference< ucb::XCommandEnvironment >& xEnv ) 263 throw( DAVException ) 264 { 265 initialize(); 266 267 int errorCount = 0; 268 bool bRetry; 269 do 270 { 271 bRetry = false; 272 try 273 { 274 DAVRequestHeaders aHeaders; 275 getUserRequestHeaders( xEnv, 276 getRequestURI(), 277 rtl::OUString::createFromAscii( 278 "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 rtl::OUString::createFromAscii( "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 rtl::OUString::createFromAscii( "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 rtl::OUString::createFromAscii( "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 rtl::OUString::createFromAscii( "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 void DAVResourceAccess::GET( 467 uno::Reference< io::XOutputStream > & rStream, 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 bool bRetry; 476 int errorCount = 0; 477 do 478 { 479 bRetry = false; 480 try 481 { 482 DAVRequestHeaders aHeaders; 483 getUserRequestHeaders( xEnv, 484 getRequestURI(), 485 rtl::OUString::createFromAscii( "GET" ), 486 aHeaders ); 487 488 m_xSession->GET( getRequestURI(), 489 rStream, 490 rHeaderNames, 491 rResource, 492 DAVRequestEnvironment( 493 getRequestURI(), 494 new DAVAuthListener_Impl( xEnv, m_aURL ), 495 aHeaders, 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 508 //========================================================================= 509 void DAVResourceAccess::abort() 510 throw( DAVException ) 511 { 512 // 17.11.09 (tkr): abort currently disabled caused by issue i106766 513 // initialize(); 514 // m_xSession->abort(); 515 OSL_TRACE( "Not implemented. -> #i106766#" ); 516 } 517 518 //========================================================================= 519 namespace { 520 521 void resetInputStream( const uno::Reference< io::XInputStream > & rStream ) 522 throw( DAVException ) 523 { 524 try 525 { 526 uno::Reference< io::XSeekable > xSeekable( 527 rStream, uno::UNO_QUERY ); 528 if ( xSeekable.is() ) 529 { 530 xSeekable->seek( 0 ); 531 return; 532 } 533 } 534 catch ( lang::IllegalArgumentException const & ) 535 { 536 } 537 catch ( io::IOException const & ) 538 { 539 } 540 541 throw DAVException( DAVException::DAV_INVALID_ARG ); 542 } 543 544 } // namespace 545 546 //========================================================================= 547 void DAVResourceAccess::PUT( 548 const uno::Reference< io::XInputStream > & rStream, 549 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 550 throw( DAVException ) 551 { 552 initialize(); 553 554 // Make stream seekable, if it not. Needed, if request must be retried. 555 uno::Reference< io::XInputStream > xSeekableStream 556 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( 557 rStream, m_xSMgr ); 558 559 int errorCount = 0; 560 bool bRetry = false; 561 do 562 { 563 if ( bRetry ) 564 resetInputStream( xSeekableStream ); 565 566 bRetry = false; 567 try 568 { 569 DAVRequestHeaders aHeaders; 570 getUserRequestHeaders( xEnv, 571 getRequestURI(), 572 rtl::OUString::createFromAscii( "PUT" ), 573 aHeaders ); 574 575 m_xSession->PUT( getRequestURI(), 576 xSeekableStream, 577 DAVRequestEnvironment( 578 getRequestURI(), 579 new DAVAuthListener_Impl( xEnv, m_aURL ), 580 aHeaders, xEnv ) ); 581 } 582 catch ( DAVException & e ) 583 { 584 errorCount++; 585 bRetry = handleException( e, errorCount ); 586 if ( !bRetry ) 587 throw; 588 } 589 } 590 while ( bRetry ); 591 } 592 593 //========================================================================= 594 uno::Reference< io::XInputStream > DAVResourceAccess::POST( 595 const rtl::OUString & rContentType, 596 const rtl::OUString & rReferer, 597 const uno::Reference< io::XInputStream > & rInputStream, 598 const uno::Reference< ucb::XCommandEnvironment >& xEnv ) 599 throw ( DAVException ) 600 { 601 initialize(); 602 603 // Make stream seekable, if it not. Needed, if request must be retried. 604 uno::Reference< io::XInputStream > xSeekableStream 605 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( 606 rInputStream, m_xSMgr ); 607 608 uno::Reference< io::XInputStream > xStream; 609 int errorCount = 0; 610 bool bRetry = false; 611 do 612 { 613 if ( bRetry ) 614 { 615 resetInputStream( xSeekableStream ); 616 bRetry = false; 617 } 618 619 try 620 { 621 DAVRequestHeaders aHeaders; 622 getUserRequestHeaders( xEnv, 623 getRequestURI(), 624 rtl::OUString::createFromAscii( "POST" ), 625 aHeaders ); 626 627 xStream = m_xSession->POST( getRequestURI(), 628 rContentType, 629 rReferer, 630 xSeekableStream, 631 DAVRequestEnvironment( 632 getRequestURI(), 633 new DAVAuthListener_Impl( 634 xEnv, m_aURL ), 635 aHeaders, xEnv ) ); 636 } 637 catch ( DAVException & e ) 638 { 639 errorCount++; 640 bRetry = handleException( e, errorCount ); 641 if ( !bRetry ) 642 throw; 643 644 if ( e.getError() == DAVException::DAV_HTTP_REDIRECT ) 645 { 646 // #i74980# - Upon POST redirect, do a GET. 647 return GET( xEnv ); 648 } 649 } 650 } 651 while ( bRetry ); 652 653 return xStream; 654 } 655 656 //========================================================================= 657 void DAVResourceAccess::POST( 658 const rtl::OUString & rContentType, 659 const rtl::OUString & rReferer, 660 const uno::Reference< io::XInputStream > & rInputStream, 661 uno::Reference< io::XOutputStream > & rOutputStream, 662 const uno::Reference< ucb::XCommandEnvironment >& xEnv ) 663 throw ( DAVException ) 664 { 665 initialize(); 666 667 // Make stream seekable, if it not. Needed, if request must be retried. 668 uno::Reference< io::XInputStream > xSeekableStream 669 = comphelper::OSeekableInputWrapper::CheckSeekableCanWrap( 670 rInputStream, m_xSMgr ); 671 672 int errorCount = 0; 673 bool bRetry = false; 674 do 675 { 676 if ( bRetry ) 677 { 678 resetInputStream( xSeekableStream ); 679 bRetry = false; 680 } 681 682 try 683 { 684 DAVRequestHeaders aHeaders; 685 getUserRequestHeaders( xEnv, 686 getRequestURI(), 687 rtl::OUString::createFromAscii( "POST" ), 688 aHeaders ); 689 690 m_xSession->POST( getRequestURI(), 691 rContentType, 692 rReferer, 693 xSeekableStream, 694 rOutputStream, 695 DAVRequestEnvironment( 696 getRequestURI(), 697 new DAVAuthListener_Impl( xEnv, m_aURL ), 698 aHeaders, xEnv ) ); 699 } 700 catch ( DAVException & e ) 701 { 702 errorCount++; 703 bRetry = handleException( e, errorCount ); 704 if ( !bRetry ) 705 throw; 706 707 if ( e.getError() == DAVException::DAV_HTTP_REDIRECT ) 708 { 709 // #i74980# - Upon POST redirect, do a GET. 710 GET( rOutputStream, xEnv ); 711 return; 712 } 713 } 714 } 715 while ( bRetry ); 716 } 717 718 //========================================================================= 719 void DAVResourceAccess::MKCOL( 720 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 721 throw( DAVException ) 722 { 723 initialize(); 724 725 int errorCount = 0; 726 bool bRetry; 727 do 728 { 729 bRetry = false; 730 try 731 { 732 DAVRequestHeaders aHeaders; 733 getUserRequestHeaders( xEnv, 734 getRequestURI(), 735 rtl::OUString::createFromAscii( "MKCOL" ), 736 aHeaders ); 737 738 m_xSession->MKCOL( getRequestURI(), 739 DAVRequestEnvironment( 740 getRequestURI(), 741 new DAVAuthListener_Impl( xEnv, m_aURL ), 742 aHeaders, xEnv ) ); 743 } 744 catch ( DAVException & e ) 745 { 746 errorCount++; 747 bRetry = handleException( e, errorCount ); 748 if ( !bRetry ) 749 throw; 750 } 751 } 752 while ( bRetry ); 753 } 754 755 //========================================================================= 756 void DAVResourceAccess::COPY( 757 const ::rtl::OUString & rSourcePath, 758 const ::rtl::OUString & rDestinationURI, 759 sal_Bool bOverwrite, 760 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 761 throw( DAVException ) 762 { 763 initialize(); 764 765 int errorCount = 0; 766 bool bRetry; 767 do 768 { 769 bRetry = false; 770 try 771 { 772 DAVRequestHeaders aHeaders; 773 getUserRequestHeaders( xEnv, 774 getRequestURI(), 775 rtl::OUString::createFromAscii( "COPY" ), 776 aHeaders ); 777 778 m_xSession->COPY( rSourcePath, 779 rDestinationURI, 780 DAVRequestEnvironment( 781 getRequestURI(), 782 new DAVAuthListener_Impl( xEnv, m_aURL ), 783 aHeaders, xEnv ), 784 bOverwrite ); 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::MOVE( 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( "MOVE" ), 818 aHeaders ); 819 820 m_xSession->MOVE( 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::DESTROY( 841 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 842 throw( DAVException ) 843 { 844 initialize(); 845 846 int errorCount = 0; 847 bool bRetry; 848 do 849 { 850 bRetry = false; 851 try 852 { 853 DAVRequestHeaders aHeaders; 854 getUserRequestHeaders( xEnv, 855 getRequestURI(), 856 rtl::OUString::createFromAscii( 857 "DESTROY" ), 858 aHeaders ); 859 860 m_xSession->DESTROY( getRequestURI(), 861 DAVRequestEnvironment( 862 getRequestURI(), 863 new DAVAuthListener_Impl( xEnv, m_aURL ), 864 aHeaders, xEnv ) ); 865 } 866 catch ( DAVException & e ) 867 { 868 errorCount++; 869 bRetry = handleException( e, errorCount ); 870 if ( !bRetry ) 871 throw; 872 } 873 } 874 while ( bRetry ); 875 } 876 877 //========================================================================= 878 // set new lock. 879 void DAVResourceAccess::LOCK( 880 ucb::Lock & inLock, 881 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 882 throw ( DAVException ) 883 { 884 initialize(); 885 886 int errorCount = 0; 887 bool bRetry; 888 do 889 { 890 bRetry = false; 891 try 892 { 893 DAVRequestHeaders aHeaders; 894 getUserRequestHeaders( xEnv, 895 getRequestURI(), 896 rtl::OUString::createFromAscii( "LOCK" ), 897 aHeaders ); 898 899 m_xSession->LOCK( getRequestURI(), 900 inLock, 901 DAVRequestEnvironment( 902 getRequestURI(), 903 new DAVAuthListener_Impl( xEnv, m_aURL ), 904 aHeaders, xEnv ) ); 905 } 906 catch ( DAVException & e ) 907 { 908 errorCount++; 909 bRetry = handleException( e, errorCount ); 910 if ( !bRetry ) 911 throw; 912 } 913 } 914 while ( bRetry ); 915 } 916 917 #if 0 // currently not used, but please don't remove code 918 //========================================================================= 919 // refresh existing lock. 920 sal_Int64 DAVResourceAccess::LOCK( 921 sal_Int64 nTimeout, 922 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 923 throw ( DAVException ) 924 { 925 initialize(); 926 927 sal_Int64 nNewTimeout = 0; 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 nNewTimeout = m_xSession->LOCK( getRequestURI(), 942 nTimeout, 943 DAVRequestEnvironment( 944 getRequestURI(), 945 new DAVAuthListener_Impl( 946 xEnv, m_aURL ), 947 aHeaders, xEnv ) ); 948 } 949 catch ( DAVException & e ) 950 { 951 errorCount++; 952 bRetry = handleException( e, errorCount ); 953 if ( !bRetry ) 954 throw; 955 } 956 } 957 while ( bRetry ); 958 959 return nNewTimeout; 960 } 961 #endif 962 963 //========================================================================= 964 void DAVResourceAccess::UNLOCK( 965 const uno::Reference< ucb::XCommandEnvironment > & xEnv ) 966 throw ( DAVException ) 967 { 968 initialize(); 969 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( "UNLOCK" ), 981 aHeaders ); 982 983 m_xSession->UNLOCK( getRequestURI(), 984 DAVRequestEnvironment( 985 getRequestURI(), 986 new DAVAuthListener_Impl( xEnv, m_aURL ), 987 aHeaders, xEnv ) ); 988 } 989 catch ( DAVException & e ) 990 { 991 errorCount++; 992 bRetry = handleException( e, errorCount ); 993 if ( !bRetry ) 994 throw; 995 } 996 } 997 while ( bRetry ); 998 } 999 1000 //========================================================================= 1001 void DAVResourceAccess::setURL( const rtl::OUString & rNewURL ) 1002 throw( DAVException ) 1003 { 1004 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1005 m_aURL = rNewURL; 1006 m_aPath = rtl::OUString(); // Next initialize() will create new session. 1007 } 1008 1009 //========================================================================= 1010 // init dav session and path 1011 void DAVResourceAccess::initialize() 1012 throw ( DAVException ) 1013 { 1014 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1015 if ( m_aPath.getLength() == 0 ) 1016 { 1017 SerfUri aURI( m_aURL ); 1018 rtl::OUString aPath( aURI.GetPath() ); 1019 1020 /* #134089# - Check URI */ 1021 if ( !aPath.getLength() ) 1022 throw DAVException( DAVException::DAV_INVALID_ARG ); 1023 1024 /* #134089# - Check URI */ 1025 if ( !aURI.GetHost().getLength() ) 1026 throw DAVException( DAVException::DAV_INVALID_ARG ); 1027 1028 if ( !m_xSession.is() || !m_xSession->CanUse( m_aURL ) ) 1029 { 1030 m_xSession.clear(); 1031 1032 // create new webdav session 1033 m_xSession 1034 = m_xSessionFactory->createDAVSession( m_aURL, m_xSMgr ); 1035 1036 if ( !m_xSession.is() ) 1037 return; 1038 } 1039 1040 // Own URI is needed for redirect cycle detection. 1041 m_aRedirectURIs.push_back( aURI ); 1042 1043 // Success. 1044 m_aPath = aPath; 1045 1046 // Not only the path has to be encoded 1047 m_aURL = aURI.GetURI(); 1048 } 1049 } 1050 1051 //========================================================================= 1052 const rtl::OUString & DAVResourceAccess::getRequestURI() const 1053 { 1054 OSL_ENSURE( m_xSession.is(), 1055 "DAVResourceAccess::getRequestURI - Not initialized!" ); 1056 1057 // In case a proxy is used we have to use the absolute URI for a request. 1058 if ( m_xSession->UsesProxy() ) 1059 return m_aURL; 1060 1061 return m_aPath; 1062 } 1063 1064 //========================================================================= 1065 // static 1066 void DAVResourceAccess::getUserRequestHeaders( 1067 const uno::Reference< ucb::XCommandEnvironment > & xEnv, 1068 const rtl::OUString & rURI, 1069 const rtl::OUString & rMethod, 1070 DAVRequestHeaders & rRequestHeaders ) 1071 { 1072 if ( xEnv.is() ) 1073 { 1074 uno::Reference< ucb::XWebDAVCommandEnvironment > xDAVEnv( 1075 xEnv, uno::UNO_QUERY ); 1076 1077 if ( xDAVEnv.is() ) 1078 { 1079 uno::Sequence< beans::NamedValue > aRequestHeaders 1080 = xDAVEnv->getUserRequestHeaders( rURI, rMethod ); 1081 1082 for ( sal_Int32 n = 0; n < aRequestHeaders.getLength(); ++n ) 1083 { 1084 rtl::OUString aValue; 1085 sal_Bool isString = aRequestHeaders[ n ].Value >>= aValue; 1086 1087 if ( !isString ) 1088 { 1089 OSL_ENSURE( isString, 1090 "DAVResourceAccess::getUserRequestHeaders :" 1091 "Value is not a string! Ignoring..." ); 1092 } 1093 1094 rRequestHeaders.push_back( 1095 DAVRequestHeader( aRequestHeaders[ n ].Name, aValue ) ); 1096 } 1097 } 1098 } 1099 } 1100 1101 //========================================================================= 1102 sal_Bool DAVResourceAccess::detectRedirectCycle( 1103 const rtl::OUString& rRedirectURL ) 1104 throw ( DAVException ) 1105 { 1106 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1107 1108 SerfUri aUri( rRedirectURL ); 1109 1110 std::vector< SerfUri >::const_iterator it = m_aRedirectURIs.begin(); 1111 std::vector< SerfUri >::const_iterator end = m_aRedirectURIs.end(); 1112 1113 while ( it != end ) 1114 { 1115 if ( aUri == (*it) ) 1116 return sal_True; 1117 1118 it++; 1119 } 1120 1121 return sal_False; 1122 } 1123 1124 //========================================================================= 1125 void DAVResourceAccess::resetUri() 1126 { 1127 osl::Guard< osl::Mutex > aGuard( m_aMutex ); 1128 if ( m_aRedirectURIs.size() > 0 ) 1129 { 1130 std::vector< SerfUri >::const_iterator it = m_aRedirectURIs.begin(); 1131 1132 SerfUri aUri( (*it) ); 1133 m_aRedirectURIs.clear(); 1134 setURL ( aUri.GetURI() ); 1135 initialize(); 1136 } 1137 } 1138 1139 //========================================================================= 1140 sal_Bool DAVResourceAccess::handleException( DAVException & e, int errorCount ) 1141 throw ( DAVException ) 1142 { 1143 switch ( e.getError() ) 1144 { 1145 case DAVException::DAV_HTTP_REDIRECT: 1146 if ( !detectRedirectCycle( e.getData() ) ) 1147 { 1148 // set new URL and path. 1149 setURL( e.getData() ); 1150 initialize(); 1151 return sal_True; 1152 } 1153 return sal_False; 1154 // --> tkr #67048# copy & paste images doesn't display. 1155 // if we have a bad connection try again. Up to three times. 1156 case DAVException::DAV_HTTP_ERROR: 1157 // retry up to three times, if not a client-side error. 1158 if ( ( e.getStatus() < 400 || e.getStatus() >= 500 ) && 1159 errorCount < 3 ) 1160 { 1161 return sal_True; 1162 } 1163 return sal_False; 1164 // <-- 1165 // --> tkr: if connection has said retry then retry! 1166 case DAVException::DAV_HTTP_RETRY: 1167 return sal_True; 1168 // <-- 1169 default: 1170 return sal_False; // Abort 1171 } 1172 } 1173