1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_ucb.hxx" 24 25 #include <SerfPropFindReqProcImpl.hxx> 26 #include <SerfTypes.hxx> 27 #include <DAVProperties.hxx> 28 29 #include <webdavresponseparser.hxx> 30 #include <comphelper/seqstream.hxx> 31 32 using namespace com::sun::star; 33 34 namespace http_dav_ucp 35 { 36 37 SerfPropFindReqProcImpl::SerfPropFindReqProcImpl( const char* inPath, 38 const Depth inDepth, 39 const std::vector< ::rtl::OUString > & inPropNames, 40 std::vector< DAVResource > & ioResources ) 41 : SerfRequestProcessorImpl( inPath ) 42 , mDepthStr( 0 ) 43 , mpPropNames( &inPropNames ) 44 , mpResources( &ioResources ) 45 , mpResInfo( 0 ) 46 , mbOnlyPropertyNames( false ) 47 , xInputStream( new SerfInputStream() ) 48 { 49 init( inDepth ); 50 } 51 52 SerfPropFindReqProcImpl::SerfPropFindReqProcImpl( const char* inPath, 53 const Depth inDepth, 54 std::vector< DAVResourceInfo > & ioResInfo ) 55 : SerfRequestProcessorImpl( inPath ) 56 , mDepthStr( 0 ) 57 , mpPropNames( 0 ) 58 , mpResources( 0 ) 59 , mpResInfo( &ioResInfo ) 60 , mbOnlyPropertyNames( true ) 61 , xInputStream( new SerfInputStream() ) 62 { 63 init( inDepth ); 64 } 65 66 void SerfPropFindReqProcImpl::init( const Depth inDepth ) 67 { 68 switch ( inDepth ) 69 { 70 case DAVZERO: 71 mDepthStr = "0"; 72 break; 73 case DAVONE: 74 mDepthStr = "1"; 75 break; 76 case DAVINFINITY: 77 mDepthStr = "infinity"; 78 break; 79 } 80 } 81 82 SerfPropFindReqProcImpl::~SerfPropFindReqProcImpl() 83 { 84 } 85 86 #define PROPFIND_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?><propfind xmlns=\"DAV:\">" 87 #define PROPFIND_TRAILER "</propfind>" 88 89 serf_bucket_t * SerfPropFindReqProcImpl::createSerfRequestBucket( serf_request_t * inSerfRequest ) 90 { 91 serf_bucket_alloc_t* pSerfBucketAlloc = serf_request_get_alloc( inSerfRequest ); 92 93 // body bucket - certain properties OR all properties OR only property names 94 serf_bucket_t* body_bkt = 0; 95 sal_Int32 nDataLen = 0; 96 { 97 // create and fill body bucket with requested properties 98 body_bkt = serf_bucket_aggregate_create( pSerfBucketAlloc ); 99 100 serf_bucket_t* tmp = 0; 101 const int nPropCount = ( !mbOnlyPropertyNames && mpPropNames ) 102 ? mpPropNames->size() 103 : 0; 104 if ( nPropCount > 0 ) 105 { 106 SerfPropName thePropName; 107 for ( int theIndex = 0; theIndex < nPropCount; theIndex ++ ) 108 { 109 // split fullname into namespace and name! 110 DAVProperties::createSerfPropName( (*mpPropNames)[ theIndex ], 111 thePropName ); 112 113 /* <*propname* xmlns="*propns*" /> */ 114 tmp = SERF_BUCKET_SIMPLE_STRING_LEN("<", 1, pSerfBucketAlloc ); 115 serf_bucket_aggregate_append( body_bkt, tmp ); 116 nDataLen += 1; 117 118 tmp = SERF_BUCKET_SIMPLE_STRING( thePropName.name, pSerfBucketAlloc ); 119 serf_bucket_aggregate_append( body_bkt, tmp ); 120 nDataLen += strlen(thePropName.name); 121 122 tmp = SERF_BUCKET_SIMPLE_STRING_LEN( " xmlns=\"", 123 sizeof(" xmlns=\"")-1, 124 pSerfBucketAlloc ); 125 serf_bucket_aggregate_append( body_bkt, tmp ); 126 nDataLen += sizeof(" xmlns=\"")-1; 127 128 tmp = SERF_BUCKET_SIMPLE_STRING( thePropName.nspace, pSerfBucketAlloc ); 129 serf_bucket_aggregate_append( body_bkt, tmp ); 130 nDataLen += strlen(thePropName.nspace); 131 132 tmp = SERF_BUCKET_SIMPLE_STRING_LEN( "\"/>", sizeof("\"/>")-1, 133 pSerfBucketAlloc ); 134 serf_bucket_aggregate_append( body_bkt, tmp ); 135 nDataLen += sizeof("\"/>")-1; 136 } 137 138 tmp = SERF_BUCKET_SIMPLE_STRING_LEN("<prop>", 139 sizeof("<prop>")-1, 140 pSerfBucketAlloc ); 141 serf_bucket_aggregate_prepend(body_bkt, tmp); 142 nDataLen += sizeof("<prop>")-1; 143 144 tmp = SERF_BUCKET_SIMPLE_STRING_LEN("</prop>", 145 sizeof("</prop>")-1, 146 pSerfBucketAlloc ); 147 serf_bucket_aggregate_append(body_bkt, tmp); 148 nDataLen += sizeof("</prop>")-1; 149 } 150 else 151 { 152 if ( mbOnlyPropertyNames ) 153 { 154 tmp = SERF_BUCKET_SIMPLE_STRING_LEN( "<propname/>", 155 sizeof("<propname/>")-1, 156 pSerfBucketAlloc ); 157 nDataLen += sizeof("<propname/>")-1; 158 } 159 else 160 { 161 tmp = SERF_BUCKET_SIMPLE_STRING_LEN( "<allprop/>", 162 sizeof("<allprop/>")-1, 163 pSerfBucketAlloc ); 164 nDataLen += sizeof("<allprop/>")-1; 165 } 166 serf_bucket_aggregate_append( body_bkt, tmp ); 167 } 168 169 tmp = SERF_BUCKET_SIMPLE_STRING_LEN( PROPFIND_HEADER, 170 sizeof(PROPFIND_HEADER)-1, 171 pSerfBucketAlloc ); 172 serf_bucket_aggregate_prepend(body_bkt, tmp); 173 nDataLen += sizeof(PROPFIND_HEADER)-1; 174 175 tmp = SERF_BUCKET_SIMPLE_STRING_LEN(PROPFIND_TRAILER, 176 sizeof(PROPFIND_TRAILER)-1, 177 pSerfBucketAlloc ); 178 serf_bucket_aggregate_append(body_bkt, tmp); 179 nDataLen += sizeof(PROPFIND_TRAILER)-1; 180 } 181 182 // create serf request 183 serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest, 184 "PROPFIND", 185 getPathStr(), 186 body_bkt, 187 serf_request_get_alloc( inSerfRequest ) ); 188 189 // TODO - correct header data 190 // set request header fields 191 serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt ); 192 serf_bucket_headers_setn( hdrs_bkt, "User-Agent", "www.openoffice.org/ucb/" ); 193 serf_bucket_headers_setn( hdrs_bkt, "Accept-Encoding", "gzip"); 194 195 // request specific header fields 196 serf_bucket_headers_setn( hdrs_bkt, "Depth", mDepthStr ); 197 serf_bucket_headers_setn( hdrs_bkt, "Content-Type", "application/xml" ); 198 serf_bucket_headers_setn( hdrs_bkt, "Content-Length", 199 rtl::OUStringToOString( rtl::OUString::valueOf( nDataLen ), RTL_TEXTENCODING_UTF8 ) ); 200 201 return req_bkt; 202 } 203 204 205 bool SerfPropFindReqProcImpl::processSerfResponseBucket( serf_request_t * /*inSerfRequest*/, 206 serf_bucket_t * inSerfResponseBucket, 207 apr_pool_t * /*inAprPool*/, 208 apr_status_t & outStatus ) 209 { 210 const char* data; 211 apr_size_t len; 212 213 while (1) { 214 outStatus = serf_bucket_read(inSerfResponseBucket, 2048, &data, &len); 215 if (SERF_BUCKET_READ_ERROR(outStatus)) 216 { 217 return true; 218 } 219 220 if ( len > 0 ) 221 { 222 xInputStream->AddToStream( data, len ); 223 } 224 225 /* are we done yet? */ 226 if (APR_STATUS_IS_EOF(outStatus)) 227 { 228 if ( mbOnlyPropertyNames ) 229 { 230 const std::vector< DAVResourceInfo > rResInfo( parseWebDAVPropNameResponse( xInputStream.get() ) ); 231 *mpResInfo = rResInfo; 232 } 233 else 234 { 235 const std::vector< DAVResource > rResources( parseWebDAVPropFindResponse( xInputStream.get() ) ); 236 *mpResources = rResources; 237 } 238 239 outStatus = APR_EOF; 240 return true; 241 } 242 243 /* have we drained the response so far? */ 244 if ( APR_STATUS_IS_EAGAIN( outStatus ) ) 245 { 246 return false; 247 } 248 } 249 250 /* NOTREACHED */ 251 return true; 252 } 253 254 } // namespace http_dav_ucp 255