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