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, 378590a0fdSAndre Fischer const rtl::OUString & inPath ) 388590a0fdSAndre Fischer : mrSerfSession( rSerfSession ) 398590a0fdSAndre Fischer , mPathStr( 0 ) 408590a0fdSAndre Fischer , mDestPathStr( 0 ) 418590a0fdSAndre Fischer , mpProcImpl( 0 ) 428590a0fdSAndre Fischer , mbProcessingDone( false ) 438590a0fdSAndre Fischer , mpDAVException() 448590a0fdSAndre Fischer , mnHTTPStatusCode( SC_NONE ) 458590a0fdSAndre Fischer , mHTTPStatusCodeText() 468590a0fdSAndre Fischer , mRedirectLocation() 47*fb7f54d2SOliver-Rainer Wittmann , mnSuccessfulCredentialAttempts( 0 ) 48*fb7f54d2SOliver-Rainer Wittmann , mbInputOfCredentialsAborted( false ) 498590a0fdSAndre Fischer , mbSetupSerfRequestCalled( false ) 508590a0fdSAndre Fischer , mbAcceptSerfResponseCalled( false ) 518590a0fdSAndre Fischer , mbHandleSerfResponseCalled( false ) 528590a0fdSAndre Fischer { 538590a0fdSAndre Fischer mPathStr = apr_pstrdup( mrSerfSession.getAprPool(), 548590a0fdSAndre Fischer rtl::OUStringToOString( inPath, RTL_TEXTENCODING_UTF8 ) ); 558590a0fdSAndre Fischer } 568590a0fdSAndre Fischer 578590a0fdSAndre Fischer SerfRequestProcessor::~SerfRequestProcessor() 588590a0fdSAndre Fischer { 598590a0fdSAndre Fischer delete mpProcImpl; 608590a0fdSAndre Fischer delete mpDAVException; 618590a0fdSAndre Fischer } 628590a0fdSAndre Fischer 638590a0fdSAndre Fischer void SerfRequestProcessor::prepareProcessor() 648590a0fdSAndre Fischer { 658590a0fdSAndre Fischer delete mpDAVException; 668590a0fdSAndre Fischer mpDAVException = 0; 678590a0fdSAndre Fischer mnHTTPStatusCode = SC_NONE; 688590a0fdSAndre Fischer mHTTPStatusCodeText = rtl::OUString(); 698590a0fdSAndre Fischer mRedirectLocation = rtl::OUString(); 708590a0fdSAndre Fischer 71*fb7f54d2SOliver-Rainer Wittmann mnSuccessfulCredentialAttempts = 0; 72*fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted = false; 738590a0fdSAndre Fischer mbSetupSerfRequestCalled = false; 748590a0fdSAndre Fischer mbAcceptSerfResponseCalled = false; 758590a0fdSAndre Fischer mbHandleSerfResponseCalled = false; 768590a0fdSAndre Fischer } 778590a0fdSAndre Fischer 788590a0fdSAndre Fischer // PROPFIND - allprop & named 798590a0fdSAndre Fischer bool SerfRequestProcessor::processPropFind( const Depth inDepth, 808590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inPropNames, 818590a0fdSAndre Fischer std::vector< DAVResource > & ioResources, 828590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 838590a0fdSAndre Fischer { 848590a0fdSAndre Fischer mpProcImpl = createPropFindReqProcImpl( mPathStr, 858590a0fdSAndre Fischer inDepth, 868590a0fdSAndre Fischer inPropNames, 878590a0fdSAndre Fischer ioResources ); 888590a0fdSAndre Fischer outSerfStatus = runProcessor(); 898590a0fdSAndre Fischer 908590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 918590a0fdSAndre Fischer } 928590a0fdSAndre Fischer 938590a0fdSAndre Fischer // PROPFIND - property names 948590a0fdSAndre Fischer bool SerfRequestProcessor::processPropFind( const Depth inDepth, 958590a0fdSAndre Fischer std::vector< DAVResourceInfo > & ioResInfo, 968590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 978590a0fdSAndre Fischer { 988590a0fdSAndre Fischer mpProcImpl = createPropFindReqProcImpl( mPathStr, 998590a0fdSAndre Fischer inDepth, 1008590a0fdSAndre Fischer ioResInfo ); 1018590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1028590a0fdSAndre Fischer 1038590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1048590a0fdSAndre Fischer } 1058590a0fdSAndre Fischer 1068590a0fdSAndre Fischer // PROPPATCH 1078590a0fdSAndre Fischer bool SerfRequestProcessor::processPropPatch( const std::vector< ProppatchValue > & inProperties, 1088590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1098590a0fdSAndre Fischer { 1108590a0fdSAndre Fischer mpProcImpl = createPropPatchReqProcImpl( mPathStr, 1118590a0fdSAndre Fischer inProperties ); 1128590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1138590a0fdSAndre Fischer 1148590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1158590a0fdSAndre Fischer } 1168590a0fdSAndre Fischer 1178590a0fdSAndre Fischer // GET 1188590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, 1198590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1208590a0fdSAndre Fischer { 1218590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 1228590a0fdSAndre Fischer xioInStrm ); 1238590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1248590a0fdSAndre Fischer 1258590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1268590a0fdSAndre Fischer } 1278590a0fdSAndre Fischer 1288590a0fdSAndre Fischer // GET inclusive header fields 1298590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, 1308590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 1318590a0fdSAndre Fischer DAVResource & ioResource, 1328590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1338590a0fdSAndre Fischer { 1348590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 1358590a0fdSAndre Fischer xioInStrm, 1368590a0fdSAndre Fischer inHeaderNames, 1378590a0fdSAndre Fischer ioResource ); 1388590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1398590a0fdSAndre Fischer 1408590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1418590a0fdSAndre Fischer } 1428590a0fdSAndre Fischer 1438590a0fdSAndre Fischer // GET 1448590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, 1458590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1468590a0fdSAndre Fischer { 1478590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 1488590a0fdSAndre Fischer xioOutStrm ); 1498590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1508590a0fdSAndre Fischer 1518590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1528590a0fdSAndre Fischer } 1538590a0fdSAndre Fischer 1548590a0fdSAndre Fischer // GET inclusive header fields 1558590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, 1568590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 1578590a0fdSAndre Fischer DAVResource & ioResource, 1588590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1598590a0fdSAndre Fischer { 1608590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 1618590a0fdSAndre Fischer xioOutStrm, 1628590a0fdSAndre Fischer inHeaderNames, 1638590a0fdSAndre Fischer ioResource ); 1648590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1658590a0fdSAndre Fischer 1668590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1678590a0fdSAndre Fischer } 1688590a0fdSAndre Fischer 1698590a0fdSAndre Fischer // HEAD 1708590a0fdSAndre Fischer bool SerfRequestProcessor::processHead( const std::vector< ::rtl::OUString > & inHeaderNames, 1718590a0fdSAndre Fischer DAVResource & ioResource, 1728590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1738590a0fdSAndre Fischer { 1748590a0fdSAndre Fischer mpProcImpl = createHeadReqProcImpl( mPathStr, 1758590a0fdSAndre Fischer inHeaderNames, 1768590a0fdSAndre Fischer ioResource ); 1778590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1788590a0fdSAndre Fischer 1798590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1808590a0fdSAndre Fischer } 1818590a0fdSAndre Fischer 1828590a0fdSAndre Fischer // PUT 1838590a0fdSAndre Fischer bool SerfRequestProcessor::processPut( const char* inData, 1848590a0fdSAndre Fischer apr_size_t inDataLen, 1858590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1868590a0fdSAndre Fischer { 1878590a0fdSAndre Fischer mpProcImpl = createPutReqProcImpl( mPathStr, 1888590a0fdSAndre Fischer inData, 1898590a0fdSAndre Fischer inDataLen ); 1908590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1918590a0fdSAndre Fischer 1928590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1938590a0fdSAndre Fischer } 1948590a0fdSAndre Fischer 1958590a0fdSAndre Fischer // POST 1968590a0fdSAndre Fischer bool SerfRequestProcessor::processPost( const char* inData, 1978590a0fdSAndre Fischer apr_size_t inDataLen, 1988590a0fdSAndre Fischer const rtl::OUString & inContentType, 1998590a0fdSAndre Fischer const rtl::OUString & inReferer, 2008590a0fdSAndre Fischer const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, 2018590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 2028590a0fdSAndre Fischer { 2038590a0fdSAndre Fischer mContentType = apr_pstrdup( mrSerfSession.getAprPool(), 2048590a0fdSAndre Fischer rtl::OUStringToOString( inContentType, RTL_TEXTENCODING_UTF8 ) ); 2058590a0fdSAndre Fischer mReferer = apr_pstrdup( mrSerfSession.getAprPool(), 2068590a0fdSAndre Fischer rtl::OUStringToOString( inReferer, RTL_TEXTENCODING_UTF8 ) ); 2078590a0fdSAndre Fischer mpProcImpl = createPostReqProcImpl( mPathStr, 2088590a0fdSAndre Fischer inData, 2098590a0fdSAndre Fischer inDataLen, 2108590a0fdSAndre Fischer mContentType, 2118590a0fdSAndre Fischer mReferer, 2128590a0fdSAndre Fischer xioInStrm ); 2138590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2148590a0fdSAndre Fischer 2158590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2168590a0fdSAndre Fischer } 2178590a0fdSAndre Fischer 2188590a0fdSAndre Fischer // POST 2198590a0fdSAndre Fischer bool SerfRequestProcessor::processPost( const char* inData, 2208590a0fdSAndre Fischer apr_size_t inDataLen, 2218590a0fdSAndre Fischer const rtl::OUString & inContentType, 2228590a0fdSAndre Fischer const rtl::OUString & inReferer, 2238590a0fdSAndre Fischer const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, 2248590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 2258590a0fdSAndre Fischer { 2268590a0fdSAndre Fischer mContentType = apr_pstrdup( mrSerfSession.getAprPool(), 2278590a0fdSAndre Fischer rtl::OUStringToOString( inContentType, RTL_TEXTENCODING_UTF8 ) ); 2288590a0fdSAndre Fischer mReferer = apr_pstrdup( mrSerfSession.getAprPool(), 2298590a0fdSAndre Fischer rtl::OUStringToOString( inReferer, RTL_TEXTENCODING_UTF8 ) ); 2308590a0fdSAndre Fischer mpProcImpl = createPostReqProcImpl( mPathStr, 2318590a0fdSAndre Fischer inData, 2328590a0fdSAndre Fischer inDataLen, 2338590a0fdSAndre Fischer mContentType, 2348590a0fdSAndre Fischer mReferer, 2358590a0fdSAndre Fischer xioOutStrm ); 2368590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2378590a0fdSAndre Fischer 2388590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2398590a0fdSAndre Fischer } 2408590a0fdSAndre Fischer 2418590a0fdSAndre Fischer // DELETE 2428590a0fdSAndre Fischer bool SerfRequestProcessor::processDelete( apr_status_t& outSerfStatus ) 2438590a0fdSAndre Fischer { 2448590a0fdSAndre Fischer mpProcImpl = createDeleteReqProcImpl( mPathStr ); 2458590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2468590a0fdSAndre Fischer 2478590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2488590a0fdSAndre Fischer } 2498590a0fdSAndre Fischer 2508590a0fdSAndre Fischer // MKCOL 2518590a0fdSAndre Fischer bool SerfRequestProcessor::processMkCol( apr_status_t& outSerfStatus ) 2528590a0fdSAndre Fischer { 2538590a0fdSAndre Fischer mpProcImpl = createMkColReqProcImpl( mPathStr ); 2548590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2558590a0fdSAndre Fischer 2568590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2578590a0fdSAndre Fischer } 2588590a0fdSAndre Fischer 2598590a0fdSAndre Fischer // COPY 2608590a0fdSAndre Fischer bool SerfRequestProcessor::processCopy( const rtl::OUString & inDestinationPath, 2618590a0fdSAndre Fischer const bool inOverwrite, 2628590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 2638590a0fdSAndre Fischer { 2648590a0fdSAndre Fischer mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), 2658590a0fdSAndre Fischer rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ) ); 2668590a0fdSAndre Fischer mpProcImpl = createCopyReqProcImpl( mPathStr, 2678590a0fdSAndre Fischer mDestPathStr, 2688590a0fdSAndre Fischer inOverwrite ); 2698590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2708590a0fdSAndre Fischer 2718590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2728590a0fdSAndre Fischer } 2738590a0fdSAndre Fischer 2748590a0fdSAndre Fischer // MOVE 2758590a0fdSAndre Fischer bool SerfRequestProcessor::processMove( const rtl::OUString & inDestinationPath, 2768590a0fdSAndre Fischer const bool inOverwrite, 2778590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 2788590a0fdSAndre Fischer { 2798590a0fdSAndre Fischer mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), 2808590a0fdSAndre Fischer rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ) ); 2818590a0fdSAndre Fischer mpProcImpl = createMoveReqProcImpl( mPathStr, 2828590a0fdSAndre Fischer mDestPathStr, 2838590a0fdSAndre Fischer inOverwrite ); 2848590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2858590a0fdSAndre Fischer 2868590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2878590a0fdSAndre Fischer } 2888590a0fdSAndre Fischer 2898590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::runProcessor() 2908590a0fdSAndre Fischer { 2918590a0fdSAndre Fischer prepareProcessor(); 2928590a0fdSAndre Fischer 2938590a0fdSAndre Fischer // create serf request 2948590a0fdSAndre Fischer serf_connection_request_create( mrSerfSession.getSerfConnection(), 2958590a0fdSAndre Fischer Serf_SetupRequest, 2968590a0fdSAndre Fischer this ); 2978590a0fdSAndre Fischer 2988590a0fdSAndre Fischer // perform serf request 2998590a0fdSAndre Fischer mbProcessingDone = false; 3008590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 3018590a0fdSAndre Fischer serf_context_t* pSerfContext = mrSerfSession.getSerfContext(); 3028590a0fdSAndre Fischer apr_pool_t* pAprPool = mrSerfSession.getAprPool(); 3038590a0fdSAndre Fischer while ( true ) 3048590a0fdSAndre Fischer { 3058590a0fdSAndre Fischer status = serf_context_run( pSerfContext, 3068590a0fdSAndre Fischer SERF_DURATION_FOREVER, 3078590a0fdSAndre Fischer pAprPool ); 3088590a0fdSAndre Fischer if ( APR_STATUS_IS_TIMEUP( status ) ) 3098590a0fdSAndre Fischer { 3108590a0fdSAndre Fischer continue; 3118590a0fdSAndre Fischer } 3128590a0fdSAndre Fischer if ( status != APR_SUCCESS ) 3138590a0fdSAndre Fischer { 3148590a0fdSAndre Fischer break; 3158590a0fdSAndre Fischer } 3168590a0fdSAndre Fischer if ( mbProcessingDone ) 3178590a0fdSAndre Fischer { 3188590a0fdSAndre Fischer break; 3198590a0fdSAndre Fischer } 3208590a0fdSAndre Fischer } 3218590a0fdSAndre Fischer 3228590a0fdSAndre Fischer postprocessProcessor( status ); 3238590a0fdSAndre Fischer 3248590a0fdSAndre Fischer return status; 3258590a0fdSAndre Fischer } 3268590a0fdSAndre Fischer 3278590a0fdSAndre Fischer void SerfRequestProcessor::postprocessProcessor( const apr_status_t inStatus ) 3288590a0fdSAndre Fischer { 3298590a0fdSAndre Fischer if ( inStatus == APR_SUCCESS ) 3308590a0fdSAndre Fischer { 3318590a0fdSAndre Fischer return; 3328590a0fdSAndre Fischer } 3338590a0fdSAndre Fischer 3348590a0fdSAndre Fischer switch ( inStatus ) 3358590a0fdSAndre Fischer { 3368590a0fdSAndre Fischer case APR_EGENERAL: 337*fb7f54d2SOliver-Rainer Wittmann case SERF_ERROR_AUTHN_FAILED: 3388590a0fdSAndre Fischer // general error; <mnHTTPStatusCode> provides more information 3398590a0fdSAndre Fischer { 3408590a0fdSAndre Fischer switch ( mnHTTPStatusCode ) 3418590a0fdSAndre Fischer { 3428590a0fdSAndre Fischer case SC_NONE: 3438590a0fdSAndre Fischer if ( !mbSetupSerfRequestCalled ) 3448590a0fdSAndre Fischer { 3458590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_LOOKUP, 3468590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( mrSerfSession.getHostName(), 3478590a0fdSAndre Fischer mrSerfSession.getPort() ) ); 3488590a0fdSAndre Fischer } 349*fb7f54d2SOliver-Rainer Wittmann else if ( mbInputOfCredentialsAborted ) 350*fb7f54d2SOliver-Rainer Wittmann { 351*fb7f54d2SOliver-Rainer Wittmann mpDAVException = new DAVException( DAVException::DAV_HTTP_NOAUTH, 352*fb7f54d2SOliver-Rainer Wittmann SerfUri::makeConnectionEndPointString( mrSerfSession.getHostName(), 353*fb7f54d2SOliver-Rainer Wittmann mrSerfSession.getPort() ) ); 354*fb7f54d2SOliver-Rainer Wittmann } 3558590a0fdSAndre Fischer else 3568590a0fdSAndre Fischer { 3578590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR, 3588590a0fdSAndre Fischer mHTTPStatusCodeText, 3598590a0fdSAndre Fischer mnHTTPStatusCode ); 3608590a0fdSAndre Fischer } 3618590a0fdSAndre Fischer break; 3628590a0fdSAndre Fischer case SC_MOVED_PERMANENTLY: 3638590a0fdSAndre Fischer case SC_MOVED_TEMPORARILY: 3648590a0fdSAndre Fischer case SC_SEE_OTHER: 3658590a0fdSAndre Fischer case SC_TEMPORARY_REDIRECT: 3668590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_REDIRECT, 3678590a0fdSAndre Fischer mRedirectLocation ); 3688590a0fdSAndre Fischer break; 3698590a0fdSAndre Fischer default: 3708590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR, 3718590a0fdSAndre Fischer mHTTPStatusCodeText, 3728590a0fdSAndre Fischer mnHTTPStatusCode ); 3738590a0fdSAndre Fischer break; 3748590a0fdSAndre Fischer } 3758590a0fdSAndre Fischer } 3768590a0fdSAndre Fischer break; 3778590a0fdSAndre Fischer 3788590a0fdSAndre Fischer default: 3798590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR ); 3808590a0fdSAndre Fischer break; 3818590a0fdSAndre Fischer } 3828590a0fdSAndre Fischer 3838590a0fdSAndre Fischer } 3848590a0fdSAndre Fischer 3858590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::provideSerfCredentials( char ** outUsername, 3868590a0fdSAndre Fischer char ** outPassword, 3878590a0fdSAndre Fischer serf_request_t * inRequest, 3888590a0fdSAndre Fischer int inCode, 3898590a0fdSAndre Fischer const char *inAuthProtocol, 3908590a0fdSAndre Fischer const char *inRealm, 3918590a0fdSAndre Fischer apr_pool_t *inAprPool ) 3928590a0fdSAndre Fischer { 393*fb7f54d2SOliver-Rainer Wittmann // as each successful provided credentials are tried twice - see below - the 394*fb7f54d2SOliver-Rainer Wittmann // number of real attempts is half of the value of <mnSuccessfulCredentialAttempts> 395*fb7f54d2SOliver-Rainer Wittmann if ( (mnSuccessfulCredentialAttempts / 2) >= 5 || 396*fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted ) 397*fb7f54d2SOliver-Rainer Wittmann { 398*fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted = true; 399*fb7f54d2SOliver-Rainer Wittmann return SERF_ERROR_AUTHN_FAILED; 400*fb7f54d2SOliver-Rainer Wittmann } 401*fb7f54d2SOliver-Rainer Wittmann 402*fb7f54d2SOliver-Rainer Wittmann // because serf keeps credentials only for a connection in case of digest authentication 403*fb7f54d2SOliver-Rainer Wittmann // we give each successful provided credentials a second try in order to workaround the 404*fb7f54d2SOliver-Rainer Wittmann // situation that the connection for which the credentials have been provided has been closed 405*fb7f54d2SOliver-Rainer Wittmann // before the provided credentials could be applied for the request. 406*fb7f54d2SOliver-Rainer Wittmann apr_status_t status = mrSerfSession.provideSerfCredentials( (mnSuccessfulCredentialAttempts % 2) == 1, 407*fb7f54d2SOliver-Rainer Wittmann outUsername, 4088590a0fdSAndre Fischer outPassword, 4098590a0fdSAndre Fischer inRequest, 4108590a0fdSAndre Fischer inCode, 4118590a0fdSAndre Fischer inAuthProtocol, 4128590a0fdSAndre Fischer inRealm, 4138590a0fdSAndre Fischer inAprPool ); 414*fb7f54d2SOliver-Rainer Wittmann if ( status != APR_SUCCESS ) 415*fb7f54d2SOliver-Rainer Wittmann { 416*fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted = true; 417*fb7f54d2SOliver-Rainer Wittmann } 418*fb7f54d2SOliver-Rainer Wittmann else 419*fb7f54d2SOliver-Rainer Wittmann { 420*fb7f54d2SOliver-Rainer Wittmann ++mnSuccessfulCredentialAttempts; 421*fb7f54d2SOliver-Rainer Wittmann } 422*fb7f54d2SOliver-Rainer Wittmann 423*fb7f54d2SOliver-Rainer Wittmann return status; 4248590a0fdSAndre Fischer } 4258590a0fdSAndre Fischer 4268590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::setupSerfRequest( serf_request_t * inSerfRequest, 4278590a0fdSAndre Fischer serf_bucket_t ** outSerfRequestBucket, 4288590a0fdSAndre Fischer serf_response_acceptor_t * outSerfResponseAcceptor, 4298590a0fdSAndre Fischer void ** outSerfResponseAcceptorBaton, 4308590a0fdSAndre Fischer serf_response_handler_t * outSerfResponseHandler, 4318590a0fdSAndre Fischer void ** outSerfResponseHandlerBaton, 4328590a0fdSAndre Fischer apr_pool_t * /*inAprPool*/ ) 4338590a0fdSAndre Fischer { 4348590a0fdSAndre Fischer mbSetupSerfRequestCalled = true; 4358590a0fdSAndre Fischer *outSerfRequestBucket = mpProcImpl->createSerfRequestBucket( inSerfRequest ); 4368590a0fdSAndre Fischer 4378590a0fdSAndre Fischer // apply callbacks for accepting response and handling response 4388590a0fdSAndre Fischer *outSerfResponseAcceptor = Serf_AcceptResponse; 4398590a0fdSAndre Fischer *outSerfResponseAcceptorBaton = this; 4408590a0fdSAndre Fischer *outSerfResponseHandler = Serf_HandleResponse; 4418590a0fdSAndre Fischer *outSerfResponseHandlerBaton = this; 4428590a0fdSAndre Fischer 4438590a0fdSAndre Fischer return APR_SUCCESS; 4448590a0fdSAndre Fischer } 4458590a0fdSAndre Fischer 4468590a0fdSAndre Fischer serf_bucket_t* SerfRequestProcessor::acceptSerfResponse( serf_request_t * inSerfRequest, 4478590a0fdSAndre Fischer serf_bucket_t * inSerfStreamBucket, 4488590a0fdSAndre Fischer apr_pool_t * inAprPool ) 4498590a0fdSAndre Fischer { 4508590a0fdSAndre Fischer mbAcceptSerfResponseCalled = true; 4518590a0fdSAndre Fischer return mrSerfSession.acceptSerfResponse( inSerfRequest, 4528590a0fdSAndre Fischer inSerfStreamBucket, 4538590a0fdSAndre Fischer inAprPool ); 4548590a0fdSAndre Fischer } 4558590a0fdSAndre Fischer 4568590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::handleSerfResponse( serf_request_t * inSerfRequest, 4578590a0fdSAndre Fischer serf_bucket_t * inSerfResponseBucket, 4588590a0fdSAndre Fischer apr_pool_t * inAprPool ) 4598590a0fdSAndre Fischer { 4608590a0fdSAndre Fischer mbHandleSerfResponseCalled = true; 4618590a0fdSAndre Fischer 4628590a0fdSAndre Fischer // some general response handling and error handling 4638590a0fdSAndre Fischer { 4648590a0fdSAndre Fischer if ( !inSerfResponseBucket ) 4658590a0fdSAndre Fischer { 4668590a0fdSAndre Fischer /* A NULL response can come back if the request failed completely */ 4678590a0fdSAndre Fischer mbProcessingDone = true; 4688590a0fdSAndre Fischer return APR_EGENERAL; 4698590a0fdSAndre Fischer } 4708590a0fdSAndre Fischer 4718590a0fdSAndre Fischer serf_status_line sl; 4728590a0fdSAndre Fischer apr_status_t status = serf_bucket_response_status( inSerfResponseBucket, &sl ); 4738590a0fdSAndre Fischer if ( status ) 4748590a0fdSAndre Fischer { 4758590a0fdSAndre Fischer mbProcessingDone = false; // allow another try in order to get a response 4768590a0fdSAndre Fischer return status; 4778590a0fdSAndre Fischer } 4788590a0fdSAndre Fischer // TODO - check, if response status code handling is correct 4798590a0fdSAndre Fischer mnHTTPStatusCode = ( sl.version != 0 && sl.code >= 0 ) 4808590a0fdSAndre Fischer ? static_cast< sal_uInt16 >( sl.code ) 4818590a0fdSAndre Fischer : SC_NONE; 4828590a0fdSAndre Fischer if ( sl.reason ) 4838590a0fdSAndre Fischer { 4848590a0fdSAndre Fischer mHTTPStatusCodeText = ::rtl::OUString::createFromAscii( sl.reason ); 4858590a0fdSAndre Fischer } 4868590a0fdSAndre Fischer if ( ( sl.version == 0 || sl.code < 0 ) || 4878590a0fdSAndre Fischer mnHTTPStatusCode >= 300 ) 4888590a0fdSAndre Fischer { 4898590a0fdSAndre Fischer if ( mnHTTPStatusCode == 301 || 4908590a0fdSAndre Fischer mnHTTPStatusCode == 302 || 4918590a0fdSAndre Fischer mnHTTPStatusCode == 303 || 4928590a0fdSAndre Fischer mnHTTPStatusCode == 307 ) 4938590a0fdSAndre Fischer { 4948590a0fdSAndre Fischer // new location for certain redirections 4958590a0fdSAndre Fischer serf_bucket_t *headers = serf_bucket_response_get_headers( inSerfResponseBucket ); 4968590a0fdSAndre Fischer const char* location = serf_bucket_headers_get( headers, "Location" ); 4978590a0fdSAndre Fischer if ( location ) 4988590a0fdSAndre Fischer { 4998590a0fdSAndre Fischer mRedirectLocation = rtl::OUString::createFromAscii( location ); 5008590a0fdSAndre Fischer } 5018590a0fdSAndre Fischer mbProcessingDone = true; 5028590a0fdSAndre Fischer return APR_EGENERAL; 5038590a0fdSAndre Fischer } 5048590a0fdSAndre Fischer else if ( mrSerfSession.isHeadRequestInProgress() && 5058590a0fdSAndre Fischer ( mnHTTPStatusCode == 401 || mnHTTPStatusCode == 407 ) ) 5068590a0fdSAndre Fischer { 5078590a0fdSAndre Fischer // keep going as authentication is not required on HEAD request. 5088590a0fdSAndre Fischer // the response already contains header fields. 5098590a0fdSAndre Fischer } 5108590a0fdSAndre Fischer else 5118590a0fdSAndre Fischer { 5128590a0fdSAndre Fischer mbProcessingDone = true; 5138590a0fdSAndre Fischer return APR_EGENERAL; 5148590a0fdSAndre Fischer } 5158590a0fdSAndre Fischer } 5168590a0fdSAndre Fischer } 5178590a0fdSAndre Fischer 5188590a0fdSAndre Fischer // request specific processing of the response bucket 5198590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 5208590a0fdSAndre Fischer mbProcessingDone = mpProcImpl->processSerfResponseBucket( inSerfRequest, 5218590a0fdSAndre Fischer inSerfResponseBucket, 5228590a0fdSAndre Fischer inAprPool, 5238590a0fdSAndre Fischer status ); 5248590a0fdSAndre Fischer 5258590a0fdSAndre Fischer return status; 5268590a0fdSAndre Fischer } 5278590a0fdSAndre Fischer 5288590a0fdSAndre Fischer } // namespace http_dav_ucp 5298590a0fdSAndre Fischer 530