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 #include <rtl/ustrbuf.hxx> 32 33 34 using namespace com::sun::star; 35 36 namespace http_dav_ucp 37 { 38 39 SerfPropFindReqProcImpl::SerfPropFindReqProcImpl( const char* inPath, 40 const DAVRequestHeaders& inRequestHeaders, 41 const Depth inDepth, 42 const std::vector< ::rtl::OUString > & inPropNames, 43 std::vector< DAVResource > & ioResources ) 44 : SerfRequestProcessorImpl( inPath, inRequestHeaders ) 45 , mDepthStr( 0 ) 46 , mpPropNames( &inPropNames ) 47 , mpResources( &ioResources ) 48 , mpResInfo( 0 ) 49 , mbOnlyPropertyNames( false ) 50 , xInputStream( new SerfInputStream() ) 51 { 52 init( inDepth ); 53 } 54 55 SerfPropFindReqProcImpl::SerfPropFindReqProcImpl( const char* inPath, 56 const DAVRequestHeaders& inRequestHeaders, 57 const Depth inDepth, 58 std::vector< DAVResourceInfo > & ioResInfo ) 59 : SerfRequestProcessorImpl( inPath, inRequestHeaders ) 60 , mDepthStr( 0 ) 61 , mpPropNames( 0 ) 62 , mpResources( 0 ) 63 , mpResInfo( &ioResInfo ) 64 , mbOnlyPropertyNames( true ) 65 , xInputStream( new SerfInputStream() ) 66 { 67 init( inDepth ); 68 } 69 70 void SerfPropFindReqProcImpl::init( const Depth inDepth ) 71 { 72 switch ( inDepth ) 73 { 74 case DAVZERO: 75 mDepthStr = "0"; 76 break; 77 case DAVONE: 78 mDepthStr = "1"; 79 break; 80 case DAVINFINITY: 81 mDepthStr = "infinity"; 82 break; 83 } 84 } 85 86 SerfPropFindReqProcImpl::~SerfPropFindReqProcImpl() 87 { 88 } 89 90 #define PROPFIND_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?><propfind xmlns=\"DAV:\">" 91 #define PROPFIND_TRAILER "</propfind>" 92 93 serf_bucket_t * SerfPropFindReqProcImpl::createSerfRequestBucket( serf_request_t * inSerfRequest ) 94 { 95 serf_bucket_alloc_t* pSerfBucketAlloc = serf_request_get_alloc( inSerfRequest ); 96 97 // body bucket - certain properties OR all properties OR only property names 98 serf_bucket_t* body_bkt = 0; 99 rtl::OString aBodyText; 100 { 101 // TODO is it really needed a Unicode string buffer? 102 // All properties and property names aren't supposed to be ASCII? 103 rtl::OUStringBuffer aBuffer; 104 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( PROPFIND_HEADER )); 105 106 // create and fill body bucket with requested properties 107 const int nPropCount = ( !mbOnlyPropertyNames && mpPropNames ) 108 ? mpPropNames->size() 109 : 0; 110 if ( nPropCount > 0 ) 111 { 112 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "<prop>" ) ); 113 SerfPropName thePropName; 114 for ( int theIndex = 0; theIndex < nPropCount; theIndex ++ ) 115 { 116 // split fullname into namespace and name! 117 DAVProperties::createSerfPropName( (*mpPropNames)[ theIndex ], 118 thePropName ); 119 120 /* <*propname* xmlns="*propns*" /> */ 121 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "<" )); 122 aBuffer.appendAscii( thePropName.name ); 123 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " xmlnx=\"" )); 124 aBuffer.appendAscii( thePropName.nspace ); 125 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "\"/>" )); 126 } 127 128 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "</prop>" )); 129 } 130 else 131 { 132 if ( mbOnlyPropertyNames ) 133 { 134 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "<propname/>" )); 135 } 136 else 137 { 138 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( "<allprop/>" )); 139 } 140 } 141 142 aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( PROPFIND_TRAILER )); 143 aBodyText = rtl::OUStringToOString( aBuffer.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ); 144 body_bkt = serf_bucket_simple_copy_create( aBodyText.getStr(), 145 aBodyText.getLength(), 146 pSerfBucketAlloc ); 147 } 148 149 // create serf request 150 serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest, 151 "PROPFIND", 152 getPathStr(), 153 body_bkt, 154 pSerfBucketAlloc ); 155 handleChunkedEncoding(req_bkt, aBodyText.getLength()); 156 157 // set request header fields 158 serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt ); 159 if (hdrs_bkt != NULL) 160 { 161 // general header fields provided by caller 162 setRequestHeaders( hdrs_bkt ); 163 164 // request specific header fields 165 serf_bucket_headers_set( hdrs_bkt, "Depth", mDepthStr ); 166 if (hdrs_bkt!=NULL && body_bkt != 0 && aBodyText.getLength() > 0 ) 167 { 168 serf_bucket_headers_set( hdrs_bkt, "Content-Type", "application/xml" ); 169 } 170 } 171 else 172 { 173 OSL_ASSERT("Headers Bucket missing"); 174 } 175 176 return req_bkt; 177 } 178 179 void SerfPropFindReqProcImpl::processChunkOfResponseData( const char* data, 180 apr_size_t len ) 181 { 182 if ( xInputStream.is() ) 183 { 184 xInputStream->AddToStream( data, len ); 185 } 186 } 187 188 void SerfPropFindReqProcImpl::handleEndOfResponseData( serf_bucket_t * /*inSerfResponseBucket*/ ) 189 { 190 if ( mbOnlyPropertyNames ) 191 { 192 const std::vector< DAVResourceInfo > rResInfo( parseWebDAVPropNameResponse( xInputStream.get() ) ); 193 *mpResInfo = rResInfo; 194 } 195 else 196 { 197 const std::vector< DAVResource > rResources( parseWebDAVPropFindResponse( xInputStream.get() ) ); 198 *mpResources = rResources; 199 } 200 } 201 202 } // namespace http_dav_ucp 203