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
25c1c10f68SAriel Constenla-Haile #include "SerfRequestProcessor.hxx"
26c1c10f68SAriel Constenla-Haile #include "SerfRequestProcessorImpl.hxx"
27c1c10f68SAriel Constenla-Haile #include "SerfRequestProcessorImplFac.hxx"
28c1c10f68SAriel Constenla-Haile #include "SerfCallbacks.hxx"
29c1c10f68SAriel Constenla-Haile #include "SerfSession.hxx"
308590a0fdSAndre Fischer
318590a0fdSAndre Fischer #include <apr_strings.h>
328590a0fdSAndre Fischer
33*3edf6992SAndrea Pescetti //to examine returned http code
34*3edf6992SAndrea Pescetti #include "DAVException.hxx"
35*3edf6992SAndrea Pescetti
368590a0fdSAndre Fischer namespace http_dav_ucp
378590a0fdSAndre Fischer {
388590a0fdSAndre Fischer
SerfRequestProcessor(SerfSession & rSerfSession,const rtl::OUString & inPath,const bool bUseChunkedEncoding)398590a0fdSAndre Fischer SerfRequestProcessor::SerfRequestProcessor( SerfSession& rSerfSession,
4049989859SOliver-Rainer Wittmann const rtl::OUString & inPath,
4149989859SOliver-Rainer Wittmann const bool bUseChunkedEncoding )
428590a0fdSAndre Fischer : mrSerfSession( rSerfSession )
438590a0fdSAndre Fischer , mPathStr( 0 )
4449989859SOliver-Rainer Wittmann , mbUseChunkedEncoding( bUseChunkedEncoding )
458590a0fdSAndre Fischer , mDestPathStr( 0 )
4649989859SOliver-Rainer Wittmann , mContentType( 0 )
4749989859SOliver-Rainer Wittmann , mReferer( 0 )
488590a0fdSAndre Fischer , mpProcImpl( 0 )
498590a0fdSAndre Fischer , mbProcessingDone( false )
508590a0fdSAndre Fischer , mpDAVException()
518590a0fdSAndre Fischer , mnHTTPStatusCode( SC_NONE )
528590a0fdSAndre Fischer , mHTTPStatusCodeText()
538590a0fdSAndre Fischer , mRedirectLocation()
54fb7f54d2SOliver-Rainer Wittmann , mnSuccessfulCredentialAttempts( 0 )
55fb7f54d2SOliver-Rainer Wittmann , mbInputOfCredentialsAborted( false )
568590a0fdSAndre Fischer , mbSetupSerfRequestCalled( false )
578590a0fdSAndre Fischer , mbAcceptSerfResponseCalled( false )
588590a0fdSAndre Fischer , mbHandleSerfResponseCalled( false )
598590a0fdSAndre Fischer {
608590a0fdSAndre Fischer mPathStr = apr_pstrdup( mrSerfSession.getAprPool(),
6124c56ab9SHerbert Dürr rtl::OUStringToOString( inPath, RTL_TEXTENCODING_UTF8 ).getStr() );
628590a0fdSAndre Fischer }
638590a0fdSAndre Fischer
~SerfRequestProcessor()648590a0fdSAndre Fischer SerfRequestProcessor::~SerfRequestProcessor()
658590a0fdSAndre Fischer {
668590a0fdSAndre Fischer delete mpProcImpl;
678590a0fdSAndre Fischer delete mpDAVException;
688590a0fdSAndre Fischer }
698590a0fdSAndre Fischer
prepareProcessor()708590a0fdSAndre Fischer void SerfRequestProcessor::prepareProcessor()
718590a0fdSAndre Fischer {
728590a0fdSAndre Fischer delete mpDAVException;
738590a0fdSAndre Fischer mpDAVException = 0;
748590a0fdSAndre Fischer mnHTTPStatusCode = SC_NONE;
758590a0fdSAndre Fischer mHTTPStatusCodeText = rtl::OUString();
768590a0fdSAndre Fischer mRedirectLocation = rtl::OUString();
778590a0fdSAndre Fischer
78fb7f54d2SOliver-Rainer Wittmann mnSuccessfulCredentialAttempts = 0;
79fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted = false;
808590a0fdSAndre Fischer mbSetupSerfRequestCalled = false;
818590a0fdSAndre Fischer mbAcceptSerfResponseCalled = false;
828590a0fdSAndre Fischer mbHandleSerfResponseCalled = false;
838590a0fdSAndre Fischer }
848590a0fdSAndre Fischer
858590a0fdSAndre Fischer // PROPFIND - allprop & named
processPropFind(const Depth inDepth,const std::vector<::rtl::OUString> & inPropNames,std::vector<DAVResource> & ioResources,apr_status_t & outSerfStatus)868590a0fdSAndre Fischer bool SerfRequestProcessor::processPropFind( const Depth inDepth,
878590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inPropNames,
888590a0fdSAndre Fischer std::vector< DAVResource > & ioResources,
898590a0fdSAndre Fischer apr_status_t& outSerfStatus )
908590a0fdSAndre Fischer {
918590a0fdSAndre Fischer mpProcImpl = createPropFindReqProcImpl( mPathStr,
92e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
938590a0fdSAndre Fischer inDepth,
948590a0fdSAndre Fischer inPropNames,
958590a0fdSAndre Fischer ioResources );
968590a0fdSAndre Fischer outSerfStatus = runProcessor();
978590a0fdSAndre Fischer
988590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
998590a0fdSAndre Fischer }
1008590a0fdSAndre Fischer
1018590a0fdSAndre Fischer // PROPFIND - property names
processPropFind(const Depth inDepth,std::vector<DAVResourceInfo> & ioResInfo,apr_status_t & outSerfStatus)1028590a0fdSAndre Fischer bool SerfRequestProcessor::processPropFind( const Depth inDepth,
1038590a0fdSAndre Fischer std::vector< DAVResourceInfo > & ioResInfo,
1048590a0fdSAndre Fischer apr_status_t& outSerfStatus )
1058590a0fdSAndre Fischer {
1068590a0fdSAndre Fischer mpProcImpl = createPropFindReqProcImpl( mPathStr,
107e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
1088590a0fdSAndre Fischer inDepth,
1098590a0fdSAndre Fischer ioResInfo );
1108590a0fdSAndre Fischer outSerfStatus = runProcessor();
1118590a0fdSAndre Fischer
1128590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
1138590a0fdSAndre Fischer }
1148590a0fdSAndre Fischer
1158590a0fdSAndre Fischer // PROPPATCH
processPropPatch(const std::vector<ProppatchValue> & inProperties,const com::sun::star::ucb::Lock inLock,apr_status_t & outSerfStatus)1168590a0fdSAndre Fischer bool SerfRequestProcessor::processPropPatch( const std::vector< ProppatchValue > & inProperties,
117*3edf6992SAndrea Pescetti const com::sun::star::ucb::Lock inLock,
1188590a0fdSAndre Fischer apr_status_t& outSerfStatus )
1198590a0fdSAndre Fischer {
120*3edf6992SAndrea Pescetti char * inLockToken = static_cast<char*>(0);
121*3edf6992SAndrea Pescetti if(inLock.LockTokens.getLength() > 0)
122*3edf6992SAndrea Pescetti {
123*3edf6992SAndrea Pescetti inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)",
124*3edf6992SAndrea Pescetti rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() );
125*3edf6992SAndrea Pescetti }
1268590a0fdSAndre Fischer mpProcImpl = createPropPatchReqProcImpl( mPathStr,
127e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
128*3edf6992SAndrea Pescetti inProperties,
129*3edf6992SAndrea Pescetti inLockToken );
1308590a0fdSAndre Fischer outSerfStatus = runProcessor();
1318590a0fdSAndre Fischer
1328590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
1338590a0fdSAndre Fischer }
1348590a0fdSAndre Fischer
1358590a0fdSAndre Fischer // GET
processGet(const com::sun::star::uno::Reference<SerfInputStream> & xioInStrm,apr_status_t & outSerfStatus)1368590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm,
1378590a0fdSAndre Fischer apr_status_t& outSerfStatus )
1388590a0fdSAndre Fischer {
1398590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr,
140e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
1418590a0fdSAndre Fischer xioInStrm );
1428590a0fdSAndre Fischer outSerfStatus = runProcessor();
1438590a0fdSAndre Fischer
1448590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
1458590a0fdSAndre Fischer }
1468590a0fdSAndre Fischer
1478590a0fdSAndre Fischer // GET inclusive header fields
processGet(const com::sun::star::uno::Reference<SerfInputStream> & xioInStrm,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource,apr_status_t & outSerfStatus)1488590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm,
1498590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames,
1508590a0fdSAndre Fischer DAVResource & ioResource,
1518590a0fdSAndre Fischer apr_status_t& outSerfStatus )
1528590a0fdSAndre Fischer {
1538590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr,
154e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
1558590a0fdSAndre Fischer xioInStrm,
1568590a0fdSAndre Fischer inHeaderNames,
1578590a0fdSAndre Fischer ioResource );
1588590a0fdSAndre Fischer outSerfStatus = runProcessor();
1598590a0fdSAndre Fischer
1608590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
1618590a0fdSAndre Fischer }
1628590a0fdSAndre Fischer
1638590a0fdSAndre Fischer // GET
processGet(const com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> & xioOutStrm,apr_status_t & outSerfStatus)1648590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm,
1658590a0fdSAndre Fischer apr_status_t& outSerfStatus )
1668590a0fdSAndre Fischer {
1678590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr,
168e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
1698590a0fdSAndre Fischer xioOutStrm );
1708590a0fdSAndre Fischer outSerfStatus = runProcessor();
1718590a0fdSAndre Fischer
1728590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
1738590a0fdSAndre Fischer }
1748590a0fdSAndre Fischer
1758590a0fdSAndre Fischer // GET inclusive header fields
processGet(const com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> & xioOutStrm,const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource,apr_status_t & outSerfStatus)1768590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm,
1778590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames,
1788590a0fdSAndre Fischer DAVResource & ioResource,
1798590a0fdSAndre Fischer apr_status_t& outSerfStatus )
1808590a0fdSAndre Fischer {
1818590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr,
182e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
1838590a0fdSAndre Fischer xioOutStrm,
1848590a0fdSAndre Fischer inHeaderNames,
1858590a0fdSAndre Fischer ioResource );
1868590a0fdSAndre Fischer outSerfStatus = runProcessor();
1878590a0fdSAndre Fischer
1888590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
1898590a0fdSAndre Fischer }
1908590a0fdSAndre Fischer
1918590a0fdSAndre Fischer // HEAD
processHead(const std::vector<::rtl::OUString> & inHeaderNames,DAVResource & ioResource,apr_status_t & outSerfStatus)1928590a0fdSAndre Fischer bool SerfRequestProcessor::processHead( const std::vector< ::rtl::OUString > & inHeaderNames,
1938590a0fdSAndre Fischer DAVResource & ioResource,
1948590a0fdSAndre Fischer apr_status_t& outSerfStatus )
1958590a0fdSAndre Fischer {
1968590a0fdSAndre Fischer mpProcImpl = createHeadReqProcImpl( mPathStr,
197e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
1988590a0fdSAndre Fischer inHeaderNames,
1998590a0fdSAndre Fischer ioResource );
2008590a0fdSAndre Fischer outSerfStatus = runProcessor();
2018590a0fdSAndre Fischer
2028590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
2038590a0fdSAndre Fischer }
2048590a0fdSAndre Fischer
2058590a0fdSAndre Fischer // PUT
processPut(const char * inData,apr_size_t inDataLen,const com::sun::star::ucb::Lock inLock,apr_status_t & outSerfStatus)2068590a0fdSAndre Fischer bool SerfRequestProcessor::processPut( const char* inData,
2078590a0fdSAndre Fischer apr_size_t inDataLen,
208*3edf6992SAndrea Pescetti const com::sun::star::ucb::Lock inLock,
2098590a0fdSAndre Fischer apr_status_t& outSerfStatus )
2108590a0fdSAndre Fischer {
211*3edf6992SAndrea Pescetti char * inLockToken = static_cast<char*>(0);
212*3edf6992SAndrea Pescetti if(inLock.LockTokens.getLength() > 0)
213*3edf6992SAndrea Pescetti {
214*3edf6992SAndrea Pescetti inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)",
215*3edf6992SAndrea Pescetti rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() );
216*3edf6992SAndrea Pescetti }
2178590a0fdSAndre Fischer mpProcImpl = createPutReqProcImpl( mPathStr,
218e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
2198590a0fdSAndre Fischer inData,
220*3edf6992SAndrea Pescetti inLockToken,
2218590a0fdSAndre Fischer inDataLen );
2228590a0fdSAndre Fischer outSerfStatus = runProcessor();
2238590a0fdSAndre Fischer
2248590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
2258590a0fdSAndre Fischer }
2268590a0fdSAndre Fischer
2278590a0fdSAndre Fischer // POST
processPost(const char * inData,apr_size_t inDataLen,const rtl::OUString & inContentType,const rtl::OUString & inReferer,const com::sun::star::ucb::Lock inLock,const com::sun::star::uno::Reference<SerfInputStream> & xioInStrm,apr_status_t & outSerfStatus)2288590a0fdSAndre Fischer bool SerfRequestProcessor::processPost( const char* inData,
2298590a0fdSAndre Fischer apr_size_t inDataLen,
2308590a0fdSAndre Fischer const rtl::OUString & inContentType,
2318590a0fdSAndre Fischer const rtl::OUString & inReferer,
232*3edf6992SAndrea Pescetti const com::sun::star::ucb::Lock inLock,
2338590a0fdSAndre Fischer const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm,
2348590a0fdSAndre Fischer apr_status_t& outSerfStatus )
2358590a0fdSAndre Fischer {
2368590a0fdSAndre Fischer mContentType = apr_pstrdup( mrSerfSession.getAprPool(),
23724c56ab9SHerbert Dürr rtl::OUStringToOString( inContentType, RTL_TEXTENCODING_UTF8 ).getStr() );
2388590a0fdSAndre Fischer mReferer = apr_pstrdup( mrSerfSession.getAprPool(),
23924c56ab9SHerbert Dürr rtl::OUStringToOString( inReferer, RTL_TEXTENCODING_UTF8 ).getStr() );
240*3edf6992SAndrea Pescetti char * inLockToken = static_cast<char*>(0);
241*3edf6992SAndrea Pescetti if(inLock.LockTokens.getLength() > 0)
242*3edf6992SAndrea Pescetti {
243*3edf6992SAndrea Pescetti inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)",
244*3edf6992SAndrea Pescetti rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() );
245*3edf6992SAndrea Pescetti }
2468590a0fdSAndre Fischer mpProcImpl = createPostReqProcImpl( mPathStr,
247e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
2488590a0fdSAndre Fischer inData,
2498590a0fdSAndre Fischer inDataLen,
250*3edf6992SAndrea Pescetti inLockToken,
2518590a0fdSAndre Fischer mContentType,
2528590a0fdSAndre Fischer mReferer,
2538590a0fdSAndre Fischer xioInStrm );
2548590a0fdSAndre Fischer outSerfStatus = runProcessor();
2558590a0fdSAndre Fischer
2568590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
2578590a0fdSAndre Fischer }
2588590a0fdSAndre Fischer
2598590a0fdSAndre Fischer // POST
processPost(const char * inData,apr_size_t inDataLen,const rtl::OUString & inContentType,const rtl::OUString & inReferer,const com::sun::star::ucb::Lock inLock,const com::sun::star::uno::Reference<com::sun::star::io::XOutputStream> & xioOutStrm,apr_status_t & outSerfStatus)2608590a0fdSAndre Fischer bool SerfRequestProcessor::processPost( const char* inData,
2618590a0fdSAndre Fischer apr_size_t inDataLen,
2628590a0fdSAndre Fischer const rtl::OUString & inContentType,
2638590a0fdSAndre Fischer const rtl::OUString & inReferer,
264*3edf6992SAndrea Pescetti const com::sun::star::ucb::Lock inLock,
2658590a0fdSAndre Fischer const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm,
2668590a0fdSAndre Fischer apr_status_t& outSerfStatus )
2678590a0fdSAndre Fischer {
2688590a0fdSAndre Fischer mContentType = apr_pstrdup( mrSerfSession.getAprPool(),
26924c56ab9SHerbert Dürr rtl::OUStringToOString( inContentType, RTL_TEXTENCODING_UTF8 ).getStr() );
2708590a0fdSAndre Fischer mReferer = apr_pstrdup( mrSerfSession.getAprPool(),
27124c56ab9SHerbert Dürr rtl::OUStringToOString( inReferer, RTL_TEXTENCODING_UTF8 ).getStr() );
272*3edf6992SAndrea Pescetti char * inLockToken = static_cast<char*>(0);
273*3edf6992SAndrea Pescetti if(inLock.LockTokens.getLength() > 0)
274*3edf6992SAndrea Pescetti {
275*3edf6992SAndrea Pescetti inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)",
276*3edf6992SAndrea Pescetti rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() );
277*3edf6992SAndrea Pescetti }
2788590a0fdSAndre Fischer mpProcImpl = createPostReqProcImpl( mPathStr,
279e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
2808590a0fdSAndre Fischer inData,
2818590a0fdSAndre Fischer inDataLen,
282*3edf6992SAndrea Pescetti inLockToken,
2838590a0fdSAndre Fischer mContentType,
2848590a0fdSAndre Fischer mReferer,
2858590a0fdSAndre Fischer xioOutStrm );
2868590a0fdSAndre Fischer outSerfStatus = runProcessor();
2878590a0fdSAndre Fischer
2888590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
2898590a0fdSAndre Fischer }
2908590a0fdSAndre Fischer
2918590a0fdSAndre Fischer // DELETE
processDelete(const com::sun::star::ucb::Lock inLock,apr_status_t & outSerfStatus)292*3edf6992SAndrea Pescetti bool SerfRequestProcessor::processDelete( const com::sun::star::ucb::Lock inLock,
293*3edf6992SAndrea Pescetti apr_status_t& outSerfStatus )
2948590a0fdSAndre Fischer {
295*3edf6992SAndrea Pescetti char * inLockToken = static_cast<char*>(0);
296*3edf6992SAndrea Pescetti if(inLock.LockTokens.getLength() > 0)
297*3edf6992SAndrea Pescetti {
298*3edf6992SAndrea Pescetti inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)",
299*3edf6992SAndrea Pescetti rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() );
300*3edf6992SAndrea Pescetti }
301e9ff7e89SOliver-Rainer Wittmann mpProcImpl = createDeleteReqProcImpl( mPathStr,
302*3edf6992SAndrea Pescetti mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
303*3edf6992SAndrea Pescetti inLockToken );
3048590a0fdSAndre Fischer outSerfStatus = runProcessor();
3058590a0fdSAndre Fischer
3068590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
3078590a0fdSAndre Fischer }
3088590a0fdSAndre Fischer
3098590a0fdSAndre Fischer // MKCOL
processMkCol(const com::sun::star::ucb::Lock inLock,apr_status_t & outSerfStatus)310*3edf6992SAndrea Pescetti bool SerfRequestProcessor::processMkCol( const com::sun::star::ucb::Lock inLock,
311*3edf6992SAndrea Pescetti apr_status_t& outSerfStatus )
3128590a0fdSAndre Fischer {
313*3edf6992SAndrea Pescetti char * inLockToken = static_cast<char*>(0);
314*3edf6992SAndrea Pescetti if(inLock.LockTokens.getLength() > 0)
315*3edf6992SAndrea Pescetti {
316*3edf6992SAndrea Pescetti inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)",
317*3edf6992SAndrea Pescetti rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() );
318*3edf6992SAndrea Pescetti }
319e9ff7e89SOliver-Rainer Wittmann mpProcImpl = createMkColReqProcImpl( mPathStr,
320*3edf6992SAndrea Pescetti mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
321*3edf6992SAndrea Pescetti inLockToken );
3228590a0fdSAndre Fischer outSerfStatus = runProcessor();
3238590a0fdSAndre Fischer
3248590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
3258590a0fdSAndre Fischer }
3268590a0fdSAndre Fischer
3278590a0fdSAndre Fischer // COPY
processCopy(const rtl::OUString & inDestinationPath,const bool inOverwrite,const com::sun::star::ucb::Lock inLock,apr_status_t & outSerfStatus)3288590a0fdSAndre Fischer bool SerfRequestProcessor::processCopy( const rtl::OUString & inDestinationPath,
3298590a0fdSAndre Fischer const bool inOverwrite,
330*3edf6992SAndrea Pescetti const com::sun::star::ucb::Lock inLock,
3318590a0fdSAndre Fischer apr_status_t& outSerfStatus )
3328590a0fdSAndre Fischer {
3338590a0fdSAndre Fischer mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(),
33424c56ab9SHerbert Dürr rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ).getStr() );
335*3edf6992SAndrea Pescetti char * inLockToken = static_cast<char*>(0);
336*3edf6992SAndrea Pescetti if(inLock.LockTokens.getLength() > 0)
337*3edf6992SAndrea Pescetti {
338*3edf6992SAndrea Pescetti inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)",
339*3edf6992SAndrea Pescetti rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() );
340*3edf6992SAndrea Pescetti }
3418590a0fdSAndre Fischer mpProcImpl = createCopyReqProcImpl( mPathStr,
342e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
3438590a0fdSAndre Fischer mDestPathStr,
344*3edf6992SAndrea Pescetti inOverwrite,
345*3edf6992SAndrea Pescetti inLockToken );
3468590a0fdSAndre Fischer outSerfStatus = runProcessor();
3478590a0fdSAndre Fischer
3488590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
3498590a0fdSAndre Fischer }
3508590a0fdSAndre Fischer
3518590a0fdSAndre Fischer // MOVE
processMove(const rtl::OUString & inDestinationPath,const bool inOverwrite,const com::sun::star::ucb::Lock inLock,apr_status_t & outSerfStatus)3528590a0fdSAndre Fischer bool SerfRequestProcessor::processMove( const rtl::OUString & inDestinationPath,
3538590a0fdSAndre Fischer const bool inOverwrite,
354*3edf6992SAndrea Pescetti const com::sun::star::ucb::Lock inLock,
3558590a0fdSAndre Fischer apr_status_t& outSerfStatus )
3568590a0fdSAndre Fischer {
3578590a0fdSAndre Fischer mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(),
35824c56ab9SHerbert Dürr rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ).getStr() );
359*3edf6992SAndrea Pescetti char * inLockToken = static_cast<char*>(0);
360*3edf6992SAndrea Pescetti if(inLock.LockTokens.getLength() > 0)
361*3edf6992SAndrea Pescetti {
362*3edf6992SAndrea Pescetti inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)",
363*3edf6992SAndrea Pescetti rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() );
364*3edf6992SAndrea Pescetti }
3658590a0fdSAndre Fischer mpProcImpl = createMoveReqProcImpl( mPathStr,
366e9ff7e89SOliver-Rainer Wittmann mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
3678590a0fdSAndre Fischer mDestPathStr,
368*3edf6992SAndrea Pescetti inOverwrite,
369*3edf6992SAndrea Pescetti inLockToken );
370*3edf6992SAndrea Pescetti outSerfStatus = runProcessor();
371*3edf6992SAndrea Pescetti
372*3edf6992SAndrea Pescetti return outSerfStatus == APR_SUCCESS;
373*3edf6992SAndrea Pescetti }
374*3edf6992SAndrea Pescetti
375*3edf6992SAndrea Pescetti //LOCK creating a new lock
processLock(const rtl::OUString & inDestinationPath,const com::sun::star::ucb::Lock & inLock,DAVPropertyValue & outLock,apr_status_t & outSerfStatus)376*3edf6992SAndrea Pescetti bool SerfRequestProcessor::processLock( const rtl::OUString & inDestinationPath,
377*3edf6992SAndrea Pescetti const com::sun::star::ucb::Lock& inLock,
378*3edf6992SAndrea Pescetti DAVPropertyValue & outLock,
379*3edf6992SAndrea Pescetti apr_status_t& outSerfStatus )
380*3edf6992SAndrea Pescetti {
381*3edf6992SAndrea Pescetti mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(),
382*3edf6992SAndrea Pescetti rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ).getStr() );
383*3edf6992SAndrea Pescetti char * Timeout;
384*3edf6992SAndrea Pescetti if(inLock.Timeout == -1)
385*3edf6992SAndrea Pescetti Timeout = apr_psprintf( mrSerfSession.getAprPool(), "Infinite" );
386*3edf6992SAndrea Pescetti else
387*3edf6992SAndrea Pescetti Timeout = apr_psprintf( mrSerfSession.getAprPool(), "Second-%ld", inLock.Timeout );
388*3edf6992SAndrea Pescetti
389*3edf6992SAndrea Pescetti mpProcImpl = createLockReqProcImpl( mPathStr,
390*3edf6992SAndrea Pescetti mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
391*3edf6992SAndrea Pescetti inLock,
392*3edf6992SAndrea Pescetti Timeout,
393*3edf6992SAndrea Pescetti outLock);
394*3edf6992SAndrea Pescetti outSerfStatus = runProcessor();
395*3edf6992SAndrea Pescetti
396*3edf6992SAndrea Pescetti return outSerfStatus == APR_SUCCESS;
397*3edf6992SAndrea Pescetti }
398*3edf6992SAndrea Pescetti
399*3edf6992SAndrea Pescetti //LOCK refresh an existing lock
processLockRefresh(const rtl::OUString & inDestinationPath,const com::sun::star::ucb::Lock & inLock,DAVPropertyValue & outLock,apr_status_t & outSerfStatus)400*3edf6992SAndrea Pescetti bool SerfRequestProcessor::processLockRefresh( const rtl::OUString & inDestinationPath,
401*3edf6992SAndrea Pescetti const com::sun::star::ucb::Lock& inLock,
402*3edf6992SAndrea Pescetti DAVPropertyValue & outLock,
403*3edf6992SAndrea Pescetti apr_status_t& outSerfStatus )
404*3edf6992SAndrea Pescetti {
405*3edf6992SAndrea Pescetti mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(),
406*3edf6992SAndrea Pescetti rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ).getStr() );
407*3edf6992SAndrea Pescetti char * Timeout;
408*3edf6992SAndrea Pescetti if(inLock.Timeout == -1)
409*3edf6992SAndrea Pescetti Timeout = apr_psprintf( mrSerfSession.getAprPool(), "Infinite" );
410*3edf6992SAndrea Pescetti else
411*3edf6992SAndrea Pescetti Timeout = apr_psprintf( mrSerfSession.getAprPool(), "Second-%ld", inLock.Timeout );
412*3edf6992SAndrea Pescetti
413*3edf6992SAndrea Pescetti char * inLockToken = apr_psprintf( mrSerfSession.getAprPool(), "(<%s>)",
414*3edf6992SAndrea Pescetti rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() );
415*3edf6992SAndrea Pescetti
416*3edf6992SAndrea Pescetti mpProcImpl = createLockRefreshProcImpl( mPathStr,
417*3edf6992SAndrea Pescetti mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
418*3edf6992SAndrea Pescetti inLock,
419*3edf6992SAndrea Pescetti inLockToken,
420*3edf6992SAndrea Pescetti Timeout,
421*3edf6992SAndrea Pescetti outLock);
422*3edf6992SAndrea Pescetti outSerfStatus = runProcessor();
423*3edf6992SAndrea Pescetti
424*3edf6992SAndrea Pescetti return outSerfStatus == APR_SUCCESS;
425*3edf6992SAndrea Pescetti }
426*3edf6992SAndrea Pescetti
427*3edf6992SAndrea Pescetti //ULOCK unlock an existing lock
processUnlock(const rtl::OUString & inDestinationPath,const com::sun::star::ucb::Lock & inLock,apr_status_t & outSerfStatus)428*3edf6992SAndrea Pescetti bool SerfRequestProcessor::processUnlock( const rtl::OUString & inDestinationPath,
429*3edf6992SAndrea Pescetti const com::sun::star::ucb::Lock& inLock,
430*3edf6992SAndrea Pescetti apr_status_t& outSerfStatus )
431*3edf6992SAndrea Pescetti {
432*3edf6992SAndrea Pescetti mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(),
433*3edf6992SAndrea Pescetti rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ).getStr() );
434*3edf6992SAndrea Pescetti
435*3edf6992SAndrea Pescetti char * aToken = apr_psprintf( mrSerfSession.getAprPool(), "<%s>",
436*3edf6992SAndrea Pescetti rtl::OUStringToOString(inLock.LockTokens[0], RTL_TEXTENCODING_UTF8 ).getStr() );
437*3edf6992SAndrea Pescetti
438*3edf6992SAndrea Pescetti mpProcImpl = createUnlockProcImpl( mPathStr,
439*3edf6992SAndrea Pescetti mrSerfSession.getRequestEnvironment().m_aRequestHeaders,
440*3edf6992SAndrea Pescetti inLock,
441*3edf6992SAndrea Pescetti aToken );
442*3edf6992SAndrea Pescetti
4438590a0fdSAndre Fischer outSerfStatus = runProcessor();
4448590a0fdSAndre Fischer
4458590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS;
4468590a0fdSAndre Fischer }
4478590a0fdSAndre Fischer
runProcessor()4488590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::runProcessor()
4498590a0fdSAndre Fischer {
4508590a0fdSAndre Fischer prepareProcessor();
4518590a0fdSAndre Fischer
45249989859SOliver-Rainer Wittmann // activate chunked encoding, if requested
45349989859SOliver-Rainer Wittmann if ( mbUseChunkedEncoding )
45449989859SOliver-Rainer Wittmann {
45549989859SOliver-Rainer Wittmann mpProcImpl->activateChunkedEncoding();
45649989859SOliver-Rainer Wittmann }
45749989859SOliver-Rainer Wittmann
4588590a0fdSAndre Fischer // create serf request
459*3edf6992SAndrea Pescetti OSL_ASSERT(mrSerfSession.getSerfConnection() != NULL);
4608590a0fdSAndre Fischer serf_connection_request_create( mrSerfSession.getSerfConnection(),
4618590a0fdSAndre Fischer Serf_SetupRequest,
4628590a0fdSAndre Fischer this );
4638590a0fdSAndre Fischer
4648590a0fdSAndre Fischer // perform serf request
4658590a0fdSAndre Fischer mbProcessingDone = false;
4668590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS;
4678590a0fdSAndre Fischer serf_context_t* pSerfContext = mrSerfSession.getSerfContext();
4688590a0fdSAndre Fischer apr_pool_t* pAprPool = mrSerfSession.getAprPool();
4698590a0fdSAndre Fischer while ( true )
4708590a0fdSAndre Fischer {
4718590a0fdSAndre Fischer status = serf_context_run( pSerfContext,
4728590a0fdSAndre Fischer SERF_DURATION_FOREVER,
4738590a0fdSAndre Fischer pAprPool );
4748590a0fdSAndre Fischer if ( APR_STATUS_IS_TIMEUP( status ) )
4758590a0fdSAndre Fischer {
4768590a0fdSAndre Fischer continue;
4778590a0fdSAndre Fischer }
4788590a0fdSAndre Fischer if ( status != APR_SUCCESS )
4798590a0fdSAndre Fischer {
480*3edf6992SAndrea Pescetti #if OSL_DEBUG_LEVEL > 0
481*3edf6992SAndrea Pescetti char buff[512];
482*3edf6992SAndrea Pescetti OSL_TRACE("SerfRequestProcessor::runProcessor, status != APR_SUCCESS: %d (%s)",status, apr_strerror(status, buff, 512));
483*3edf6992SAndrea Pescetti #endif
4848590a0fdSAndre Fischer break;
4858590a0fdSAndre Fischer }
4868590a0fdSAndre Fischer if ( mbProcessingDone )
4878590a0fdSAndre Fischer {
4888590a0fdSAndre Fischer break;
4898590a0fdSAndre Fischer }
4908590a0fdSAndre Fischer }
4918590a0fdSAndre Fischer
4928590a0fdSAndre Fischer postprocessProcessor( status );
4938590a0fdSAndre Fischer
4948590a0fdSAndre Fischer return status;
4958590a0fdSAndre Fischer }
4968590a0fdSAndre Fischer
postprocessProcessor(const apr_status_t inStatus)4978590a0fdSAndre Fischer void SerfRequestProcessor::postprocessProcessor( const apr_status_t inStatus )
4988590a0fdSAndre Fischer {
4998590a0fdSAndre Fischer if ( inStatus == APR_SUCCESS )
5008590a0fdSAndre Fischer {
5018590a0fdSAndre Fischer return;
5028590a0fdSAndre Fischer }
5038590a0fdSAndre Fischer
504*3edf6992SAndrea Pescetti OSL_TRACE("SerfRequestProcessor::postprocessProcessor:%d",__LINE__);
5058590a0fdSAndre Fischer switch ( inStatus )
5068590a0fdSAndre Fischer {
5078590a0fdSAndre Fischer case APR_EGENERAL:
508fb7f54d2SOliver-Rainer Wittmann case SERF_ERROR_AUTHN_FAILED:
5098590a0fdSAndre Fischer // general error; <mnHTTPStatusCode> provides more information
5108590a0fdSAndre Fischer {
5118590a0fdSAndre Fischer switch ( mnHTTPStatusCode )
5128590a0fdSAndre Fischer {
5138590a0fdSAndre Fischer case SC_NONE:
5148590a0fdSAndre Fischer if ( !mbSetupSerfRequestCalled )
5158590a0fdSAndre Fischer {
5168590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_LOOKUP,
5178590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( mrSerfSession.getHostName(),
5188590a0fdSAndre Fischer mrSerfSession.getPort() ) );
5198590a0fdSAndre Fischer }
520fb7f54d2SOliver-Rainer Wittmann else if ( mbInputOfCredentialsAborted )
521fb7f54d2SOliver-Rainer Wittmann {
522fb7f54d2SOliver-Rainer Wittmann mpDAVException = new DAVException( DAVException::DAV_HTTP_NOAUTH,
523fb7f54d2SOliver-Rainer Wittmann SerfUri::makeConnectionEndPointString( mrSerfSession.getHostName(),
524fb7f54d2SOliver-Rainer Wittmann mrSerfSession.getPort() ) );
525fb7f54d2SOliver-Rainer Wittmann }
5268590a0fdSAndre Fischer else
5278590a0fdSAndre Fischer {
5288590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR,
5298590a0fdSAndre Fischer mHTTPStatusCodeText,
5308590a0fdSAndre Fischer mnHTTPStatusCode );
5318590a0fdSAndre Fischer }
5328590a0fdSAndre Fischer break;
5338590a0fdSAndre Fischer case SC_MOVED_PERMANENTLY:
5348590a0fdSAndre Fischer case SC_MOVED_TEMPORARILY:
5358590a0fdSAndre Fischer case SC_SEE_OTHER:
5368590a0fdSAndre Fischer case SC_TEMPORARY_REDIRECT:
5378590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_REDIRECT,
5388590a0fdSAndre Fischer mRedirectLocation );
5398590a0fdSAndre Fischer break;
540*3edf6992SAndrea Pescetti case SC_LOCKED:
541*3edf6992SAndrea Pescetti mpDAVException = new DAVException( DAVException::DAV_LOCKED,
542*3edf6992SAndrea Pescetti mHTTPStatusCodeText,
543*3edf6992SAndrea Pescetti mnHTTPStatusCode );
544*3edf6992SAndrea Pescetti break;
5458590a0fdSAndre Fischer default:
5468590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR,
5478590a0fdSAndre Fischer mHTTPStatusCodeText,
5488590a0fdSAndre Fischer mnHTTPStatusCode );
5498590a0fdSAndre Fischer break;
5508590a0fdSAndre Fischer }
5518590a0fdSAndre Fischer }
5528590a0fdSAndre Fischer break;
5538590a0fdSAndre Fischer
5548590a0fdSAndre Fischer default:
5558590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR );
5568590a0fdSAndre Fischer break;
5578590a0fdSAndre Fischer }
5588590a0fdSAndre Fischer }
5598590a0fdSAndre Fischer
provideSerfCredentials(char ** outUsername,char ** outPassword,serf_request_t * inRequest,int inCode,const char * inAuthProtocol,const char * inRealm,apr_pool_t * inAprPool)5608590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::provideSerfCredentials( char ** outUsername,
5618590a0fdSAndre Fischer char ** outPassword,
5628590a0fdSAndre Fischer serf_request_t * inRequest,
5638590a0fdSAndre Fischer int inCode,
5648590a0fdSAndre Fischer const char *inAuthProtocol,
5658590a0fdSAndre Fischer const char *inRealm,
5668590a0fdSAndre Fischer apr_pool_t *inAprPool )
5678590a0fdSAndre Fischer {
568fb7f54d2SOliver-Rainer Wittmann // as each successful provided credentials are tried twice - see below - the
569fb7f54d2SOliver-Rainer Wittmann // number of real attempts is half of the value of <mnSuccessfulCredentialAttempts>
570fb7f54d2SOliver-Rainer Wittmann if ( (mnSuccessfulCredentialAttempts / 2) >= 5 ||
571fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted )
572fb7f54d2SOliver-Rainer Wittmann {
573fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted = true;
574fb7f54d2SOliver-Rainer Wittmann return SERF_ERROR_AUTHN_FAILED;
575fb7f54d2SOliver-Rainer Wittmann }
576fb7f54d2SOliver-Rainer Wittmann
577fb7f54d2SOliver-Rainer Wittmann // because serf keeps credentials only for a connection in case of digest authentication
578fb7f54d2SOliver-Rainer Wittmann // we give each successful provided credentials a second try in order to workaround the
579fb7f54d2SOliver-Rainer Wittmann // situation that the connection for which the credentials have been provided has been closed
580fb7f54d2SOliver-Rainer Wittmann // before the provided credentials could be applied for the request.
581fb7f54d2SOliver-Rainer Wittmann apr_status_t status = mrSerfSession.provideSerfCredentials( (mnSuccessfulCredentialAttempts % 2) == 1,
582fb7f54d2SOliver-Rainer Wittmann outUsername,
5838590a0fdSAndre Fischer outPassword,
5848590a0fdSAndre Fischer inRequest,
5858590a0fdSAndre Fischer inCode,
5868590a0fdSAndre Fischer inAuthProtocol,
5878590a0fdSAndre Fischer inRealm,
5888590a0fdSAndre Fischer inAprPool );
589fb7f54d2SOliver-Rainer Wittmann if ( status != APR_SUCCESS )
590fb7f54d2SOliver-Rainer Wittmann {
591fb7f54d2SOliver-Rainer Wittmann mbInputOfCredentialsAborted = true;
592fb7f54d2SOliver-Rainer Wittmann }
593fb7f54d2SOliver-Rainer Wittmann else
594fb7f54d2SOliver-Rainer Wittmann {
595fb7f54d2SOliver-Rainer Wittmann ++mnSuccessfulCredentialAttempts;
596fb7f54d2SOliver-Rainer Wittmann }
597fb7f54d2SOliver-Rainer Wittmann
598fb7f54d2SOliver-Rainer Wittmann return status;
5998590a0fdSAndre Fischer }
6008590a0fdSAndre Fischer
setupSerfRequest(serf_request_t * inSerfRequest,serf_bucket_t ** outSerfRequestBucket,serf_response_acceptor_t * outSerfResponseAcceptor,void ** outSerfResponseAcceptorBaton,serf_response_handler_t * outSerfResponseHandler,void ** outSerfResponseHandlerBaton,apr_pool_t *)6018590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::setupSerfRequest( serf_request_t * inSerfRequest,
6028590a0fdSAndre Fischer serf_bucket_t ** outSerfRequestBucket,
6038590a0fdSAndre Fischer serf_response_acceptor_t * outSerfResponseAcceptor,
6048590a0fdSAndre Fischer void ** outSerfResponseAcceptorBaton,
6058590a0fdSAndre Fischer serf_response_handler_t * outSerfResponseHandler,
6068590a0fdSAndre Fischer void ** outSerfResponseHandlerBaton,
6078590a0fdSAndre Fischer apr_pool_t * /*inAprPool*/ )
6088590a0fdSAndre Fischer {
6098590a0fdSAndre Fischer mbSetupSerfRequestCalled = true;
6108590a0fdSAndre Fischer *outSerfRequestBucket = mpProcImpl->createSerfRequestBucket( inSerfRequest );
6118590a0fdSAndre Fischer
6128590a0fdSAndre Fischer // apply callbacks for accepting response and handling response
6138590a0fdSAndre Fischer *outSerfResponseAcceptor = Serf_AcceptResponse;
6148590a0fdSAndre Fischer *outSerfResponseAcceptorBaton = this;
6158590a0fdSAndre Fischer *outSerfResponseHandler = Serf_HandleResponse;
6168590a0fdSAndre Fischer *outSerfResponseHandlerBaton = this;
6178590a0fdSAndre Fischer
6188590a0fdSAndre Fischer return APR_SUCCESS;
6198590a0fdSAndre Fischer }
6208590a0fdSAndre Fischer
acceptSerfResponse(serf_request_t * inSerfRequest,serf_bucket_t * inSerfStreamBucket,apr_pool_t * inAprPool)6218590a0fdSAndre Fischer serf_bucket_t* SerfRequestProcessor::acceptSerfResponse( serf_request_t * inSerfRequest,
6228590a0fdSAndre Fischer serf_bucket_t * inSerfStreamBucket,
6238590a0fdSAndre Fischer apr_pool_t * inAprPool )
6248590a0fdSAndre Fischer {
6258590a0fdSAndre Fischer mbAcceptSerfResponseCalled = true;
6268590a0fdSAndre Fischer return mrSerfSession.acceptSerfResponse( inSerfRequest,
6278590a0fdSAndre Fischer inSerfStreamBucket,
6288590a0fdSAndre Fischer inAprPool );
6298590a0fdSAndre Fischer }
6308590a0fdSAndre Fischer
handleSerfResponse(serf_request_t * inSerfRequest,serf_bucket_t * inSerfResponseBucket,apr_pool_t * inAprPool)6318590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::handleSerfResponse( serf_request_t * inSerfRequest,
6328590a0fdSAndre Fischer serf_bucket_t * inSerfResponseBucket,
6338590a0fdSAndre Fischer apr_pool_t * inAprPool )
6348590a0fdSAndre Fischer {
6358590a0fdSAndre Fischer mbHandleSerfResponseCalled = true;
6368590a0fdSAndre Fischer
6378590a0fdSAndre Fischer // some general response handling and error handling
6388590a0fdSAndre Fischer {
6398590a0fdSAndre Fischer if ( !inSerfResponseBucket )
6408590a0fdSAndre Fischer {
6418590a0fdSAndre Fischer /* A NULL response can come back if the request failed completely */
6428590a0fdSAndre Fischer mbProcessingDone = true;
6438590a0fdSAndre Fischer return APR_EGENERAL;
6448590a0fdSAndre Fischer }
6458590a0fdSAndre Fischer
6468590a0fdSAndre Fischer serf_status_line sl;
6478590a0fdSAndre Fischer apr_status_t status = serf_bucket_response_status( inSerfResponseBucket, &sl );
6488590a0fdSAndre Fischer if ( status )
6498590a0fdSAndre Fischer {
6508590a0fdSAndre Fischer mbProcessingDone = false; // allow another try in order to get a response
6518590a0fdSAndre Fischer return status;
6528590a0fdSAndre Fischer }
653*3edf6992SAndrea Pescetti serf_bucket_t *headers = serf_bucket_response_get_headers( inSerfResponseBucket );
654*3edf6992SAndrea Pescetti
655*3edf6992SAndrea Pescetti // check header according:
656*3edf6992SAndrea Pescetti // http://tools.ietf.org/html/rfc7231#section-7.4.2
657*3edf6992SAndrea Pescetti // need to do this so we can adjust the protocol accordingly
658*3edf6992SAndrea Pescetti // serf_bucket_headers_get is case independent
659*3edf6992SAndrea Pescetti const char* server = serf_bucket_headers_get( headers, "server" );
660*3edf6992SAndrea Pescetti if( server )
661*3edf6992SAndrea Pescetti {
662*3edf6992SAndrea Pescetti //update the server type on session
663*3edf6992SAndrea Pescetti mrSerfSession.setServerHeaderField( ::rtl::OUString::createFromAscii( server ) );
664*3edf6992SAndrea Pescetti }
665*3edf6992SAndrea Pescetti //the following extension is MS IIS specific,
666*3edf6992SAndrea Pescetti //see https://msdn.microsoft.com/en-us/library/cc250064.aspx
667*3edf6992SAndrea Pescetti //site last checked on 2015-03-02
668*3edf6992SAndrea Pescetti //TODO i126305 need to be added when serf is updated to a version supporting Windows authentication
669*3edf6992SAndrea Pescetti //const char* msDavExtErr = serf_bucket_headers_get( headers, "X-MSDAVEXT_ERROR" );
670*3edf6992SAndrea Pescetti
6718590a0fdSAndre Fischer // TODO - check, if response status code handling is correct
6728590a0fdSAndre Fischer mnHTTPStatusCode = ( sl.version != 0 && sl.code >= 0 )
6738590a0fdSAndre Fischer ? static_cast< sal_uInt16 >( sl.code )
6748590a0fdSAndre Fischer : SC_NONE;
6758590a0fdSAndre Fischer if ( sl.reason )
6768590a0fdSAndre Fischer {
6778590a0fdSAndre Fischer mHTTPStatusCodeText = ::rtl::OUString::createFromAscii( sl.reason );
6788590a0fdSAndre Fischer }
6798590a0fdSAndre Fischer if ( ( sl.version == 0 || sl.code < 0 ) ||
6808590a0fdSAndre Fischer mnHTTPStatusCode >= 300 )
6818590a0fdSAndre Fischer {
6828590a0fdSAndre Fischer if ( mnHTTPStatusCode == 301 ||
6838590a0fdSAndre Fischer mnHTTPStatusCode == 302 ||
6848590a0fdSAndre Fischer mnHTTPStatusCode == 303 ||
6858590a0fdSAndre Fischer mnHTTPStatusCode == 307 )
6868590a0fdSAndre Fischer {
6878590a0fdSAndre Fischer // new location for certain redirections
6888590a0fdSAndre Fischer const char* location = serf_bucket_headers_get( headers, "Location" );
6898590a0fdSAndre Fischer if ( location )
6908590a0fdSAndre Fischer {
6918590a0fdSAndre Fischer mRedirectLocation = rtl::OUString::createFromAscii( location );
6928590a0fdSAndre Fischer }
6938590a0fdSAndre Fischer mbProcessingDone = true;
6948590a0fdSAndre Fischer return APR_EGENERAL;
6958590a0fdSAndre Fischer }
6968590a0fdSAndre Fischer else if ( mrSerfSession.isHeadRequestInProgress() &&
6978590a0fdSAndre Fischer ( mnHTTPStatusCode == 401 || mnHTTPStatusCode == 407 ) )
6988590a0fdSAndre Fischer {
6998590a0fdSAndre Fischer // keep going as authentication is not required on HEAD request.
7008590a0fdSAndre Fischer // the response already contains header fields.
7018590a0fdSAndre Fischer }
7028590a0fdSAndre Fischer else
7038590a0fdSAndre Fischer {
7048590a0fdSAndre Fischer mbProcessingDone = true;
7058590a0fdSAndre Fischer return APR_EGENERAL;
7068590a0fdSAndre Fischer }
7078590a0fdSAndre Fischer }
7088590a0fdSAndre Fischer }
7098590a0fdSAndre Fischer
7108590a0fdSAndre Fischer // request specific processing of the response bucket
7118590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS;
7128590a0fdSAndre Fischer mbProcessingDone = mpProcImpl->processSerfResponseBucket( inSerfRequest,
7138590a0fdSAndre Fischer inSerfResponseBucket,
7148590a0fdSAndre Fischer inAprPool,
7158590a0fdSAndre Fischer status );
7168590a0fdSAndre Fischer
7178590a0fdSAndre Fischer return status;
7188590a0fdSAndre Fischer }
7198590a0fdSAndre Fischer
7208590a0fdSAndre Fischer } // namespace http_dav_ucp
7218590a0fdSAndre Fischer
722