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