1*8590a0fdSAndre Fischer /************************************************************** 2*8590a0fdSAndre Fischer * 3*8590a0fdSAndre Fischer * Licensed to the Apache Software Foundation (ASF) under one 4*8590a0fdSAndre Fischer * or more contributor license agreements. See the NOTICE file 5*8590a0fdSAndre Fischer * distributed with this work for additional information 6*8590a0fdSAndre Fischer * regarding copyright ownership. The ASF licenses this file 7*8590a0fdSAndre Fischer * to you under the Apache License, Version 2.0 (the 8*8590a0fdSAndre Fischer * "License"); you may not use this file except in compliance 9*8590a0fdSAndre Fischer * with the License. You may obtain a copy of the License at 10*8590a0fdSAndre Fischer * 11*8590a0fdSAndre Fischer * http://www.apache.org/licenses/LICENSE-2.0 12*8590a0fdSAndre Fischer * 13*8590a0fdSAndre Fischer * Unless required by applicable law or agreed to in writing, 14*8590a0fdSAndre Fischer * software distributed under the License is distributed on an 15*8590a0fdSAndre Fischer * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*8590a0fdSAndre Fischer * KIND, either express or implied. See the License for the 17*8590a0fdSAndre Fischer * specific language governing permissions and limitations 18*8590a0fdSAndre Fischer * under the License. 19*8590a0fdSAndre Fischer * 20*8590a0fdSAndre Fischer *************************************************************/ 21*8590a0fdSAndre Fischer 22*8590a0fdSAndre Fischer // MARKER(update_precomp.py): autogen include statement, do not remove 23*8590a0fdSAndre Fischer #include "precompiled_ucb.hxx" 24*8590a0fdSAndre Fischer 25*8590a0fdSAndre Fischer #include <SerfRequestProcessor.hxx> 26*8590a0fdSAndre Fischer #include <SerfRequestProcessorImpl.hxx> 27*8590a0fdSAndre Fischer #include <SerfRequestProcessorImplFac.hxx> 28*8590a0fdSAndre Fischer #include <SerfCallbacks.hxx> 29*8590a0fdSAndre Fischer #include <SerfSession.hxx> 30*8590a0fdSAndre Fischer 31*8590a0fdSAndre Fischer #include <apr_strings.h> 32*8590a0fdSAndre Fischer 33*8590a0fdSAndre Fischer namespace http_dav_ucp 34*8590a0fdSAndre Fischer { 35*8590a0fdSAndre Fischer 36*8590a0fdSAndre Fischer SerfRequestProcessor::SerfRequestProcessor( SerfSession& rSerfSession, 37*8590a0fdSAndre Fischer const rtl::OUString & inPath ) 38*8590a0fdSAndre Fischer : mrSerfSession( rSerfSession ) 39*8590a0fdSAndre Fischer , mPathStr( 0 ) 40*8590a0fdSAndre Fischer , mDestPathStr( 0 ) 41*8590a0fdSAndre Fischer , mpProcImpl( 0 ) 42*8590a0fdSAndre Fischer , mbProcessingDone( false ) 43*8590a0fdSAndre Fischer , mpDAVException() 44*8590a0fdSAndre Fischer , mnHTTPStatusCode( SC_NONE ) 45*8590a0fdSAndre Fischer , mHTTPStatusCodeText() 46*8590a0fdSAndre Fischer , mRedirectLocation() 47*8590a0fdSAndre Fischer , mbSetupSerfRequestCalled( false ) 48*8590a0fdSAndre Fischer , mbAcceptSerfResponseCalled( false ) 49*8590a0fdSAndre Fischer , mbHandleSerfResponseCalled( false ) 50*8590a0fdSAndre Fischer { 51*8590a0fdSAndre Fischer mPathStr = apr_pstrdup( mrSerfSession.getAprPool(), 52*8590a0fdSAndre Fischer rtl::OUStringToOString( inPath, RTL_TEXTENCODING_UTF8 ) ); 53*8590a0fdSAndre Fischer } 54*8590a0fdSAndre Fischer 55*8590a0fdSAndre Fischer SerfRequestProcessor::~SerfRequestProcessor() 56*8590a0fdSAndre Fischer { 57*8590a0fdSAndre Fischer delete mpProcImpl; 58*8590a0fdSAndre Fischer delete mpDAVException; 59*8590a0fdSAndre Fischer } 60*8590a0fdSAndre Fischer 61*8590a0fdSAndre Fischer void SerfRequestProcessor::prepareProcessor() 62*8590a0fdSAndre Fischer { 63*8590a0fdSAndre Fischer delete mpDAVException; 64*8590a0fdSAndre Fischer mpDAVException = 0; 65*8590a0fdSAndre Fischer mnHTTPStatusCode = SC_NONE; 66*8590a0fdSAndre Fischer mHTTPStatusCodeText = rtl::OUString(); 67*8590a0fdSAndre Fischer mRedirectLocation = rtl::OUString(); 68*8590a0fdSAndre Fischer 69*8590a0fdSAndre Fischer mbSetupSerfRequestCalled = false; 70*8590a0fdSAndre Fischer mbAcceptSerfResponseCalled = false; 71*8590a0fdSAndre Fischer mbHandleSerfResponseCalled = false; 72*8590a0fdSAndre Fischer } 73*8590a0fdSAndre Fischer 74*8590a0fdSAndre Fischer // PROPFIND - allprop & named 75*8590a0fdSAndre Fischer bool SerfRequestProcessor::processPropFind( const Depth inDepth, 76*8590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inPropNames, 77*8590a0fdSAndre Fischer std::vector< DAVResource > & ioResources, 78*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 79*8590a0fdSAndre Fischer { 80*8590a0fdSAndre Fischer mpProcImpl = createPropFindReqProcImpl( mPathStr, 81*8590a0fdSAndre Fischer inDepth, 82*8590a0fdSAndre Fischer inPropNames, 83*8590a0fdSAndre Fischer ioResources ); 84*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 85*8590a0fdSAndre Fischer 86*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 87*8590a0fdSAndre Fischer } 88*8590a0fdSAndre Fischer 89*8590a0fdSAndre Fischer // PROPFIND - property names 90*8590a0fdSAndre Fischer bool SerfRequestProcessor::processPropFind( const Depth inDepth, 91*8590a0fdSAndre Fischer std::vector< DAVResourceInfo > & ioResInfo, 92*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 93*8590a0fdSAndre Fischer { 94*8590a0fdSAndre Fischer mpProcImpl = createPropFindReqProcImpl( mPathStr, 95*8590a0fdSAndre Fischer inDepth, 96*8590a0fdSAndre Fischer ioResInfo ); 97*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 98*8590a0fdSAndre Fischer 99*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 100*8590a0fdSAndre Fischer } 101*8590a0fdSAndre Fischer 102*8590a0fdSAndre Fischer // PROPPATCH 103*8590a0fdSAndre Fischer bool SerfRequestProcessor::processPropPatch( const std::vector< ProppatchValue > & inProperties, 104*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 105*8590a0fdSAndre Fischer { 106*8590a0fdSAndre Fischer mpProcImpl = createPropPatchReqProcImpl( mPathStr, 107*8590a0fdSAndre Fischer inProperties ); 108*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 109*8590a0fdSAndre Fischer 110*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 111*8590a0fdSAndre Fischer } 112*8590a0fdSAndre Fischer 113*8590a0fdSAndre Fischer // GET 114*8590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, 115*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 116*8590a0fdSAndre Fischer { 117*8590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 118*8590a0fdSAndre Fischer xioInStrm ); 119*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 120*8590a0fdSAndre Fischer 121*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 122*8590a0fdSAndre Fischer } 123*8590a0fdSAndre Fischer 124*8590a0fdSAndre Fischer // GET inclusive header fields 125*8590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, 126*8590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 127*8590a0fdSAndre Fischer DAVResource & ioResource, 128*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 129*8590a0fdSAndre Fischer { 130*8590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 131*8590a0fdSAndre Fischer xioInStrm, 132*8590a0fdSAndre Fischer inHeaderNames, 133*8590a0fdSAndre Fischer ioResource ); 134*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 135*8590a0fdSAndre Fischer 136*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 137*8590a0fdSAndre Fischer } 138*8590a0fdSAndre Fischer 139*8590a0fdSAndre Fischer // GET 140*8590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, 141*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 142*8590a0fdSAndre Fischer { 143*8590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 144*8590a0fdSAndre Fischer xioOutStrm ); 145*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 146*8590a0fdSAndre Fischer 147*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 148*8590a0fdSAndre Fischer } 149*8590a0fdSAndre Fischer 150*8590a0fdSAndre Fischer // GET inclusive header fields 151*8590a0fdSAndre Fischer bool SerfRequestProcessor::processGet( const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, 152*8590a0fdSAndre Fischer const std::vector< ::rtl::OUString > & inHeaderNames, 153*8590a0fdSAndre Fischer DAVResource & ioResource, 154*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 155*8590a0fdSAndre Fischer { 156*8590a0fdSAndre Fischer mpProcImpl = createGetReqProcImpl( mPathStr, 157*8590a0fdSAndre Fischer xioOutStrm, 158*8590a0fdSAndre Fischer inHeaderNames, 159*8590a0fdSAndre Fischer ioResource ); 160*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 161*8590a0fdSAndre Fischer 162*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 163*8590a0fdSAndre Fischer } 164*8590a0fdSAndre Fischer 165*8590a0fdSAndre Fischer // HEAD 166*8590a0fdSAndre Fischer bool SerfRequestProcessor::processHead( const std::vector< ::rtl::OUString > & inHeaderNames, 167*8590a0fdSAndre Fischer DAVResource & ioResource, 168*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 169*8590a0fdSAndre Fischer { 170*8590a0fdSAndre Fischer mpProcImpl = createHeadReqProcImpl( mPathStr, 171*8590a0fdSAndre Fischer inHeaderNames, 172*8590a0fdSAndre Fischer ioResource ); 173*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 174*8590a0fdSAndre Fischer 175*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 176*8590a0fdSAndre Fischer } 177*8590a0fdSAndre Fischer 178*8590a0fdSAndre Fischer // PUT 179*8590a0fdSAndre Fischer bool SerfRequestProcessor::processPut( const char* inData, 180*8590a0fdSAndre Fischer apr_size_t inDataLen, 181*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 182*8590a0fdSAndre Fischer { 183*8590a0fdSAndre Fischer mpProcImpl = createPutReqProcImpl( mPathStr, 184*8590a0fdSAndre Fischer inData, 185*8590a0fdSAndre Fischer inDataLen ); 186*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 187*8590a0fdSAndre Fischer 188*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 189*8590a0fdSAndre Fischer } 190*8590a0fdSAndre Fischer 191*8590a0fdSAndre Fischer // POST 192*8590a0fdSAndre Fischer bool SerfRequestProcessor::processPost( const char* inData, 193*8590a0fdSAndre Fischer apr_size_t inDataLen, 194*8590a0fdSAndre Fischer const rtl::OUString & inContentType, 195*8590a0fdSAndre Fischer const rtl::OUString & inReferer, 196*8590a0fdSAndre Fischer const com::sun::star::uno::Reference< SerfInputStream >& xioInStrm, 197*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 198*8590a0fdSAndre Fischer { 199*8590a0fdSAndre Fischer mContentType = apr_pstrdup( mrSerfSession.getAprPool(), 200*8590a0fdSAndre Fischer rtl::OUStringToOString( inContentType, RTL_TEXTENCODING_UTF8 ) ); 201*8590a0fdSAndre Fischer mReferer = apr_pstrdup( mrSerfSession.getAprPool(), 202*8590a0fdSAndre Fischer rtl::OUStringToOString( inReferer, RTL_TEXTENCODING_UTF8 ) ); 203*8590a0fdSAndre Fischer mpProcImpl = createPostReqProcImpl( mPathStr, 204*8590a0fdSAndre Fischer inData, 205*8590a0fdSAndre Fischer inDataLen, 206*8590a0fdSAndre Fischer mContentType, 207*8590a0fdSAndre Fischer mReferer, 208*8590a0fdSAndre Fischer xioInStrm ); 209*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 210*8590a0fdSAndre Fischer 211*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 212*8590a0fdSAndre Fischer } 213*8590a0fdSAndre Fischer 214*8590a0fdSAndre Fischer // POST 215*8590a0fdSAndre Fischer bool SerfRequestProcessor::processPost( const char* inData, 216*8590a0fdSAndre Fischer apr_size_t inDataLen, 217*8590a0fdSAndre Fischer const rtl::OUString & inContentType, 218*8590a0fdSAndre Fischer const rtl::OUString & inReferer, 219*8590a0fdSAndre Fischer const com::sun::star::uno::Reference< com::sun::star::io::XOutputStream >& xioOutStrm, 220*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 221*8590a0fdSAndre Fischer { 222*8590a0fdSAndre Fischer mContentType = apr_pstrdup( mrSerfSession.getAprPool(), 223*8590a0fdSAndre Fischer rtl::OUStringToOString( inContentType, RTL_TEXTENCODING_UTF8 ) ); 224*8590a0fdSAndre Fischer mReferer = apr_pstrdup( mrSerfSession.getAprPool(), 225*8590a0fdSAndre Fischer rtl::OUStringToOString( inReferer, RTL_TEXTENCODING_UTF8 ) ); 226*8590a0fdSAndre Fischer mpProcImpl = createPostReqProcImpl( mPathStr, 227*8590a0fdSAndre Fischer inData, 228*8590a0fdSAndre Fischer inDataLen, 229*8590a0fdSAndre Fischer mContentType, 230*8590a0fdSAndre Fischer mReferer, 231*8590a0fdSAndre Fischer xioOutStrm ); 232*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 233*8590a0fdSAndre Fischer 234*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 235*8590a0fdSAndre Fischer } 236*8590a0fdSAndre Fischer 237*8590a0fdSAndre Fischer // DELETE 238*8590a0fdSAndre Fischer bool SerfRequestProcessor::processDelete( apr_status_t& outSerfStatus ) 239*8590a0fdSAndre Fischer { 240*8590a0fdSAndre Fischer mpProcImpl = createDeleteReqProcImpl( mPathStr ); 241*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 242*8590a0fdSAndre Fischer 243*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 244*8590a0fdSAndre Fischer } 245*8590a0fdSAndre Fischer 246*8590a0fdSAndre Fischer // MKCOL 247*8590a0fdSAndre Fischer bool SerfRequestProcessor::processMkCol( apr_status_t& outSerfStatus ) 248*8590a0fdSAndre Fischer { 249*8590a0fdSAndre Fischer mpProcImpl = createMkColReqProcImpl( mPathStr ); 250*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 251*8590a0fdSAndre Fischer 252*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 253*8590a0fdSAndre Fischer } 254*8590a0fdSAndre Fischer 255*8590a0fdSAndre Fischer // COPY 256*8590a0fdSAndre Fischer bool SerfRequestProcessor::processCopy( const rtl::OUString & inDestinationPath, 257*8590a0fdSAndre Fischer const bool inOverwrite, 258*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 259*8590a0fdSAndre Fischer { 260*8590a0fdSAndre Fischer mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), 261*8590a0fdSAndre Fischer rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ) ); 262*8590a0fdSAndre Fischer mpProcImpl = createCopyReqProcImpl( mPathStr, 263*8590a0fdSAndre Fischer mDestPathStr, 264*8590a0fdSAndre Fischer inOverwrite ); 265*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 266*8590a0fdSAndre Fischer 267*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 268*8590a0fdSAndre Fischer } 269*8590a0fdSAndre Fischer 270*8590a0fdSAndre Fischer // MOVE 271*8590a0fdSAndre Fischer bool SerfRequestProcessor::processMove( const rtl::OUString & inDestinationPath, 272*8590a0fdSAndre Fischer const bool inOverwrite, 273*8590a0fdSAndre Fischer apr_status_t& outSerfStatus ) 274*8590a0fdSAndre Fischer { 275*8590a0fdSAndre Fischer mDestPathStr = apr_pstrdup( mrSerfSession.getAprPool(), 276*8590a0fdSAndre Fischer rtl::OUStringToOString( inDestinationPath, RTL_TEXTENCODING_UTF8 ) ); 277*8590a0fdSAndre Fischer mpProcImpl = createMoveReqProcImpl( mPathStr, 278*8590a0fdSAndre Fischer mDestPathStr, 279*8590a0fdSAndre Fischer inOverwrite ); 280*8590a0fdSAndre Fischer outSerfStatus = runProcessor(); 281*8590a0fdSAndre Fischer 282*8590a0fdSAndre Fischer return outSerfStatus == APR_SUCCESS; 283*8590a0fdSAndre Fischer } 284*8590a0fdSAndre Fischer 285*8590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::runProcessor() 286*8590a0fdSAndre Fischer { 287*8590a0fdSAndre Fischer prepareProcessor(); 288*8590a0fdSAndre Fischer 289*8590a0fdSAndre Fischer // create serf request 290*8590a0fdSAndre Fischer serf_connection_request_create( mrSerfSession.getSerfConnection(), 291*8590a0fdSAndre Fischer Serf_SetupRequest, 292*8590a0fdSAndre Fischer this ); 293*8590a0fdSAndre Fischer 294*8590a0fdSAndre Fischer // perform serf request 295*8590a0fdSAndre Fischer mbProcessingDone = false; 296*8590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 297*8590a0fdSAndre Fischer serf_context_t* pSerfContext = mrSerfSession.getSerfContext(); 298*8590a0fdSAndre Fischer apr_pool_t* pAprPool = mrSerfSession.getAprPool(); 299*8590a0fdSAndre Fischer while ( true ) 300*8590a0fdSAndre Fischer { 301*8590a0fdSAndre Fischer status = serf_context_run( pSerfContext, 302*8590a0fdSAndre Fischer SERF_DURATION_FOREVER, 303*8590a0fdSAndre Fischer pAprPool ); 304*8590a0fdSAndre Fischer if ( APR_STATUS_IS_TIMEUP( status ) ) 305*8590a0fdSAndre Fischer { 306*8590a0fdSAndre Fischer continue; 307*8590a0fdSAndre Fischer } 308*8590a0fdSAndre Fischer if ( status != APR_SUCCESS ) 309*8590a0fdSAndre Fischer { 310*8590a0fdSAndre Fischer break; 311*8590a0fdSAndre Fischer } 312*8590a0fdSAndre Fischer if ( mbProcessingDone ) 313*8590a0fdSAndre Fischer { 314*8590a0fdSAndre Fischer break; 315*8590a0fdSAndre Fischer } 316*8590a0fdSAndre Fischer } 317*8590a0fdSAndre Fischer 318*8590a0fdSAndre Fischer postprocessProcessor( status ); 319*8590a0fdSAndre Fischer 320*8590a0fdSAndre Fischer return status; 321*8590a0fdSAndre Fischer } 322*8590a0fdSAndre Fischer 323*8590a0fdSAndre Fischer void SerfRequestProcessor::postprocessProcessor( const apr_status_t inStatus ) 324*8590a0fdSAndre Fischer { 325*8590a0fdSAndre Fischer if ( inStatus == APR_SUCCESS ) 326*8590a0fdSAndre Fischer { 327*8590a0fdSAndre Fischer return; 328*8590a0fdSAndre Fischer } 329*8590a0fdSAndre Fischer 330*8590a0fdSAndre Fischer // DEBUG INFO 331*8590a0fdSAndre Fischer const char* SerfErrorStr = serf_error_string( inStatus ); 332*8590a0fdSAndre Fischer char AprErrorStr[256]; 333*8590a0fdSAndre Fischer apr_strerror( inStatus, AprErrorStr, sizeof( AprErrorStr ) ); 334*8590a0fdSAndre Fischer 335*8590a0fdSAndre Fischer switch ( inStatus ) 336*8590a0fdSAndre Fischer { 337*8590a0fdSAndre Fischer case APR_EGENERAL: 338*8590a0fdSAndre Fischer // general error; <mnHTTPStatusCode> provides more information 339*8590a0fdSAndre Fischer { 340*8590a0fdSAndre Fischer // TODO: reactivate special handling copied from neon!? 341*8590a0fdSAndre Fischer /* 342*8590a0fdSAndre Fischer if ( mnHTTPStatusCode == SC_LOCKED ) 343*8590a0fdSAndre Fischer { 344*8590a0fdSAndre Fischer if ( m_aSerfLockStore.findByUri( 345*8590a0fdSAndre Fischer makeAbsoluteURL( inPath ) ) == 0 ) 346*8590a0fdSAndre Fischer { 347*8590a0fdSAndre Fischer // locked by 3rd party 348*8590a0fdSAndre Fischer throw DAVException( DAVException::DAV_LOCKED ); 349*8590a0fdSAndre Fischer } 350*8590a0fdSAndre Fischer else 351*8590a0fdSAndre Fischer { 352*8590a0fdSAndre Fischer // locked by ourself 353*8590a0fdSAndre Fischer throw DAVException( DAVException::DAV_LOCKED_SELF ); 354*8590a0fdSAndre Fischer } 355*8590a0fdSAndre Fischer } 356*8590a0fdSAndre Fischer 357*8590a0fdSAndre Fischer // Special handling for 400 and 412 status codes, which may indicate 358*8590a0fdSAndre Fischer // that a lock previously obtained by us has been released meanwhile 359*8590a0fdSAndre Fischer // by the server. Unfortunately, RFC is not clear at this point, 360*8590a0fdSAndre Fischer // thus server implementations behave different... 361*8590a0fdSAndre Fischer else if ( mnHTTPStatusCode == SC_BAD_REQUEST || mnHTTPStatusCode == SC_PRECONDITION_FAILED ) 362*8590a0fdSAndre Fischer { 363*8590a0fdSAndre Fischer if ( removeExpiredLocktoken( makeAbsoluteURL( inPath ), rEnv ) ) 364*8590a0fdSAndre Fischer throw DAVException( DAVException::DAV_LOCK_EXPIRED ); 365*8590a0fdSAndre Fischer } 366*8590a0fdSAndre Fischer */ 367*8590a0fdSAndre Fischer switch ( mnHTTPStatusCode ) 368*8590a0fdSAndre Fischer { 369*8590a0fdSAndre Fischer case SC_NONE: 370*8590a0fdSAndre Fischer if ( !mbSetupSerfRequestCalled ) 371*8590a0fdSAndre Fischer { 372*8590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_LOOKUP, 373*8590a0fdSAndre Fischer SerfUri::makeConnectionEndPointString( mrSerfSession.getHostName(), 374*8590a0fdSAndre Fischer mrSerfSession.getPort() ) ); 375*8590a0fdSAndre Fischer } 376*8590a0fdSAndre Fischer else 377*8590a0fdSAndre Fischer { 378*8590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR, 379*8590a0fdSAndre Fischer mHTTPStatusCodeText, 380*8590a0fdSAndre Fischer mnHTTPStatusCode ); 381*8590a0fdSAndre Fischer } 382*8590a0fdSAndre Fischer break; 383*8590a0fdSAndre Fischer case SC_MOVED_PERMANENTLY: 384*8590a0fdSAndre Fischer case SC_MOVED_TEMPORARILY: 385*8590a0fdSAndre Fischer case SC_SEE_OTHER: 386*8590a0fdSAndre Fischer case SC_TEMPORARY_REDIRECT: 387*8590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_REDIRECT, 388*8590a0fdSAndre Fischer mRedirectLocation ); 389*8590a0fdSAndre Fischer break; 390*8590a0fdSAndre Fischer default: 391*8590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR, 392*8590a0fdSAndre Fischer mHTTPStatusCodeText, 393*8590a0fdSAndre Fischer mnHTTPStatusCode ); 394*8590a0fdSAndre Fischer break; 395*8590a0fdSAndre Fischer } 396*8590a0fdSAndre Fischer } 397*8590a0fdSAndre Fischer break; 398*8590a0fdSAndre Fischer 399*8590a0fdSAndre Fischer default: 400*8590a0fdSAndre Fischer mpDAVException = new DAVException( DAVException::DAV_HTTP_ERROR ); 401*8590a0fdSAndre Fischer break; 402*8590a0fdSAndre Fischer } 403*8590a0fdSAndre Fischer 404*8590a0fdSAndre Fischer } 405*8590a0fdSAndre Fischer 406*8590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::provideSerfCredentials( char ** outUsername, 407*8590a0fdSAndre Fischer char ** outPassword, 408*8590a0fdSAndre Fischer serf_request_t * inRequest, 409*8590a0fdSAndre Fischer int inCode, 410*8590a0fdSAndre Fischer const char *inAuthProtocol, 411*8590a0fdSAndre Fischer const char *inRealm, 412*8590a0fdSAndre Fischer apr_pool_t *inAprPool ) 413*8590a0fdSAndre Fischer { 414*8590a0fdSAndre Fischer return mrSerfSession.provideSerfCredentials( outUsername, 415*8590a0fdSAndre Fischer outPassword, 416*8590a0fdSAndre Fischer inRequest, 417*8590a0fdSAndre Fischer inCode, 418*8590a0fdSAndre Fischer inAuthProtocol, 419*8590a0fdSAndre Fischer inRealm, 420*8590a0fdSAndre Fischer inAprPool ); 421*8590a0fdSAndre Fischer } 422*8590a0fdSAndre Fischer 423*8590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::setupSerfRequest( serf_request_t * inSerfRequest, 424*8590a0fdSAndre Fischer serf_bucket_t ** outSerfRequestBucket, 425*8590a0fdSAndre Fischer serf_response_acceptor_t * outSerfResponseAcceptor, 426*8590a0fdSAndre Fischer void ** outSerfResponseAcceptorBaton, 427*8590a0fdSAndre Fischer serf_response_handler_t * outSerfResponseHandler, 428*8590a0fdSAndre Fischer void ** outSerfResponseHandlerBaton, 429*8590a0fdSAndre Fischer apr_pool_t * /*inAprPool*/ ) 430*8590a0fdSAndre Fischer { 431*8590a0fdSAndre Fischer mbSetupSerfRequestCalled = true; 432*8590a0fdSAndre Fischer *outSerfRequestBucket = mpProcImpl->createSerfRequestBucket( inSerfRequest ); 433*8590a0fdSAndre Fischer 434*8590a0fdSAndre Fischer // apply callbacks for accepting response and handling response 435*8590a0fdSAndre Fischer *outSerfResponseAcceptor = Serf_AcceptResponse; 436*8590a0fdSAndre Fischer *outSerfResponseAcceptorBaton = this; 437*8590a0fdSAndre Fischer *outSerfResponseHandler = Serf_HandleResponse; 438*8590a0fdSAndre Fischer *outSerfResponseHandlerBaton = this; 439*8590a0fdSAndre Fischer 440*8590a0fdSAndre Fischer return APR_SUCCESS; 441*8590a0fdSAndre Fischer } 442*8590a0fdSAndre Fischer 443*8590a0fdSAndre Fischer serf_bucket_t* SerfRequestProcessor::acceptSerfResponse( serf_request_t * inSerfRequest, 444*8590a0fdSAndre Fischer serf_bucket_t * inSerfStreamBucket, 445*8590a0fdSAndre Fischer apr_pool_t * inAprPool ) 446*8590a0fdSAndre Fischer { 447*8590a0fdSAndre Fischer mbAcceptSerfResponseCalled = true; 448*8590a0fdSAndre Fischer return mrSerfSession.acceptSerfResponse( inSerfRequest, 449*8590a0fdSAndre Fischer inSerfStreamBucket, 450*8590a0fdSAndre Fischer inAprPool ); 451*8590a0fdSAndre Fischer } 452*8590a0fdSAndre Fischer 453*8590a0fdSAndre Fischer apr_status_t SerfRequestProcessor::handleSerfResponse( serf_request_t * inSerfRequest, 454*8590a0fdSAndre Fischer serf_bucket_t * inSerfResponseBucket, 455*8590a0fdSAndre Fischer apr_pool_t * inAprPool ) 456*8590a0fdSAndre Fischer { 457*8590a0fdSAndre Fischer mbHandleSerfResponseCalled = true; 458*8590a0fdSAndre Fischer 459*8590a0fdSAndre Fischer // some general response handling and error handling 460*8590a0fdSAndre Fischer { 461*8590a0fdSAndre Fischer if ( !inSerfResponseBucket ) 462*8590a0fdSAndre Fischer { 463*8590a0fdSAndre Fischer /* A NULL response can come back if the request failed completely */ 464*8590a0fdSAndre Fischer mbProcessingDone = true; 465*8590a0fdSAndre Fischer return APR_EGENERAL; 466*8590a0fdSAndre Fischer } 467*8590a0fdSAndre Fischer 468*8590a0fdSAndre Fischer serf_status_line sl; 469*8590a0fdSAndre Fischer apr_status_t status = serf_bucket_response_status( inSerfResponseBucket, &sl ); 470*8590a0fdSAndre Fischer if ( status ) 471*8590a0fdSAndre Fischer { 472*8590a0fdSAndre Fischer mbProcessingDone = false; // allow another try in order to get a response 473*8590a0fdSAndre Fischer return status; 474*8590a0fdSAndre Fischer } 475*8590a0fdSAndre Fischer // TODO - check, if response status code handling is correct 476*8590a0fdSAndre Fischer mnHTTPStatusCode = ( sl.version != 0 && sl.code >= 0 ) 477*8590a0fdSAndre Fischer ? static_cast< sal_uInt16 >( sl.code ) 478*8590a0fdSAndre Fischer : SC_NONE; 479*8590a0fdSAndre Fischer if ( sl.reason ) 480*8590a0fdSAndre Fischer { 481*8590a0fdSAndre Fischer mHTTPStatusCodeText = ::rtl::OUString::createFromAscii( sl.reason ); 482*8590a0fdSAndre Fischer } 483*8590a0fdSAndre Fischer if ( ( sl.version == 0 || sl.code < 0 ) || 484*8590a0fdSAndre Fischer mnHTTPStatusCode >= 300 ) 485*8590a0fdSAndre Fischer { 486*8590a0fdSAndre Fischer if ( mnHTTPStatusCode == 301 || 487*8590a0fdSAndre Fischer mnHTTPStatusCode == 302 || 488*8590a0fdSAndre Fischer mnHTTPStatusCode == 303 || 489*8590a0fdSAndre Fischer mnHTTPStatusCode == 307 ) 490*8590a0fdSAndre Fischer { 491*8590a0fdSAndre Fischer // new location for certain redirections 492*8590a0fdSAndre Fischer serf_bucket_t *headers = serf_bucket_response_get_headers( inSerfResponseBucket ); 493*8590a0fdSAndre Fischer const char* location = serf_bucket_headers_get( headers, "Location" ); 494*8590a0fdSAndre Fischer if ( location ) 495*8590a0fdSAndre Fischer { 496*8590a0fdSAndre Fischer mRedirectLocation = rtl::OUString::createFromAscii( location ); 497*8590a0fdSAndre Fischer } 498*8590a0fdSAndre Fischer mbProcessingDone = true; 499*8590a0fdSAndre Fischer return APR_EGENERAL; 500*8590a0fdSAndre Fischer } 501*8590a0fdSAndre Fischer else if ( mrSerfSession.isHeadRequestInProgress() && 502*8590a0fdSAndre Fischer ( mnHTTPStatusCode == 401 || mnHTTPStatusCode == 407 ) ) 503*8590a0fdSAndre Fischer { 504*8590a0fdSAndre Fischer // keep going as authentication is not required on HEAD request. 505*8590a0fdSAndre Fischer // the response already contains header fields. 506*8590a0fdSAndre Fischer } 507*8590a0fdSAndre Fischer else 508*8590a0fdSAndre Fischer { 509*8590a0fdSAndre Fischer mbProcessingDone = true; 510*8590a0fdSAndre Fischer return APR_EGENERAL; 511*8590a0fdSAndre Fischer } 512*8590a0fdSAndre Fischer } 513*8590a0fdSAndre Fischer } 514*8590a0fdSAndre Fischer 515*8590a0fdSAndre Fischer // request specific processing of the response bucket 516*8590a0fdSAndre Fischer apr_status_t status = APR_SUCCESS; 517*8590a0fdSAndre Fischer mbProcessingDone = mpProcImpl->processSerfResponseBucket( inSerfRequest, 518*8590a0fdSAndre Fischer inSerfResponseBucket, 519*8590a0fdSAndre Fischer inAprPool, 520*8590a0fdSAndre Fischer status ); 521*8590a0fdSAndre Fischer 522*8590a0fdSAndre Fischer return status; 523*8590a0fdSAndre Fischer } 524*8590a0fdSAndre Fischer 525*8590a0fdSAndre Fischer } // namespace http_dav_ucp 526*8590a0fdSAndre Fischer 527