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