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 25*c1c10f68SAriel Constenla-Haile #include "SerfRequestProcessor.hxx" 26*c1c10f68SAriel Constenla-Haile #include "SerfRequestProcessorImpl.hxx" 27*c1c10f68SAriel Constenla-Haile #include "SerfRequestProcessorImplFac.hxx" 28*c1c10f68SAriel Constenla-Haile #include "SerfCallbacks.hxx" 29*c1c10f68SAriel Constenla-Haile #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, 3749989859SOliver-Rainer Wittmann const rtl::OUString & inPath, 3849989859SOliver-Rainer Wittmann const bool bUseChunkedEncoding ) 398590a0fdSAndre Fischer : mrSerfSession( rSerfSession ) 408590a0fdSAndre Fischer , mPathStr( 0 ) 4149989859SOliver-Rainer Wittmann , mbUseChunkedEncoding( bUseChunkedEncoding ) 428590a0fdSAndre Fischer , mDestPathStr( 0 ) 4349989859SOliver-Rainer Wittmann , mContentType( 0 ) 4449989859SOliver-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, 89e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 908590a0fdSAndre Fischer inDepth, 918590a0fdSAndre Fischer inPropNames, 928590a0fdSAndre Fischer ioResources ); 938590a0fdSAndre Fischer outSerfStatus = runProcessor(); 948590a0fdSAndre Fischer 958590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 968590a0fdSAndre Fischer } 978590a0fdSAndre Fischer 988590a0fdSAndre Fischer // PROPFIND - property names 998590a0fdSAndre Fischer bool SerfRequestProcessor::processPropFind( const Depth inDepth, 1008590a0fdSAndre Fischer std::vector< DAVResourceInfo > & ioResInfo, 1018590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1028590a0fdSAndre Fischer { 1038590a0fdSAndre Fischer mpProcImpl = createPropFindReqProcImpl( mPathStr, 104e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 1058590a0fdSAndre Fischer inDepth, 1068590a0fdSAndre Fischer ioResInfo ); 1078590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1088590a0fdSAndre Fischer 1098590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1108590a0fdSAndre Fischer } 1118590a0fdSAndre Fischer 1128590a0fdSAndre Fischer // PROPPATCH 1138590a0fdSAndre Fischer bool SerfRequestProcessor::processPropPatch( const std::vector< ProppatchValue > & inProperties, 1148590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1158590a0fdSAndre Fischer { 1168590a0fdSAndre Fischer mpProcImpl = createPropPatchReqProcImpl( mPathStr, 117e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 1188590a0fdSAndre Fischer inProperties ); 1198590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1208590a0fdSAndre Fischer 1218590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1228590a0fdSAndre Fischer } 1238590a0fdSAndre Fischer 1248590a0fdSAndre Fischer // GET 1258590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, 1268590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1278590a0fdSAndre Fischer { 1288590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 129e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 1308590a0fdSAndre Fischer xioInStrm ); 1318590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1328590a0fdSAndre Fischer 1338590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1348590a0fdSAndre Fischer } 1358590a0fdSAndre Fischer 1368590a0fdSAndre Fischer // GET inclusive header fields 1378590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, 1388590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 1398590a0fdSAndre Fischer DAVResource & ioResource, 1408590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1418590a0fdSAndre Fischer { 1428590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 143e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 1448590a0fdSAndre Fischer xioInStrm, 1458590a0fdSAndre Fischer inHeaderNames, 1468590a0fdSAndre Fischer ioResource ); 1478590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1488590a0fdSAndre Fischer 1498590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1508590a0fdSAndre Fischer } 1518590a0fdSAndre Fischer 1528590a0fdSAndre Fischer // GET 1538590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, 1548590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1558590a0fdSAndre Fischer { 1568590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 157e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 1588590a0fdSAndre Fischer xioOutStrm ); 1598590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1608590a0fdSAndre Fischer 1618590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1628590a0fdSAndre Fischer } 1638590a0fdSAndre Fischer 1648590a0fdSAndre Fischer // GET inclusive header fields 1658590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, 1668590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 1678590a0fdSAndre Fischer DAVResource & ioResource, 1688590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1698590a0fdSAndre Fischer { 1708590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 171e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 1728590a0fdSAndre Fischer xioOutStrm, 1738590a0fdSAndre Fischer inHeaderNames, 1748590a0fdSAndre Fischer ioResource ); 1758590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1768590a0fdSAndre Fischer 1778590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1788590a0fdSAndre Fischer } 1798590a0fdSAndre Fischer 1808590a0fdSAndre Fischer // HEAD 1818590a0fdSAndre Fischer bool SerfRequestProcessor::processHead( const std::vector< ::rtl::OUString > & inHeaderNames, 1828590a0fdSAndre Fischer DAVResource & ioResource, 1838590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1848590a0fdSAndre Fischer { 1858590a0fdSAndre Fischer mpProcImpl = createHeadReqProcImpl( mPathStr, 186e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 1878590a0fdSAndre Fischer inHeaderNames, 1888590a0fdSAndre Fischer ioResource ); 1898590a0fdSAndre Fischer outSerfStatus = runProcessor(); 1908590a0fdSAndre Fischer 1918590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 1928590a0fdSAndre Fischer } 1938590a0fdSAndre Fischer 1948590a0fdSAndre Fischer // PUT 1958590a0fdSAndre Fischer bool SerfRequestProcessor::processPut( const char* inData, 1968590a0fdSAndre Fischer apr_size_t inDataLen, 1978590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 1988590a0fdSAndre Fischer { 1998590a0fdSAndre Fischer mpProcImpl = createPutReqProcImpl( mPathStr, 200e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 2018590a0fdSAndre Fischer inData, 2028590a0fdSAndre Fischer inDataLen ); 2038590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2048590a0fdSAndre Fischer 2058590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2068590a0fdSAndre Fischer } 2078590a0fdSAndre Fischer 2088590a0fdSAndre Fischer // POST 2098590a0fdSAndre Fischer bool SerfRequestProcessor::processPost( const char* inData, 2108590a0fdSAndre Fischer apr_size_t inDataLen, 2118590a0fdSAndre Fischer const rtl::OUString & inContentType, 2128590a0fdSAndre Fischer const rtl::OUString & inReferer, 2138590a0fdSAndre Fischer const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, 2148590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 2158590a0fdSAndre Fischer { 2168590a0fdSAndre Fischer mContentType = apr_pstrdup( mrSerfSession.getAprPool(), 2178590a0fdSAndre Fischer rtl::OUStringToOString( inContentType, RTL_TEXTENCODING_UTF8 ) ); 2188590a0fdSAndre Fischer mReferer = apr_pstrdup( mrSerfSession.getAprPool(), 2198590a0fdSAndre Fischer rtl::OUStringToOString( inReferer, RTL_TEXTENCODING_UTF8 ) ); 2208590a0fdSAndre Fischer mpProcImpl = createPostReqProcImpl( mPathStr, 221e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 2228590a0fdSAndre Fischer inData, 2238590a0fdSAndre Fischer inDataLen, 2248590a0fdSAndre Fischer mContentType, 2258590a0fdSAndre Fischer mReferer, 2268590a0fdSAndre Fischer xioInStrm ); 2278590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2288590a0fdSAndre Fischer 2298590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2308590a0fdSAndre Fischer } 2318590a0fdSAndre Fischer 2328590a0fdSAndre Fischer // POST 2338590a0fdSAndre Fischer bool SerfRequestProcessor::processPost( const char* inData, 2348590a0fdSAndre Fischer apr_size_t inDataLen, 2358590a0fdSAndre Fischer const rtl::OUString & inContentType, 2368590a0fdSAndre Fischer const rtl::OUString & inReferer, 2378590a0fdSAndre Fischer const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, 2388590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 2398590a0fdSAndre Fischer { 2408590a0fdSAndre Fischer mContentType = apr_pstrdup( mrSerfSession.getAprPool(), 2418590a0fdSAndre Fischer rtl::OUStringToOString( inContentType, RTL_TEXTENCODING_UTF8 ) ); 2428590a0fdSAndre Fischer mReferer = apr_pstrdup( mrSerfSession.getAprPool(), 2438590a0fdSAndre Fischer rtl::OUStringToOString( inReferer, RTL_TEXTENCODING_UTF8 ) ); 2448590a0fdSAndre Fischer mpProcImpl = createPostReqProcImpl( mPathStr, 245e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 2468590a0fdSAndre Fischer inData, 2478590a0fdSAndre Fischer inDataLen, 2488590a0fdSAndre Fischer mContentType, 2498590a0fdSAndre Fischer mReferer, 2508590a0fdSAndre Fischer xioOutStrm ); 2518590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2528590a0fdSAndre Fischer 2538590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2548590a0fdSAndre Fischer } 2558590a0fdSAndre Fischer 2568590a0fdSAndre Fischer // DELETE 2578590a0fdSAndre Fischer bool SerfRequestProcessor::processDelete( apr_status_t& outSerfStatus ) 2588590a0fdSAndre Fischer { 259e9ff7e89SOliver-Rainer Wittmann mpProcImpl = createDeleteReqProcImpl( mPathStr, 260e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders ); 2618590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2628590a0fdSAndre Fischer 2638590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2648590a0fdSAndre Fischer } 2658590a0fdSAndre Fischer 2668590a0fdSAndre Fischer // MKCOL 2678590a0fdSAndre Fischer bool SerfRequestProcessor::processMkCol( apr_status_t& outSerfStatus ) 2688590a0fdSAndre Fischer { 269e9ff7e89SOliver-Rainer Wittmann mpProcImpl = createMkColReqProcImpl( mPathStr, 270e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders ); 2718590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2728590a0fdSAndre Fischer 2738590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2748590a0fdSAndre Fischer } 2758590a0fdSAndre Fischer 2768590a0fdSAndre Fischer // COPY 2778590a0fdSAndre Fischer bool SerfRequestProcessor::processCopy( const rtl::OUString & inDestinationPath, 2788590a0fdSAndre Fischer const bool inOverwrite, 2798590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 2808590a0fdSAndre Fischer { 2818590a0fdSAndre Fischer mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), 2828590a0fdSAndre Fischer rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ) ); 2838590a0fdSAndre Fischer mpProcImpl = createCopyReqProcImpl( mPathStr, 284e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 2858590a0fdSAndre Fischer mDestPathStr, 2868590a0fdSAndre Fischer inOverwrite ); 2878590a0fdSAndre Fischer outSerfStatus = runProcessor(); 2888590a0fdSAndre Fischer 2898590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 2908590a0fdSAndre Fischer } 2918590a0fdSAndre Fischer 2928590a0fdSAndre Fischer // MOVE 2938590a0fdSAndre Fischer bool SerfRequestProcessor::processMove( const rtl::OUString & inDestinationPath, 2948590a0fdSAndre Fischer const bool inOverwrite, 2958590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 2968590a0fdSAndre Fischer { 2978590a0fdSAndre Fischer mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), 2988590a0fdSAndre Fischer rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ) ); 2998590a0fdSAndre Fischer mpProcImpl = createMoveReqProcImpl( mPathStr, 300e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders, 3018590a0fdSAndre Fischer mDestPathStr, 3028590a0fdSAndre Fischer inOverwrite ); 3038590a0fdSAndre Fischer outSerfStatus = runProcessor(); 3048590a0fdSAndre Fischer 3058590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 3068590a0fdSAndre Fischer } 3078590a0fdSAndre Fischer 3088590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::runProcessor() 3098590a0fdSAndre Fischer { 3108590a0fdSAndre Fischer prepareProcessor(); 3118590a0fdSAndre Fischer 31249989859SOliver-Rainer Wittmann // activate chunked encoding, if requested 31349989859SOliver-Rainer Wittmann if ( mbUseChunkedEncoding ) 31449989859SOliver-Rainer Wittmann { 31549989859SOliver-Rainer Wittmann mpProcImpl->activateChunkedEncoding(); 31649989859SOliver-Rainer Wittmann } 31749989859SOliver-Rainer Wittmann 3188590a0fdSAndre Fischer // create serf request 3198590a0fdSAndre Fischer serf_connection_request_create( mrSerfSession.getSerfConnection(), 3208590a0fdSAndre Fischer Serf_SetupRequest, 3218590a0fdSAndre Fischer this ); 3228590a0fdSAndre Fischer 3238590a0fdSAndre Fischer // perform serf request 3248590a0fdSAndre Fischer mbProcessingDone = false; 3258590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 3268590a0fdSAndre Fischer serf_context_t* pSerfContext = mrSerfSession.getSerfContext(); 3278590a0fdSAndre Fischer apr_pool_t* pAprPool = mrSerfSession.getAprPool(); 3288590a0fdSAndre Fischer while ( true ) 3298590a0fdSAndre Fischer { 3308590a0fdSAndre Fischer status = serf_context_run( pSerfContext, 3318590a0fdSAndre Fischer SERF_DURATION_FOREVER, 3328590a0fdSAndre Fischer pAprPool ); 3338590a0fdSAndre Fischer if ( APR_STATUS_IS_TIMEUP( status ) ) 3348590a0fdSAndre Fischer { 3358590a0fdSAndre Fischer continue; 3368590a0fdSAndre Fischer } 3378590a0fdSAndre Fischer if ( status != APR_SUCCESS ) 3388590a0fdSAndre Fischer { 3398590a0fdSAndre Fischer break; 3408590a0fdSAndre Fischer } 3418590a0fdSAndre Fischer if ( mbProcessingDone ) 3428590a0fdSAndre Fischer { 3438590a0fdSAndre Fischer break; 3448590a0fdSAndre Fischer } 3458590a0fdSAndre Fischer } 3468590a0fdSAndre Fischer 3478590a0fdSAndre Fischer postprocessProcessor( status ); 3488590a0fdSAndre Fischer 3498590a0fdSAndre Fischer return status; 3508590a0fdSAndre Fischer } 3518590a0fdSAndre Fischer 3528590a0fdSAndre Fischer void SerfRequestProcessor::postprocessProcessor( const apr_status_t inStatus ) 3538590a0fdSAndre Fischer { 3548590a0fdSAndre Fischer if ( inStatus == APR_SUCCESS ) 3558590a0fdSAndre Fischer { 3568590a0fdSAndre Fischer return; 3578590a0fdSAndre Fischer } 3588590a0fdSAndre Fischer 3598590a0fdSAndre Fischer switch ( inStatus ) 3608590a0fdSAndre Fischer { 3618590a0fdSAndre Fischer case APR_EGENERAL: 362fb7f54d2SOliver-Rainer Wittmann case SERF_ERROR_AUTHN_FAILED: 3638590a0fdSAndre Fischer // general error; <mnHTTPStatusCode> provides more information 3648590a0fdSAndre Fischer { 3658590a0fdSAndre Fischer switch ( mnHTTPStatusCode ) 3668590a0fdSAndre Fischer { 3678590a0fdSAndre Fischer case SC_NONE: 3688590a0fdSAndre Fischer if ( !mbSetupSerfRequestCalled ) 3698590a0fdSAndre Fischer { 3708590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_LOOKUP, 3718590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( mrSerfSession.getHostName(), 3728590a0fdSAndre Fischer mrSerfSession.getPort() ) ); 3738590a0fdSAndre Fischer } 374fb7f54d2SOliver-Rainer Wittmann else if ( mbInputOfCredentialsAborted ) 375fb7f54d2SOliver-Rainer Wittmann { 376fb7f54d2SOliver-Rainer Wittmann mpDAVException = new DAVException( DAVException::DAV_HTTP_NOAUTH, 377fb7f54d2SOliver-Rainer Wittmann SerfUri::makeConnectionEndPointString( mrSerfSession.getHostName(), 378fb7f54d2SOliver-Rainer Wittmann mrSerfSession.getPort() ) ); 379fb7f54d2SOliver-Rainer Wittmann } 3808590a0fdSAndre Fischer else 3818590a0fdSAndre Fischer { 3828590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR, 3838590a0fdSAndre Fischer mHTTPStatusCodeText, 3848590a0fdSAndre Fischer mnHTTPStatusCode ); 3858590a0fdSAndre Fischer } 3868590a0fdSAndre Fischer break; 3878590a0fdSAndre Fischer case SC_MOVED_PERMANENTLY: 3888590a0fdSAndre Fischer case SC_MOVED_TEMPORARILY: 3898590a0fdSAndre Fischer case SC_SEE_OTHER: 3908590a0fdSAndre Fischer case SC_TEMPORARY_REDIRECT: 3918590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_REDIRECT, 3928590a0fdSAndre Fischer mRedirectLocation ); 3938590a0fdSAndre Fischer break; 3948590a0fdSAndre Fischer default: 3958590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR, 3968590a0fdSAndre Fischer mHTTPStatusCodeText, 3978590a0fdSAndre Fischer mnHTTPStatusCode ); 3988590a0fdSAndre Fischer break; 3998590a0fdSAndre Fischer } 4008590a0fdSAndre Fischer } 4018590a0fdSAndre Fischer break; 4028590a0fdSAndre Fischer 4038590a0fdSAndre Fischer default: 4048590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR ); 4058590a0fdSAndre Fischer break; 4068590a0fdSAndre Fischer } 4078590a0fdSAndre Fischer 4088590a0fdSAndre Fischer } 4098590a0fdSAndre Fischer 4108590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::provideSerfCredentials( char ** outUsername, 4118590a0fdSAndre Fischer char ** outPassword, 4128590a0fdSAndre Fischer serf_request_t * inRequest, 4138590a0fdSAndre Fischer int inCode, 4148590a0fdSAndre Fischer const char *inAuthProtocol, 4158590a0fdSAndre Fischer const char *inRealm, 4168590a0fdSAndre Fischer apr_pool_t *inAprPool ) 4178590a0fdSAndre Fischer { 418fb7f54d2SOliver-Rainer Wittmann // as each successful provided credentials are tried twice - see below - the 419fb7f54d2SOliver-Rainer Wittmann // number of real attempts is half of the value of <mnSuccessfulCredentialAttempts> 420fb7f54d2SOliver-Rainer Wittmann if ( (mnSuccessfulCredentialAttempts / 2) >= 5 || 421fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted ) 422fb7f54d2SOliver-Rainer Wittmann { 423fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted = true; 424fb7f54d2SOliver-Rainer Wittmann return SERF_ERROR_AUTHN_FAILED; 425fb7f54d2SOliver-Rainer Wittmann } 426fb7f54d2SOliver-Rainer Wittmann 427fb7f54d2SOliver-Rainer Wittmann // because serf keeps credentials only for a connection in case of digest authentication 428fb7f54d2SOliver-Rainer Wittmann // we give each successful provided credentials a second try in order to workaround the 429fb7f54d2SOliver-Rainer Wittmann // situation that the connection for which the credentials have been provided has been closed 430fb7f54d2SOliver-Rainer Wittmann // before the provided credentials could be applied for the request. 431fb7f54d2SOliver-Rainer Wittmann apr_status_t status = mrSerfSession.provideSerfCredentials( (mnSuccessfulCredentialAttempts % 2) == 1, 432fb7f54d2SOliver-Rainer Wittmann outUsername, 4338590a0fdSAndre Fischer outPassword, 4348590a0fdSAndre Fischer inRequest, 4358590a0fdSAndre Fischer inCode, 4368590a0fdSAndre Fischer inAuthProtocol, 4378590a0fdSAndre Fischer inRealm, 4388590a0fdSAndre Fischer inAprPool ); 439fb7f54d2SOliver-Rainer Wittmann if ( status != APR_SUCCESS ) 440fb7f54d2SOliver-Rainer Wittmann { 441fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted = true; 442fb7f54d2SOliver-Rainer Wittmann } 443fb7f54d2SOliver-Rainer Wittmann else 444fb7f54d2SOliver-Rainer Wittmann { 445fb7f54d2SOliver-Rainer Wittmann ++mnSuccessfulCredentialAttempts; 446fb7f54d2SOliver-Rainer Wittmann } 447fb7f54d2SOliver-Rainer Wittmann 448fb7f54d2SOliver-Rainer Wittmann return status; 4498590a0fdSAndre Fischer } 4508590a0fdSAndre Fischer 4518590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::setupSerfRequest( serf_request_t * inSerfRequest, 4528590a0fdSAndre Fischer serf_bucket_t ** outSerfRequestBucket, 4538590a0fdSAndre Fischer serf_response_acceptor_t * outSerfResponseAcceptor, 4548590a0fdSAndre Fischer void ** outSerfResponseAcceptorBaton, 4558590a0fdSAndre Fischer serf_response_handler_t * outSerfResponseHandler, 4568590a0fdSAndre Fischer void ** outSerfResponseHandlerBaton, 4578590a0fdSAndre Fischer apr_pool_t * /*inAprPool*/ ) 4588590a0fdSAndre Fischer { 4598590a0fdSAndre Fischer mbSetupSerfRequestCalled = true; 4608590a0fdSAndre Fischer *outSerfRequestBucket = mpProcImpl->createSerfRequestBucket( inSerfRequest ); 4618590a0fdSAndre Fischer 4628590a0fdSAndre Fischer // apply callbacks for accepting response and handling response 4638590a0fdSAndre Fischer *outSerfResponseAcceptor = Serf_AcceptResponse; 4648590a0fdSAndre Fischer *outSerfResponseAcceptorBaton = this; 4658590a0fdSAndre Fischer *outSerfResponseHandler = Serf_HandleResponse; 4668590a0fdSAndre Fischer *outSerfResponseHandlerBaton = this; 4678590a0fdSAndre Fischer 4688590a0fdSAndre Fischer return APR_SUCCESS; 4698590a0fdSAndre Fischer } 4708590a0fdSAndre Fischer 4718590a0fdSAndre Fischer serf_bucket_t* SerfRequestProcessor::acceptSerfResponse( serf_request_t * inSerfRequest, 4728590a0fdSAndre Fischer serf_bucket_t * inSerfStreamBucket, 4738590a0fdSAndre Fischer apr_pool_t * inAprPool ) 4748590a0fdSAndre Fischer { 4758590a0fdSAndre Fischer mbAcceptSerfResponseCalled = true; 4768590a0fdSAndre Fischer return mrSerfSession.acceptSerfResponse( inSerfRequest, 4778590a0fdSAndre Fischer inSerfStreamBucket, 4788590a0fdSAndre Fischer inAprPool ); 4798590a0fdSAndre Fischer } 4808590a0fdSAndre Fischer 4818590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::handleSerfResponse( serf_request_t * inSerfRequest, 4828590a0fdSAndre Fischer serf_bucket_t * inSerfResponseBucket, 4838590a0fdSAndre Fischer apr_pool_t * inAprPool ) 4848590a0fdSAndre Fischer { 4858590a0fdSAndre Fischer mbHandleSerfResponseCalled = true; 4868590a0fdSAndre Fischer 4878590a0fdSAndre Fischer // some general response handling and error handling 4888590a0fdSAndre Fischer { 4898590a0fdSAndre Fischer if ( !inSerfResponseBucket ) 4908590a0fdSAndre Fischer { 4918590a0fdSAndre Fischer /* A NULL response can come back if the request failed completely */ 4928590a0fdSAndre Fischer mbProcessingDone = true; 4938590a0fdSAndre Fischer return APR_EGENERAL; 4948590a0fdSAndre Fischer } 4958590a0fdSAndre Fischer 4968590a0fdSAndre Fischer serf_status_line sl; 4978590a0fdSAndre Fischer apr_status_t status = serf_bucket_response_status( inSerfResponseBucket, &sl ); 4988590a0fdSAndre Fischer if ( status ) 4998590a0fdSAndre Fischer { 5008590a0fdSAndre Fischer mbProcessingDone = false; // allow another try in order to get a response 5018590a0fdSAndre Fischer return status; 5028590a0fdSAndre Fischer } 5038590a0fdSAndre Fischer // TODO - check, if response status code handling is correct 5048590a0fdSAndre Fischer mnHTTPStatusCode = ( sl.version != 0 && sl.code >= 0 ) 5058590a0fdSAndre Fischer ? static_cast< sal_uInt16 >( sl.code ) 5068590a0fdSAndre Fischer : SC_NONE; 5078590a0fdSAndre Fischer if ( sl.reason ) 5088590a0fdSAndre Fischer { 5098590a0fdSAndre Fischer mHTTPStatusCodeText = ::rtl::OUString::createFromAscii( sl.reason ); 5108590a0fdSAndre Fischer } 5118590a0fdSAndre Fischer if ( ( sl.version == 0 || sl.code < 0 ) || 5128590a0fdSAndre Fischer mnHTTPStatusCode >= 300 ) 5138590a0fdSAndre Fischer { 5148590a0fdSAndre Fischer if ( mnHTTPStatusCode == 301 || 5158590a0fdSAndre Fischer mnHTTPStatusCode == 302 || 5168590a0fdSAndre Fischer mnHTTPStatusCode == 303 || 5178590a0fdSAndre Fischer mnHTTPStatusCode == 307 ) 5188590a0fdSAndre Fischer { 5198590a0fdSAndre Fischer // new location for certain redirections 5208590a0fdSAndre Fischer serf_bucket_t *headers = serf_bucket_response_get_headers( inSerfResponseBucket ); 5218590a0fdSAndre Fischer const char* location = serf_bucket_headers_get( headers, "Location" ); 5228590a0fdSAndre Fischer if ( location ) 5238590a0fdSAndre Fischer { 5248590a0fdSAndre Fischer mRedirectLocation = rtl::OUString::createFromAscii( location ); 5258590a0fdSAndre Fischer } 5268590a0fdSAndre Fischer mbProcessingDone = true; 5278590a0fdSAndre Fischer return APR_EGENERAL; 5288590a0fdSAndre Fischer } 5298590a0fdSAndre Fischer else if ( mrSerfSession.isHeadRequestInProgress() && 5308590a0fdSAndre Fischer ( mnHTTPStatusCode == 401 || mnHTTPStatusCode == 407 ) ) 5318590a0fdSAndre Fischer { 5328590a0fdSAndre Fischer // keep going as authentication is not required on HEAD request. 5338590a0fdSAndre Fischer // the response already contains header fields. 5348590a0fdSAndre Fischer } 5358590a0fdSAndre Fischer else 5368590a0fdSAndre Fischer { 5378590a0fdSAndre Fischer mbProcessingDone = true; 5388590a0fdSAndre Fischer return APR_EGENERAL; 5398590a0fdSAndre Fischer } 5408590a0fdSAndre Fischer } 5418590a0fdSAndre Fischer } 5428590a0fdSAndre Fischer 5438590a0fdSAndre Fischer // request specific processing of the response bucket 5448590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 5458590a0fdSAndre Fischer mbProcessingDone = mpProcImpl->processSerfResponseBucket( inSerfRequest, 5468590a0fdSAndre Fischer inSerfResponseBucket, 5478590a0fdSAndre Fischer inAprPool, 5488590a0fdSAndre Fischer status ); 5498590a0fdSAndre Fischer 5508590a0fdSAndre Fischer return status; 5518590a0fdSAndre Fischer } 5528590a0fdSAndre Fischer 5538590a0fdSAndre Fischer } // namespace http_dav_ucp 5548590a0fdSAndre Fischer 555