xref: /AOO41X/main/ucb/source/ucp/webdav/SerfPropFindReqProcImpl.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 <SerfPropFindReqProcImpl.hxx>
26*8590a0fdSAndre Fischer #include <SerfTypes.hxx>
27*8590a0fdSAndre Fischer #include <DAVProperties.hxx>
28*8590a0fdSAndre Fischer 
29*8590a0fdSAndre Fischer #include <webdavresponseparser.hxx>
30*8590a0fdSAndre Fischer #include <comphelper/seqstream.hxx>
31*8590a0fdSAndre Fischer 
32*8590a0fdSAndre Fischer using namespace com::sun::star;
33*8590a0fdSAndre Fischer 
34*8590a0fdSAndre Fischer namespace http_dav_ucp
35*8590a0fdSAndre Fischer {
36*8590a0fdSAndre Fischer 
37*8590a0fdSAndre Fischer SerfPropFindReqProcImpl::SerfPropFindReqProcImpl( const char* inPath,
38*8590a0fdSAndre Fischer                                                   const Depth inDepth,
39*8590a0fdSAndre Fischer                                                   const std::vector< ::rtl::OUString > & inPropNames,
40*8590a0fdSAndre Fischer                                                   std::vector< DAVResource > & ioResources )
41*8590a0fdSAndre Fischer     : SerfRequestProcessorImpl( inPath )
42*8590a0fdSAndre Fischer     , mDepthStr( 0 )
43*8590a0fdSAndre Fischer     , mpPropNames( &inPropNames )
44*8590a0fdSAndre Fischer     , mpResources( &ioResources )
45*8590a0fdSAndre Fischer     , mpResInfo( 0 )
46*8590a0fdSAndre Fischer     , mbOnlyPropertyNames( false )
47*8590a0fdSAndre Fischer     , xInputStream( new SerfInputStream() )
48*8590a0fdSAndre Fischer {
49*8590a0fdSAndre Fischer     init( inDepth );
50*8590a0fdSAndre Fischer }
51*8590a0fdSAndre Fischer 
52*8590a0fdSAndre Fischer SerfPropFindReqProcImpl::SerfPropFindReqProcImpl( const char* inPath,
53*8590a0fdSAndre Fischer                                                   const Depth inDepth,
54*8590a0fdSAndre Fischer                                                   std::vector< DAVResourceInfo > & ioResInfo )
55*8590a0fdSAndre Fischer     : SerfRequestProcessorImpl( inPath )
56*8590a0fdSAndre Fischer     , mDepthStr( 0 )
57*8590a0fdSAndre Fischer     , mpPropNames( 0 )
58*8590a0fdSAndre Fischer     , mpResources( 0 )
59*8590a0fdSAndre Fischer     , mpResInfo( &ioResInfo )
60*8590a0fdSAndre Fischer     , mbOnlyPropertyNames( true )
61*8590a0fdSAndre Fischer     , xInputStream( new SerfInputStream() )
62*8590a0fdSAndre Fischer {
63*8590a0fdSAndre Fischer     init( inDepth );
64*8590a0fdSAndre Fischer }
65*8590a0fdSAndre Fischer 
66*8590a0fdSAndre Fischer void SerfPropFindReqProcImpl::init( const Depth inDepth )
67*8590a0fdSAndre Fischer {
68*8590a0fdSAndre Fischer     switch ( inDepth )
69*8590a0fdSAndre Fischer     {
70*8590a0fdSAndre Fischer         case DAVZERO:
71*8590a0fdSAndre Fischer             mDepthStr = "0";
72*8590a0fdSAndre Fischer             break;
73*8590a0fdSAndre Fischer         case DAVONE:
74*8590a0fdSAndre Fischer             mDepthStr = "1";
75*8590a0fdSAndre Fischer             break;
76*8590a0fdSAndre Fischer         case DAVINFINITY:
77*8590a0fdSAndre Fischer             mDepthStr = "infinity";
78*8590a0fdSAndre Fischer             break;
79*8590a0fdSAndre Fischer     }
80*8590a0fdSAndre Fischer }
81*8590a0fdSAndre Fischer 
82*8590a0fdSAndre Fischer SerfPropFindReqProcImpl::~SerfPropFindReqProcImpl()
83*8590a0fdSAndre Fischer {
84*8590a0fdSAndre Fischer }
85*8590a0fdSAndre Fischer 
86*8590a0fdSAndre Fischer #define PROPFIND_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?><propfind xmlns=\"DAV:\">"
87*8590a0fdSAndre Fischer #define PROPFIND_TRAILER "</propfind>"
88*8590a0fdSAndre Fischer 
89*8590a0fdSAndre Fischer serf_bucket_t * SerfPropFindReqProcImpl::createSerfRequestBucket( serf_request_t * inSerfRequest )
90*8590a0fdSAndre Fischer {
91*8590a0fdSAndre Fischer     serf_bucket_alloc_t* pSerfBucketAlloc = serf_request_get_alloc( inSerfRequest );
92*8590a0fdSAndre Fischer 
93*8590a0fdSAndre Fischer     // body bucket - certain properties OR all properties OR only property names
94*8590a0fdSAndre Fischer     serf_bucket_t* body_bkt = 0;
95*8590a0fdSAndre Fischer     sal_Int32 nDataLen = 0;
96*8590a0fdSAndre Fischer     {
97*8590a0fdSAndre Fischer         // create and fill body bucket with requested properties
98*8590a0fdSAndre Fischer         body_bkt = serf_bucket_aggregate_create( pSerfBucketAlloc );
99*8590a0fdSAndre Fischer 
100*8590a0fdSAndre Fischer         serf_bucket_t* tmp = 0;
101*8590a0fdSAndre Fischer         const int nPropCount = ( !mbOnlyPropertyNames && mpPropNames )
102*8590a0fdSAndre Fischer                                ? mpPropNames->size()
103*8590a0fdSAndre Fischer                                : 0;
104*8590a0fdSAndre Fischer         if ( nPropCount > 0 )
105*8590a0fdSAndre Fischer         {
106*8590a0fdSAndre Fischer             SerfPropName thePropName;
107*8590a0fdSAndre Fischer             for ( int theIndex = 0; theIndex < nPropCount; theIndex ++ )
108*8590a0fdSAndre Fischer             {
109*8590a0fdSAndre Fischer                 // split fullname into namespace and name!
110*8590a0fdSAndre Fischer                 DAVProperties::createSerfPropName( (*mpPropNames)[ theIndex ],
111*8590a0fdSAndre Fischer                                                    thePropName );
112*8590a0fdSAndre Fischer 
113*8590a0fdSAndre Fischer                 /* <*propname* xmlns="*propns*" /> */
114*8590a0fdSAndre Fischer                 tmp = SERF_BUCKET_SIMPLE_STRING_LEN("<", 1, pSerfBucketAlloc );
115*8590a0fdSAndre Fischer                 serf_bucket_aggregate_append( body_bkt, tmp );
116*8590a0fdSAndre Fischer                 nDataLen += 1;
117*8590a0fdSAndre Fischer 
118*8590a0fdSAndre Fischer                 tmp = SERF_BUCKET_SIMPLE_STRING( thePropName.name, pSerfBucketAlloc );
119*8590a0fdSAndre Fischer                 serf_bucket_aggregate_append( body_bkt, tmp );
120*8590a0fdSAndre Fischer                 nDataLen += strlen(thePropName.name);
121*8590a0fdSAndre Fischer 
122*8590a0fdSAndre Fischer                 tmp = SERF_BUCKET_SIMPLE_STRING_LEN( " xmlns=\"",
123*8590a0fdSAndre Fischer                                                      sizeof(" xmlns=\"")-1,
124*8590a0fdSAndre Fischer                                                      pSerfBucketAlloc );
125*8590a0fdSAndre Fischer                 serf_bucket_aggregate_append( body_bkt, tmp );
126*8590a0fdSAndre Fischer                 nDataLen += sizeof(" xmlns=\"")-1;
127*8590a0fdSAndre Fischer 
128*8590a0fdSAndre Fischer                 tmp = SERF_BUCKET_SIMPLE_STRING( thePropName.nspace, pSerfBucketAlloc );
129*8590a0fdSAndre Fischer                 serf_bucket_aggregate_append( body_bkt, tmp );
130*8590a0fdSAndre Fischer                 nDataLen += strlen(thePropName.nspace);
131*8590a0fdSAndre Fischer 
132*8590a0fdSAndre Fischer                 tmp = SERF_BUCKET_SIMPLE_STRING_LEN( "\"/>", sizeof("\"/>")-1,
133*8590a0fdSAndre Fischer                                                      pSerfBucketAlloc );
134*8590a0fdSAndre Fischer                 serf_bucket_aggregate_append( body_bkt, tmp );
135*8590a0fdSAndre Fischer                 nDataLen += sizeof("\"/>")-1;
136*8590a0fdSAndre Fischer             }
137*8590a0fdSAndre Fischer 
138*8590a0fdSAndre Fischer             tmp = SERF_BUCKET_SIMPLE_STRING_LEN("<prop>",
139*8590a0fdSAndre Fischer                                                 sizeof("<prop>")-1,
140*8590a0fdSAndre Fischer                                                 pSerfBucketAlloc );
141*8590a0fdSAndre Fischer             serf_bucket_aggregate_prepend(body_bkt, tmp);
142*8590a0fdSAndre Fischer             nDataLen += sizeof("<prop>")-1;
143*8590a0fdSAndre Fischer 
144*8590a0fdSAndre Fischer             tmp = SERF_BUCKET_SIMPLE_STRING_LEN("</prop>",
145*8590a0fdSAndre Fischer                                                 sizeof("</prop>")-1,
146*8590a0fdSAndre Fischer                                                 pSerfBucketAlloc );
147*8590a0fdSAndre Fischer             serf_bucket_aggregate_append(body_bkt, tmp);
148*8590a0fdSAndre Fischer             nDataLen += sizeof("</prop>")-1;
149*8590a0fdSAndre Fischer         }
150*8590a0fdSAndre Fischer         else
151*8590a0fdSAndre Fischer         {
152*8590a0fdSAndre Fischer             if ( mbOnlyPropertyNames )
153*8590a0fdSAndre Fischer             {
154*8590a0fdSAndre Fischer                 tmp = SERF_BUCKET_SIMPLE_STRING_LEN( "<propname/>",
155*8590a0fdSAndre Fischer                                                      sizeof("<propname/>")-1,
156*8590a0fdSAndre Fischer                                                      pSerfBucketAlloc );
157*8590a0fdSAndre Fischer                 nDataLen += sizeof("<propname/>")-1;
158*8590a0fdSAndre Fischer             }
159*8590a0fdSAndre Fischer             else
160*8590a0fdSAndre Fischer             {
161*8590a0fdSAndre Fischer                 tmp = SERF_BUCKET_SIMPLE_STRING_LEN( "<allprop/>",
162*8590a0fdSAndre Fischer                                                      sizeof("<allprop/>")-1,
163*8590a0fdSAndre Fischer                                                      pSerfBucketAlloc );
164*8590a0fdSAndre Fischer                 nDataLen += sizeof("<allprop/>")-1;
165*8590a0fdSAndre Fischer             }
166*8590a0fdSAndre Fischer             serf_bucket_aggregate_append( body_bkt, tmp );
167*8590a0fdSAndre Fischer         }
168*8590a0fdSAndre Fischer 
169*8590a0fdSAndre Fischer         tmp = SERF_BUCKET_SIMPLE_STRING_LEN( PROPFIND_HEADER,
170*8590a0fdSAndre Fischer                                              sizeof(PROPFIND_HEADER)-1,
171*8590a0fdSAndre Fischer                                              pSerfBucketAlloc );
172*8590a0fdSAndre Fischer         serf_bucket_aggregate_prepend(body_bkt, tmp);
173*8590a0fdSAndre Fischer         nDataLen += sizeof(PROPFIND_HEADER)-1;
174*8590a0fdSAndre Fischer 
175*8590a0fdSAndre Fischer         tmp = SERF_BUCKET_SIMPLE_STRING_LEN(PROPFIND_TRAILER,
176*8590a0fdSAndre Fischer                                             sizeof(PROPFIND_TRAILER)-1,
177*8590a0fdSAndre Fischer                                             pSerfBucketAlloc );
178*8590a0fdSAndre Fischer         serf_bucket_aggregate_append(body_bkt, tmp);
179*8590a0fdSAndre Fischer         nDataLen += sizeof(PROPFIND_TRAILER)-1;
180*8590a0fdSAndre Fischer     }
181*8590a0fdSAndre Fischer 
182*8590a0fdSAndre Fischer     // create serf request
183*8590a0fdSAndre Fischer     serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest,
184*8590a0fdSAndre Fischer                                                                  "PROPFIND",
185*8590a0fdSAndre Fischer                                                                  getPathStr(),
186*8590a0fdSAndre Fischer                                                                  body_bkt,
187*8590a0fdSAndre Fischer                                                                  serf_request_get_alloc( inSerfRequest ) );
188*8590a0fdSAndre Fischer 
189*8590a0fdSAndre Fischer     // TODO - correct header data
190*8590a0fdSAndre Fischer     // set request header fields
191*8590a0fdSAndre Fischer     serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt );
192*8590a0fdSAndre Fischer     serf_bucket_headers_setn( hdrs_bkt, "User-Agent", "www.openoffice.org/ucb/" );
193*8590a0fdSAndre Fischer     serf_bucket_headers_setn( hdrs_bkt, "Accept-Encoding", "gzip");
194*8590a0fdSAndre Fischer 
195*8590a0fdSAndre Fischer     // request specific header fields
196*8590a0fdSAndre Fischer     serf_bucket_headers_setn( hdrs_bkt, "Depth", mDepthStr );
197*8590a0fdSAndre Fischer     serf_bucket_headers_setn( hdrs_bkt, "Content-Type", "application/xml" );
198*8590a0fdSAndre Fischer     serf_bucket_headers_setn( hdrs_bkt, "Content-Length",
199*8590a0fdSAndre Fischer                               rtl::OUStringToOString( rtl::OUString::valueOf( nDataLen ), RTL_TEXTENCODING_UTF8 ) );
200*8590a0fdSAndre Fischer 
201*8590a0fdSAndre Fischer     return req_bkt;
202*8590a0fdSAndre Fischer }
203*8590a0fdSAndre Fischer 
204*8590a0fdSAndre Fischer 
205*8590a0fdSAndre Fischer bool SerfPropFindReqProcImpl::processSerfResponseBucket( serf_request_t * /*inSerfRequest*/,
206*8590a0fdSAndre Fischer                                                          serf_bucket_t * inSerfResponseBucket,
207*8590a0fdSAndre Fischer                                                          apr_pool_t * /*inAprPool*/,
208*8590a0fdSAndre Fischer                                                          apr_status_t & outStatus )
209*8590a0fdSAndre Fischer {
210*8590a0fdSAndre Fischer     const char* data;
211*8590a0fdSAndre Fischer     apr_size_t len;
212*8590a0fdSAndre Fischer 
213*8590a0fdSAndre Fischer     while (1) {
214*8590a0fdSAndre Fischer         outStatus = serf_bucket_read(inSerfResponseBucket, 2048, &data, &len);
215*8590a0fdSAndre Fischer         if (SERF_BUCKET_READ_ERROR(outStatus))
216*8590a0fdSAndre Fischer         {
217*8590a0fdSAndre Fischer             return true;
218*8590a0fdSAndre Fischer         }
219*8590a0fdSAndre Fischer 
220*8590a0fdSAndre Fischer         if ( len > 0 )
221*8590a0fdSAndre Fischer         {
222*8590a0fdSAndre Fischer             xInputStream->AddToStream( data, len );
223*8590a0fdSAndre Fischer         }
224*8590a0fdSAndre Fischer 
225*8590a0fdSAndre Fischer         /* are we done yet? */
226*8590a0fdSAndre Fischer         if (APR_STATUS_IS_EOF(outStatus))
227*8590a0fdSAndre Fischer         {
228*8590a0fdSAndre Fischer             if ( mbOnlyPropertyNames )
229*8590a0fdSAndre Fischer             {
230*8590a0fdSAndre Fischer                 const std::vector< DAVResourceInfo > rResInfo( parseWebDAVPropNameResponse( xInputStream.get() ) );
231*8590a0fdSAndre Fischer                 *mpResInfo = rResInfo;
232*8590a0fdSAndre Fischer             }
233*8590a0fdSAndre Fischer             else
234*8590a0fdSAndre Fischer             {
235*8590a0fdSAndre Fischer                 const std::vector< DAVResource > rResources( parseWebDAVPropFindResponse( xInputStream.get() ) );
236*8590a0fdSAndre Fischer                 *mpResources = rResources;
237*8590a0fdSAndre Fischer             }
238*8590a0fdSAndre Fischer 
239*8590a0fdSAndre Fischer             outStatus = APR_EOF;
240*8590a0fdSAndre Fischer             return true;
241*8590a0fdSAndre Fischer         }
242*8590a0fdSAndre Fischer 
243*8590a0fdSAndre Fischer         /* have we drained the response so far? */
244*8590a0fdSAndre Fischer         if ( APR_STATUS_IS_EAGAIN( outStatus ) )
245*8590a0fdSAndre Fischer         {
246*8590a0fdSAndre Fischer             return false;
247*8590a0fdSAndre Fischer         }
248*8590a0fdSAndre Fischer     }
249*8590a0fdSAndre Fischer 
250*8590a0fdSAndre Fischer     /* NOTREACHED */
251*8590a0fdSAndre Fischer     return true;
252*8590a0fdSAndre Fischer }
253*8590a0fdSAndre Fischer 
254*8590a0fdSAndre Fischer } // namespace http_dav_ucp
255