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 rtl::OUString aBodyText; 96 { 97 // create and fill body bucket with requested properties 98 const int nPropCount = ( !mbOnlyPropertyNames && mpPropNames ) 99 ? mpPropNames->size() 100 : 0; 101 if ( nPropCount > 0 ) 102 { 103 SerfPropName thePropName; 104 for ( int theIndex = 0; theIndex < nPropCount; theIndex ++ ) 105 { 106 // split fullname into namespace and name! 107 DAVProperties::createSerfPropName( (*mpPropNames)[ theIndex ], 108 thePropName ); 109 110 /* <*propname* xmlns="*propns*" /> */ 111 aBodyText += rtl::OUString::createFromAscii( "<" ); 112 aBodyText += rtl::OUString::createFromAscii( thePropName.name ); 113 aBodyText += rtl::OUString::createFromAscii( " xmlnx=\"" ); 114 aBodyText += rtl::OUString::createFromAscii( thePropName.nspace ); 115 aBodyText += rtl::OUString::createFromAscii( "\"/>" ); 116 } 117 118 aBodyText = rtl::OUString::createFromAscii( "<prop>" ) + 119 aBodyText + 120 rtl::OUString::createFromAscii( "</prop>" ); 121 } 122 else 123 { 124 if ( mbOnlyPropertyNames ) 125 { 126 aBodyText = rtl::OUString::createFromAscii( "<propname/>" ); 127 } 128 else 129 { 130 aBodyText = rtl::OUString::createFromAscii( "<allprop/>" ); 131 } 132 } 133 134 aBodyText = rtl::OUString::createFromAscii( PROPFIND_HEADER ) + 135 aBodyText + 136 rtl::OUString::createFromAscii( PROPFIND_TRAILER ); 137 body_bkt = SERF_BUCKET_SIMPLE_STRING( rtl::OUStringToOString( aBodyText, RTL_TEXTENCODING_UTF8 ), 138 pSerfBucketAlloc ); 139 } 140 141 // create serf request 142 serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest, 143 "PROPFIND", 144 getPathStr(), 145 body_bkt, 146 serf_request_get_alloc( inSerfRequest ) ); 147 148 // TODO - correct header data 149 // set request header fields 150 serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt ); 151 serf_bucket_headers_setn( hdrs_bkt, "User-Agent", "www.openoffice.org/ucb/" ); 152 serf_bucket_headers_setn( hdrs_bkt, "Accept-Encoding", "gzip"); 153 154 // request specific header fields 155 // request specific header fields 156 serf_bucket_headers_setn( hdrs_bkt, "Depth", mDepthStr ); 157 if ( body_bkt != 0 && aBodyText.getLength() > 0 ) 158 { 159 serf_bucket_headers_setn( hdrs_bkt, "Content-Type", "application/xml" ); 160 serf_bucket_headers_setn( hdrs_bkt, "Content-Length", 161 rtl::OUStringToOString( rtl::OUString::valueOf( aBodyText.getLength() ), RTL_TEXTENCODING_UTF8 ) ); 162 } 163 164 return req_bkt; 165 } 166 167 168 bool SerfPropFindReqProcImpl::processSerfResponseBucket( serf_request_t * /*inSerfRequest*/, 169 serf_bucket_t * inSerfResponseBucket, 170 apr_pool_t * /*inAprPool*/, 171 apr_status_t & outStatus ) 172 { 173 const char* data; 174 apr_size_t len; 175 176 while (1) { 177 outStatus = serf_bucket_read(inSerfResponseBucket, 2048, &data, &len); 178 if (SERF_BUCKET_READ_ERROR(outStatus)) 179 { 180 return true; 181 } 182 183 if ( len > 0 ) 184 { 185 xInputStream->AddToStream( data, len ); 186 } 187 188 /* are we done yet? */ 189 if (APR_STATUS_IS_EOF(outStatus)) 190 { 191 if ( mbOnlyPropertyNames ) 192 { 193 const std::vector< DAVResourceInfo > rResInfo( parseWebDAVPropNameResponse( xInputStream.get() ) ); 194 *mpResInfo = rResInfo; 195 } 196 else 197 { 198 const std::vector< DAVResource > rResources( parseWebDAVPropFindResponse( xInputStream.get() ) ); 199 *mpResources = rResources; 200 } 201 202 outStatus = APR_EOF; 203 return true; 204 } 205 206 /* have we drained the response so far? */ 207 if ( APR_STATUS_IS_EAGAIN( outStatus ) ) 208 { 209 return false; 210 } 211 } 212 213 /* NOTREACHED */ 214 return true; 215 } 216 217 } // namespace http_dav_ucp 218