18590a0fdSAndre Fischer /************************************************************** 28590a0fdSAndre Fischer * 38590a0fdSAndre Fischer * Licensed to the Apache Software Foundation (ASF) under one 48590a0fdSAndre Fischer * or more contributor license agreements. See the NOTICE file 58590a0fdSAndre Fischer * distributed with this work for additional information 68590a0fdSAndre Fischer * regarding copyright ownership. The ASF licenses this file 78590a0fdSAndre Fischer * to you under the Apache License, Version 2.0 (the 88590a0fdSAndre Fischer * "License"); you may not use this file except in compliance 98590a0fdSAndre Fischer * with the License. You may obtain a copy of the License at 108590a0fdSAndre Fischer * 118590a0fdSAndre Fischer * http://www.apache.org/licenses/LICENSE-2.0 128590a0fdSAndre Fischer * 138590a0fdSAndre Fischer * Unless required by applicable law or agreed to in writing, 148590a0fdSAndre Fischer * software distributed under the License is distributed on an 158590a0fdSAndre Fischer * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 168590a0fdSAndre Fischer * KIND, either express or implied. See the License for the 178590a0fdSAndre Fischer * specific language governing permissions and limitations 188590a0fdSAndre Fischer * under the License. 198590a0fdSAndre Fischer * 208590a0fdSAndre Fischer *************************************************************/ 218590a0fdSAndre Fischer 228590a0fdSAndre Fischer // MARKER(update_precomp.py): autogen include statement, do not remove 238590a0fdSAndre Fischer #include "precompiled_ucb.hxx" 248590a0fdSAndre Fischer 258590a0fdSAndre Fischer #include <SerfRequestProcessor.hxx> 268590a0fdSAndre Fischer #include <SerfRequestProcessorImpl.hxx> 278590a0fdSAndre Fischer #include <SerfRequestProcessorImplFac.hxx> 288590a0fdSAndre Fischer #include <SerfCallbacks.hxx> 298590a0fdSAndre Fischer #include <SerfSession.hxx> 308590a0fdSAndre Fischer 318590a0fdSAndre Fischer #include <apr_strings.h> 328590a0fdSAndre Fischer 338590a0fdSAndre Fischer namespace http_dav_ucp 348590a0fdSAndre Fischer { 358590a0fdSAndre Fischer 368590a0fdSAndre Fischer SerfRequestProcessor::SerfRequestProcessor( SerfSession& rSerfSession, 37*49989859SOliver-Rainer Wittmann const rtl::OUString & inPath, 38*49989859SOliver-Rainer Wittmann const bool bUseChunkedEncoding ) 398590a0fdSAndre Fischer : mrSerfSession( rSerfSession ) 408590a0fdSAndre Fischer , mPathStr( 0 ) 41*49989859SOliver-Rainer Wittmann , mbUseChunkedEncoding( bUseChunkedEncoding ) 428590a0fdSAndre Fischer , mDestPathStr( 0 ) 43*49989859SOliver-Rainer Wittmann , mContentType( 0 ) 44*49989859SOliver-Rainer Wittmann , mReferer( 0 ) 458590a0fdSAndre Fischer , mpProcImpl( 0 ) 468590a0fdSAndre Fischer , mbProcessingDone( false ) 478590a0fdSAndre Fischer , mpDAVException() 488590a0fdSAndre Fischer , mnHTTPStatusCode( SC_NONE ) 498590a0fdSAndre Fischer , mHTTPStatusCodeText() 508590a0fdSAndre Fischer , mRedirectLocation() 51fb7f54d2SOliver-Rainer Wittmann , mnSuccessfulCredentialAttempts( 0 ) 52fb7f54d2SOliver-Rainer Wittmann , mbInputOfCredentialsAborted( false ) 538590a0fdSAndre Fischer , mbSetupSerfRequestCalled( false ) 548590a0fdSAndre Fischer , mbAcceptSerfResponseCalled( false ) 558590a0fdSAndre Fischer , mbHandleSerfResponseCalled( false ) 568590a0fdSAndre Fischer { 578590a0fdSAndre Fischer mPathStr = apr_pstrdup( mrSerfSession.getAprPool(), 588590a0fdSAndre Fischer rtl::OUStringToOString( inPath, RTL_TEXTENCODING_UTF8 ) ); 598590a0fdSAndre Fischer } 608590a0fdSAndre Fischer 618590a0fdSAndre Fischer SerfRequestProcessor::~SerfRequestProcessor() 628590a0fdSAndre Fischer { 638590a0fdSAndre Fischer delete mpProcImpl; 648590a0fdSAndre Fischer delete mpDAVException; 658590a0fdSAndre Fischer } 668590a0fdSAndre Fischer 678590a0fdSAndre Fischer void SerfRequestProcessor::prepareProcessor() 688590a0fdSAndre Fischer { 698590a0fdSAndre Fischer delete mpDAVException; 708590a0fdSAndre Fischer mpDAVException = 0; 718590a0fdSAndre Fischer mnHTTPStatusCode = SC_NONE; 728590a0fdSAndre Fischer mHTTPStatusCodeText = rtl::OUString(); 738590a0fdSAndre Fischer mRedirectLocation = rtl::OUString(); 748590a0fdSAndre Fischer 75fb7f54d2SOliver-Rainer Wittmann mnSuccessfulCredentialAttempts = 0; 76fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted = false; 778590a0fdSAndre Fischer mbSetupSerfRequestCalled = false; 788590a0fdSAndre Fischer mbAcceptSerfResponseCalled = false; 798590a0fdSAndre Fischer mbHandleSerfResponseCalled = false; 808590a0fdSAndre Fischer } 818590a0fdSAndre Fischer 828590a0fdSAndre Fischer // PROPFIND - allprop & named 838590a0fdSAndre Fischer bool SerfRequestProcessor::processPropFind( const Depth inDepth, 848590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inPropNames, 858590a0fdSAndre Fischer std::vector< DAVResource > & ioResources, 868590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 878590a0fdSAndre Fischer { 888590a0fdSAndre Fischer mpProcImpl = createPropFindReqProcImpl( mPathStr, 898590a0fdSAndre Fischer inDepth, 908590a0fdSAndre Fischer inPropNames, 918590a0fdSAndre Fischer ioResources ); 928590a0fdSAndre Fischer outSerfStatus = runProcessor(); 938590a0fdSAndre Fischer 948590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 958590a0fdSAndre Fischer } 968590a0fdSAndre Fischer 978590a0fdSAndre Fischer // PROPFIND - property names 988590a0fdSAndre Fischer bool SerfRequestProcessor::processPropFind( const Depth inDepth, 998590a0fdSAndre Fischer std::vector< DAVResourceInfo > & ioResInfo, 1008590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1018590a0fdSAndre Fischer { 1028590a0fdSAndre Fischer mpProcImpl = createPropFindReqProcImpl( mPathStr, 1038590a0fdSAndre Fischer inDepth, 1048590a0fdSAndre Fischer ioResInfo ); 1058590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1068590a0fdSAndre Fischer 1078590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1088590a0fdSAndre Fischer } 1098590a0fdSAndre Fischer 1108590a0fdSAndre Fischer // PROPPATCH 1118590a0fdSAndre Fischer bool SerfRequestProcessor::processPropPatch( const std::vector< ProppatchValue > & inProperties, 1128590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1138590a0fdSAndre Fischer { 1148590a0fdSAndre Fischer mpProcImpl = createPropPatchReqProcImpl( mPathStr, 1158590a0fdSAndre Fischer inProperties ); 1168590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1178590a0fdSAndre Fischer 1188590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1198590a0fdSAndre Fischer } 1208590a0fdSAndre Fischer 1218590a0fdSAndre Fischer // GET 1228590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, 1238590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1248590a0fdSAndre Fischer { 1258590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 1268590a0fdSAndre Fischer xioInStrm ); 1278590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1288590a0fdSAndre Fischer 1298590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1308590a0fdSAndre Fischer } 1318590a0fdSAndre Fischer 1328590a0fdSAndre Fischer // GET inclusive header fields 1338590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, 1348590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 1358590a0fdSAndre Fischer DAVResource & ioResource, 1368590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1378590a0fdSAndre Fischer { 1388590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 1398590a0fdSAndre Fischer xioInStrm, 1408590a0fdSAndre Fischer inHeaderNames, 1418590a0fdSAndre Fischer ioResource ); 1428590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1438590a0fdSAndre Fischer 1448590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1458590a0fdSAndre Fischer } 1468590a0fdSAndre Fischer 1478590a0fdSAndre Fischer // GET 1488590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, 1498590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1508590a0fdSAndre Fischer { 1518590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 1528590a0fdSAndre Fischer xioOutStrm ); 1538590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1548590a0fdSAndre Fischer 1558590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1568590a0fdSAndre Fischer } 1578590a0fdSAndre Fischer 1588590a0fdSAndre Fischer // GET inclusive header fields 1598590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, 1608590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 1618590a0fdSAndre Fischer DAVResource & ioResource, 1628590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1638590a0fdSAndre Fischer { 1648590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 1658590a0fdSAndre Fischer xioOutStrm, 1668590a0fdSAndre Fischer inHeaderNames, 1678590a0fdSAndre Fischer ioResource ); 1688590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1698590a0fdSAndre Fischer 1708590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1718590a0fdSAndre Fischer } 1728590a0fdSAndre Fischer 1738590a0fdSAndre Fischer // HEAD 1748590a0fdSAndre Fischer bool SerfRequestProcessor::processHead( const std::vector< ::rtl::OUString > & inHeaderNames, 1758590a0fdSAndre Fischer DAVResource & ioResource, 1768590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1778590a0fdSAndre Fischer { 1788590a0fdSAndre Fischer mpProcImpl = createHeadReqProcImpl( mPathStr, 1798590a0fdSAndre Fischer inHeaderNames, 1808590a0fdSAndre Fischer ioResource ); 1818590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1828590a0fdSAndre Fischer 1838590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1848590a0fdSAndre Fischer } 1858590a0fdSAndre Fischer 1868590a0fdSAndre Fischer // PUT 1878590a0fdSAndre Fischer bool SerfRequestProcessor::processPut( const char* inData, 1888590a0fdSAndre Fischer apr_size_t inDataLen, 1898590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1908590a0fdSAndre Fischer { 1918590a0fdSAndre Fischer mpProcImpl = createPutReqProcImpl( mPathStr, 1928590a0fdSAndre Fischer inData, 1938590a0fdSAndre Fischer inDataLen ); 1948590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1958590a0fdSAndre Fischer 1968590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1978590a0fdSAndre Fischer } 1988590a0fdSAndre Fischer 1998590a0fdSAndre Fischer // POST 2008590a0fdSAndre Fischer bool SerfRequestProcessor::processPost( const char* inData, 2018590a0fdSAndre Fischer apr_size_t inDataLen, 2028590a0fdSAndre Fischer const rtl::OUString & inContentType, 2038590a0fdSAndre Fischer const rtl::OUString & inReferer, 2048590a0fdSAndre Fischer const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, 2058590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 2068590a0fdSAndre Fischer { 2078590a0fdSAndre Fischer mContentType = apr_pstrdup( mrSerfSession.getAprPool(), 2088590a0fdSAndre Fischer rtl::OUStringToOString( inContentType, RTL_TEXTENCODING_UTF8 ) ); 2098590a0fdSAndre Fischer mReferer = apr_pstrdup( mrSerfSession.getAprPool(), 2108590a0fdSAndre Fischer rtl::OUStringToOString( inReferer, RTL_TEXTENCODING_UTF8 ) ); 2118590a0fdSAndre Fischer mpProcImpl = createPostReqProcImpl( mPathStr, 2128590a0fdSAndre Fischer inData, 2138590a0fdSAndre Fischer inDataLen, 2148590a0fdSAndre Fischer mContentType, 2158590a0fdSAndre Fischer mReferer, 2168590a0fdSAndre Fischer xioInStrm ); 2178590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2188590a0fdSAndre Fischer 2198590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2208590a0fdSAndre Fischer } 2218590a0fdSAndre Fischer 2228590a0fdSAndre Fischer // POST 2238590a0fdSAndre Fischer bool SerfRequestProcessor::processPost( const char* inData, 2248590a0fdSAndre Fischer apr_size_t inDataLen, 2258590a0fdSAndre Fischer const rtl::OUString & inContentType, 2268590a0fdSAndre Fischer const rtl::OUString & inReferer, 2278590a0fdSAndre Fischer const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, 2288590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 2298590a0fdSAndre Fischer { 2308590a0fdSAndre Fischer mContentType = apr_pstrdup( mrSerfSession.getAprPool(), 2318590a0fdSAndre Fischer rtl::OUStringToOString( inContentType, RTL_TEXTENCODING_UTF8 ) ); 2328590a0fdSAndre Fischer mReferer = apr_pstrdup( mrSerfSession.getAprPool(), 2338590a0fdSAndre Fischer rtl::OUStringToOString( inReferer, RTL_TEXTENCODING_UTF8 ) ); 2348590a0fdSAndre Fischer mpProcImpl = createPostReqProcImpl( mPathStr, 2358590a0fdSAndre Fischer inData, 2368590a0fdSAndre Fischer inDataLen, 2378590a0fdSAndre Fischer mContentType, 2388590a0fdSAndre Fischer mReferer, 2398590a0fdSAndre Fischer xioOutStrm ); 2408590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2418590a0fdSAndre Fischer 2428590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2438590a0fdSAndre Fischer } 2448590a0fdSAndre Fischer 2458590a0fdSAndre Fischer // DELETE 2468590a0fdSAndre Fischer bool SerfRequestProcessor::processDelete( apr_status_t& outSerfStatus ) 2478590a0fdSAndre Fischer { 2488590a0fdSAndre Fischer mpProcImpl = createDeleteReqProcImpl( mPathStr ); 2498590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2508590a0fdSAndre Fischer 2518590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2528590a0fdSAndre Fischer } 2538590a0fdSAndre Fischer 2548590a0fdSAndre Fischer // MKCOL 2558590a0fdSAndre Fischer bool SerfRequestProcessor::processMkCol( apr_status_t& outSerfStatus ) 2568590a0fdSAndre Fischer { 2578590a0fdSAndre Fischer mpProcImpl = createMkColReqProcImpl( mPathStr ); 2588590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2598590a0fdSAndre Fischer 2608590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2618590a0fdSAndre Fischer } 2628590a0fdSAndre Fischer 2638590a0fdSAndre Fischer // COPY 2648590a0fdSAndre Fischer bool SerfRequestProcessor::processCopy( const rtl::OUString & inDestinationPath, 2658590a0fdSAndre Fischer const bool inOverwrite, 2668590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 2678590a0fdSAndre Fischer { 2688590a0fdSAndre Fischer mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), 2698590a0fdSAndre Fischer rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ) ); 2708590a0fdSAndre Fischer mpProcImpl = createCopyReqProcImpl( mPathStr, 2718590a0fdSAndre Fischer mDestPathStr, 2728590a0fdSAndre Fischer inOverwrite ); 2738590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2748590a0fdSAndre Fischer 2758590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2768590a0fdSAndre Fischer } 2778590a0fdSAndre Fischer 2788590a0fdSAndre Fischer // MOVE 2798590a0fdSAndre Fischer bool SerfRequestProcessor::processMove( const rtl::OUString & inDestinationPath, 2808590a0fdSAndre Fischer const bool inOverwrite, 2818590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 2828590a0fdSAndre Fischer { 2838590a0fdSAndre Fischer mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), 2848590a0fdSAndre Fischer rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ) ); 2858590a0fdSAndre Fischer mpProcImpl = createMoveReqProcImpl( mPathStr, 2868590a0fdSAndre Fischer mDestPathStr, 2878590a0fdSAndre Fischer inOverwrite ); 2888590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2898590a0fdSAndre Fischer 2908590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2918590a0fdSAndre Fischer } 2928590a0fdSAndre Fischer 2938590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::runProcessor() 2948590a0fdSAndre Fischer { 2958590a0fdSAndre Fischer prepareProcessor(); 2968590a0fdSAndre Fischer 297*49989859SOliver-Rainer Wittmann // activate chunked encoding, if requested 298*49989859SOliver-Rainer Wittmann if ( mbUseChunkedEncoding ) 299*49989859SOliver-Rainer Wittmann { 300*49989859SOliver-Rainer Wittmann mpProcImpl->activateChunkedEncoding(); 301*49989859SOliver-Rainer Wittmann } 302*49989859SOliver-Rainer Wittmann 3038590a0fdSAndre Fischer // create serf request 3048590a0fdSAndre Fischer serf_connection_request_create( mrSerfSession.getSerfConnection(), 3058590a0fdSAndre Fischer Serf_SetupRequest, 3068590a0fdSAndre Fischer this ); 3078590a0fdSAndre Fischer 3088590a0fdSAndre Fischer // perform serf request 3098590a0fdSAndre Fischer mbProcessingDone = false; 3108590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 3118590a0fdSAndre Fischer serf_context_t* pSerfContext = mrSerfSession.getSerfContext(); 3128590a0fdSAndre Fischer apr_pool_t* pAprPool = mrSerfSession.getAprPool(); 3138590a0fdSAndre Fischer while ( true ) 3148590a0fdSAndre Fischer { 3158590a0fdSAndre Fischer status = serf_context_run( pSerfContext, 3168590a0fdSAndre Fischer SERF_DURATION_FOREVER, 3178590a0fdSAndre Fischer pAprPool ); 3188590a0fdSAndre Fischer if ( APR_STATUS_IS_TIMEUP( status ) ) 3198590a0fdSAndre Fischer { 3208590a0fdSAndre Fischer continue; 3218590a0fdSAndre Fischer } 3228590a0fdSAndre Fischer if ( status != APR_SUCCESS ) 3238590a0fdSAndre Fischer { 3248590a0fdSAndre Fischer break; 3258590a0fdSAndre Fischer } 3268590a0fdSAndre Fischer if ( mbProcessingDone ) 3278590a0fdSAndre Fischer { 3288590a0fdSAndre Fischer break; 3298590a0fdSAndre Fischer } 3308590a0fdSAndre Fischer } 3318590a0fdSAndre Fischer 3328590a0fdSAndre Fischer postprocessProcessor( status ); 3338590a0fdSAndre Fischer 3348590a0fdSAndre Fischer return status; 3358590a0fdSAndre Fischer } 3368590a0fdSAndre Fischer 3378590a0fdSAndre Fischer void SerfRequestProcessor::postprocessProcessor( const apr_status_t inStatus ) 3388590a0fdSAndre Fischer { 3398590a0fdSAndre Fischer if ( inStatus == APR_SUCCESS ) 3408590a0fdSAndre Fischer { 3418590a0fdSAndre Fischer return; 3428590a0fdSAndre Fischer } 3438590a0fdSAndre Fischer 3448590a0fdSAndre Fischer switch ( inStatus ) 3458590a0fdSAndre Fischer { 3468590a0fdSAndre Fischer case APR_EGENERAL: 347fb7f54d2SOliver-Rainer Wittmann case SERF_ERROR_AUTHN_FAILED: 3488590a0fdSAndre Fischer // general error; <mnHTTPStatusCode> provides more information 3498590a0fdSAndre Fischer { 3508590a0fdSAndre Fischer switch ( mnHTTPStatusCode ) 3518590a0fdSAndre Fischer { 3528590a0fdSAndre Fischer case SC_NONE: 3538590a0fdSAndre Fischer if ( !mbSetupSerfRequestCalled ) 3548590a0fdSAndre Fischer { 3558590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_LOOKUP, 3568590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( mrSerfSession.getHostName(), 3578590a0fdSAndre Fischer mrSerfSession.getPort() ) ); 3588590a0fdSAndre Fischer } 359fb7f54d2SOliver-Rainer Wittmann else if ( mbInputOfCredentialsAborted ) 360fb7f54d2SOliver-Rainer Wittmann { 361fb7f54d2SOliver-Rainer Wittmann mpDAVException = new DAVException( DAVException::DAV_HTTP_NOAUTH, 362fb7f54d2SOliver-Rainer Wittmann SerfUri::makeConnectionEndPointString( mrSerfSession.getHostName(), 363fb7f54d2SOliver-Rainer Wittmann mrSerfSession.getPort() ) ); 364fb7f54d2SOliver-Rainer Wittmann } 3658590a0fdSAndre Fischer else 3668590a0fdSAndre Fischer { 3678590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR, 3688590a0fdSAndre Fischer mHTTPStatusCodeText, 3698590a0fdSAndre Fischer mnHTTPStatusCode ); 3708590a0fdSAndre Fischer } 3718590a0fdSAndre Fischer break; 3728590a0fdSAndre Fischer case SC_MOVED_PERMANENTLY: 3738590a0fdSAndre Fischer case SC_MOVED_TEMPORARILY: 3748590a0fdSAndre Fischer case SC_SEE_OTHER: 3758590a0fdSAndre Fischer case SC_TEMPORARY_REDIRECT: 3768590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_REDIRECT, 3778590a0fdSAndre Fischer mRedirectLocation ); 3788590a0fdSAndre Fischer break; 3798590a0fdSAndre Fischer default: 3808590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR, 3818590a0fdSAndre Fischer mHTTPStatusCodeText, 3828590a0fdSAndre Fischer mnHTTPStatusCode ); 3838590a0fdSAndre Fischer break; 3848590a0fdSAndre Fischer } 3858590a0fdSAndre Fischer } 3868590a0fdSAndre Fischer break; 3878590a0fdSAndre Fischer 3888590a0fdSAndre Fischer default: 3898590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR ); 3908590a0fdSAndre Fischer break; 3918590a0fdSAndre Fischer } 3928590a0fdSAndre Fischer 3938590a0fdSAndre Fischer } 3948590a0fdSAndre Fischer 3958590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::provideSerfCredentials( char ** outUsername, 3968590a0fdSAndre Fischer char ** outPassword, 3978590a0fdSAndre Fischer serf_request_t * inRequest, 3988590a0fdSAndre Fischer int inCode, 3998590a0fdSAndre Fischer const char *inAuthProtocol, 4008590a0fdSAndre Fischer const char *inRealm, 4018590a0fdSAndre Fischer apr_pool_t *inAprPool ) 4028590a0fdSAndre Fischer { 403fb7f54d2SOliver-Rainer Wittmann // as each successful provided credentials are tried twice - see below - the 404fb7f54d2SOliver-Rainer Wittmann // number of real attempts is half of the value of <mnSuccessfulCredentialAttempts> 405fb7f54d2SOliver-Rainer Wittmann if ( (mnSuccessfulCredentialAttempts / 2) >= 5 || 406fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted ) 407fb7f54d2SOliver-Rainer Wittmann { 408fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted = true; 409fb7f54d2SOliver-Rainer Wittmann return SERF_ERROR_AUTHN_FAILED; 410fb7f54d2SOliver-Rainer Wittmann } 411fb7f54d2SOliver-Rainer Wittmann 412fb7f54d2SOliver-Rainer Wittmann // because serf keeps credentials only for a connection in case of digest authentication 413fb7f54d2SOliver-Rainer Wittmann // we give each successful provided credentials a second try in order to workaround the 414fb7f54d2SOliver-Rainer Wittmann // situation that the connection for which the credentials have been provided has been closed 415fb7f54d2SOliver-Rainer Wittmann // before the provided credentials could be applied for the request. 416fb7f54d2SOliver-Rainer Wittmann apr_status_t status = mrSerfSession.provideSerfCredentials( (mnSuccessfulCredentialAttempts % 2) == 1, 417fb7f54d2SOliver-Rainer Wittmann outUsername, 4188590a0fdSAndre Fischer outPassword, 4198590a0fdSAndre Fischer inRequest, 4208590a0fdSAndre Fischer inCode, 4218590a0fdSAndre Fischer inAuthProtocol, 4228590a0fdSAndre Fischer inRealm, 4238590a0fdSAndre Fischer inAprPool ); 424fb7f54d2SOliver-Rainer Wittmann if ( status != APR_SUCCESS ) 425fb7f54d2SOliver-Rainer Wittmann { 426fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted = true; 427fb7f54d2SOliver-Rainer Wittmann } 428fb7f54d2SOliver-Rainer Wittmann else 429fb7f54d2SOliver-Rainer Wittmann { 430fb7f54d2SOliver-Rainer Wittmann ++mnSuccessfulCredentialAttempts; 431fb7f54d2SOliver-Rainer Wittmann } 432fb7f54d2SOliver-Rainer Wittmann 433fb7f54d2SOliver-Rainer Wittmann return status; 4348590a0fdSAndre Fischer } 4358590a0fdSAndre Fischer 4368590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::setupSerfRequest( serf_request_t * inSerfRequest, 4378590a0fdSAndre Fischer serf_bucket_t ** outSerfRequestBucket, 4388590a0fdSAndre Fischer serf_response_acceptor_t * outSerfResponseAcceptor, 4398590a0fdSAndre Fischer void ** outSerfResponseAcceptorBaton, 4408590a0fdSAndre Fischer serf_response_handler_t * outSerfResponseHandler, 4418590a0fdSAndre Fischer void ** outSerfResponseHandlerBaton, 4428590a0fdSAndre Fischer apr_pool_t * /*inAprPool*/ ) 4438590a0fdSAndre Fischer { 4448590a0fdSAndre Fischer mbSetupSerfRequestCalled = true; 4458590a0fdSAndre Fischer *outSerfRequestBucket = mpProcImpl->createSerfRequestBucket( inSerfRequest ); 4468590a0fdSAndre Fischer 4478590a0fdSAndre Fischer // apply callbacks for accepting response and handling response 4488590a0fdSAndre Fischer *outSerfResponseAcceptor = Serf_AcceptResponse; 4498590a0fdSAndre Fischer *outSerfResponseAcceptorBaton = this; 4508590a0fdSAndre Fischer *outSerfResponseHandler = Serf_HandleResponse; 4518590a0fdSAndre Fischer *outSerfResponseHandlerBaton = this; 4528590a0fdSAndre Fischer 4538590a0fdSAndre Fischer return APR_SUCCESS; 4548590a0fdSAndre Fischer } 4558590a0fdSAndre Fischer 4568590a0fdSAndre Fischer serf_bucket_t* SerfRequestProcessor::acceptSerfResponse( serf_request_t * inSerfRequest, 4578590a0fdSAndre Fischer serf_bucket_t * inSerfStreamBucket, 4588590a0fdSAndre Fischer apr_pool_t * inAprPool ) 4598590a0fdSAndre Fischer { 4608590a0fdSAndre Fischer mbAcceptSerfResponseCalled = true; 4618590a0fdSAndre Fischer return mrSerfSession.acceptSerfResponse( inSerfRequest, 4628590a0fdSAndre Fischer inSerfStreamBucket, 4638590a0fdSAndre Fischer inAprPool ); 4648590a0fdSAndre Fischer } 4658590a0fdSAndre Fischer 4668590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::handleSerfResponse( serf_request_t * inSerfRequest, 4678590a0fdSAndre Fischer serf_bucket_t * inSerfResponseBucket, 4688590a0fdSAndre Fischer apr_pool_t * inAprPool ) 4698590a0fdSAndre Fischer { 4708590a0fdSAndre Fischer mbHandleSerfResponseCalled = true; 4718590a0fdSAndre Fischer 4728590a0fdSAndre Fischer // some general response handling and error handling 4738590a0fdSAndre Fischer { 4748590a0fdSAndre Fischer if ( !inSerfResponseBucket ) 4758590a0fdSAndre Fischer { 4768590a0fdSAndre Fischer /* A NULL response can come back if the request failed completely */ 4778590a0fdSAndre Fischer mbProcessingDone = true; 4788590a0fdSAndre Fischer return APR_EGENERAL; 4798590a0fdSAndre Fischer } 4808590a0fdSAndre Fischer 4818590a0fdSAndre Fischer serf_status_line sl; 4828590a0fdSAndre Fischer apr_status_t status = serf_bucket_response_status( inSerfResponseBucket, &sl ); 4838590a0fdSAndre Fischer if ( status ) 4848590a0fdSAndre Fischer { 4858590a0fdSAndre Fischer mbProcessingDone = false; // allow another try in order to get a response 4868590a0fdSAndre Fischer return status; 4878590a0fdSAndre Fischer } 4888590a0fdSAndre Fischer // TODO - check, if response status code handling is correct 4898590a0fdSAndre Fischer mnHTTPStatusCode = ( sl.version != 0 && sl.code >= 0 ) 4908590a0fdSAndre Fischer ? static_cast< sal_uInt16 >( sl.code ) 4918590a0fdSAndre Fischer : SC_NONE; 4928590a0fdSAndre Fischer if ( sl.reason ) 4938590a0fdSAndre Fischer { 4948590a0fdSAndre Fischer mHTTPStatusCodeText = ::rtl::OUString::createFromAscii( sl.reason ); 4958590a0fdSAndre Fischer } 4968590a0fdSAndre Fischer if ( ( sl.version == 0 || sl.code < 0 ) || 4978590a0fdSAndre Fischer mnHTTPStatusCode >= 300 ) 4988590a0fdSAndre Fischer { 4998590a0fdSAndre Fischer if ( mnHTTPStatusCode == 301 || 5008590a0fdSAndre Fischer mnHTTPStatusCode == 302 || 5018590a0fdSAndre Fischer mnHTTPStatusCode == 303 || 5028590a0fdSAndre Fischer mnHTTPStatusCode == 307 ) 5038590a0fdSAndre Fischer { 5048590a0fdSAndre Fischer // new location for certain redirections 5058590a0fdSAndre Fischer serf_bucket_t *headers = serf_bucket_response_get_headers( inSerfResponseBucket ); 5068590a0fdSAndre Fischer const char* location = serf_bucket_headers_get( headers, "Location" ); 5078590a0fdSAndre Fischer if ( location ) 5088590a0fdSAndre Fischer { 5098590a0fdSAndre Fischer mRedirectLocation = rtl::OUString::createFromAscii( location ); 5108590a0fdSAndre Fischer } 5118590a0fdSAndre Fischer mbProcessingDone = true; 5128590a0fdSAndre Fischer return APR_EGENERAL; 5138590a0fdSAndre Fischer } 5148590a0fdSAndre Fischer else if ( mrSerfSession.isHeadRequestInProgress() && 5158590a0fdSAndre Fischer ( mnHTTPStatusCode == 401 || mnHTTPStatusCode == 407 ) ) 5168590a0fdSAndre Fischer { 5178590a0fdSAndre Fischer // keep going as authentication is not required on HEAD request. 5188590a0fdSAndre Fischer // the response already contains header fields. 5198590a0fdSAndre Fischer } 5208590a0fdSAndre Fischer else 5218590a0fdSAndre Fischer { 5228590a0fdSAndre Fischer mbProcessingDone = true; 5238590a0fdSAndre Fischer return APR_EGENERAL; 5248590a0fdSAndre Fischer } 5258590a0fdSAndre Fischer } 5268590a0fdSAndre Fischer } 5278590a0fdSAndre Fischer 5288590a0fdSAndre Fischer // request specific processing of the response bucket 5298590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 5308590a0fdSAndre Fischer mbProcessingDone = mpProcImpl->processSerfResponseBucket( inSerfRequest, 5318590a0fdSAndre Fischer inSerfResponseBucket, 5328590a0fdSAndre Fischer inAprPool, 5338590a0fdSAndre Fischer status ); 5348590a0fdSAndre Fischer 5358590a0fdSAndre Fischer return status; 5368590a0fdSAndre Fischer } 5378590a0fdSAndre Fischer 5388590a0fdSAndre Fischer } // namespace http_dav_ucp 5398590a0fdSAndre Fischer 540