xref: /AOO41X/main/ucb/source/ucp/webdav/SerfRequestProcessor.cxx (revision fb7f54d274e818c0fa3cfcf886ef07ebf066acca)
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