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