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 <rtl/ustring.hxx> 26 #include <DAVProperties.hxx> 27 #include <UCBDeadPropertyValue.hxx> 28 29 #include <SerfPropPatchReqProcImpl.hxx> 30 #include <SerfTypes.hxx> 31 32 namespace http_dav_ucp 33 { 34 35 SerfPropPatchReqProcImpl::SerfPropPatchReqProcImpl( const char* inPath, 36 const std::vector< ProppatchValue > & inProperties ) 37 : SerfRequestProcessorImpl( inPath ) 38 , mpProperties( &inProperties ) 39 { 40 } 41 42 SerfPropPatchReqProcImpl::~SerfPropPatchReqProcImpl() 43 { 44 } 45 46 #define PROPPATCH_HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?><propertyupdate xmlns=\"DAV:\">" 47 #define PROPPATCH_TRAILER "</propertyupdate>" 48 49 serf_bucket_t * SerfPropPatchReqProcImpl::createSerfRequestBucket( serf_request_t * inSerfRequest ) 50 { 51 serf_bucket_alloc_t* pSerfBucketAlloc = serf_request_get_alloc( inSerfRequest ); 52 53 // body bucket 54 serf_bucket_t* body_bkt = 0; 55 rtl::OUString aBodyText; 56 { 57 // create and fill body bucket with properties to be set or removed 58 static const char* OpCodes[2] = { "set", "remove" }; 59 const int nPropCount = ( mpProperties != 0 ) 60 ? mpProperties->size() 61 : 0; 62 if ( nPropCount > 0 ) 63 { 64 // <*operation code*><prop> 65 ProppatchOperation lastOp = (*mpProperties)[ 0 ].operation; 66 aBodyText += rtl::OUString::createFromAscii( "<" ); 67 aBodyText += rtl::OUString::createFromAscii( OpCodes[lastOp] ); 68 aBodyText += rtl::OUString::createFromAscii( "><prop>" ); 69 70 SerfPropName thePropName; 71 for ( int n = 0; n < nPropCount; ++n ) 72 { 73 const ProppatchValue & rProperty = (*mpProperties)[ n ]; 74 // split fullname into namespace and name! 75 DAVProperties::createSerfPropName( rProperty.name, 76 thePropName ); 77 78 if ( rProperty.operation != lastOp ) 79 { 80 // </prop></*last operation code*><*operation code><prop> 81 aBodyText += rtl::OUString::createFromAscii( "</prop></" ); 82 aBodyText += rtl::OUString::createFromAscii( OpCodes[lastOp] ); 83 aBodyText += rtl::OUString::createFromAscii( "><" ); 84 aBodyText += rtl::OUString::createFromAscii( OpCodes[rProperty.operation] ); 85 aBodyText += rtl::OUString::createFromAscii( "><prop>" ); 86 } 87 88 // <*propname* xmlns="*propns*" 89 aBodyText += rtl::OUString::createFromAscii( "<" ); 90 aBodyText += rtl::OUString::createFromAscii( thePropName.name ); 91 aBodyText += rtl::OUString::createFromAscii( " xmlns=\"" ); 92 aBodyText += rtl::OUString::createFromAscii( thePropName.nspace ); 93 aBodyText += rtl::OUString::createFromAscii( "\"" ); 94 95 if ( rProperty.operation == PROPSET ) 96 { 97 // >*property value*</*propname*> 98 aBodyText += rtl::OUString::createFromAscii( ">" ); 99 100 rtl::OUString aStringValue; 101 if ( DAVProperties::isUCBDeadProperty( thePropName ) ) 102 { 103 UCBDeadPropertyValue::toXML( rProperty.value, 104 aStringValue ); 105 } 106 else 107 { 108 rProperty.value >>= aStringValue; 109 } 110 aBodyText += aStringValue; 111 aBodyText += rtl::OUString::createFromAscii( "</" ); 112 aBodyText += rtl::OUString::createFromAscii( thePropName.name ); 113 aBodyText += rtl::OUString::createFromAscii( ">" ); 114 } 115 else 116 { 117 // /> 118 aBodyText += rtl::OUString::createFromAscii( "/>" ); 119 } 120 121 lastOp = rProperty.operation; 122 } 123 124 // </prop></*last operation code*> 125 aBodyText += rtl::OUString::createFromAscii( "</prop></" ); 126 aBodyText += rtl::OUString::createFromAscii( OpCodes[lastOp] ); 127 aBodyText += rtl::OUString::createFromAscii( ">" ); 128 129 // add PropPatch xml header in front 130 aBodyText = rtl::OUString::createFromAscii( PROPPATCH_HEADER ) + aBodyText; 131 132 // add PropPatch xml trailer at end 133 aBodyText += rtl::OUString::createFromAscii( PROPPATCH_TRAILER ); 134 135 body_bkt = SERF_BUCKET_SIMPLE_STRING( rtl::OUStringToOString( aBodyText, RTL_TEXTENCODING_UTF8 ), 136 pSerfBucketAlloc ); 137 if ( useChunkedEncoding() ) 138 { 139 body_bkt = serf_bucket_chunk_create( body_bkt, pSerfBucketAlloc ); 140 } 141 } 142 } 143 144 // create serf request 145 serf_bucket_t *req_bkt = serf_request_bucket_request_create( inSerfRequest, 146 "PROPPATCH", 147 getPathStr(), 148 body_bkt, 149 pSerfBucketAlloc ) ; 150 151 // TODO - correct header data 152 // set request header fields 153 serf_bucket_t* hdrs_bkt = serf_bucket_request_get_headers( req_bkt ); 154 serf_bucket_headers_setn( hdrs_bkt, "User-Agent", "www.openoffice.org/ucb/" ); 155 serf_bucket_headers_setn( hdrs_bkt, "Accept-Encoding", "gzip"); 156 157 // request specific header fields 158 if ( body_bkt != 0 && aBodyText.getLength() > 0 ) 159 { 160 if ( useChunkedEncoding() ) 161 { 162 serf_bucket_headers_setn( hdrs_bkt, "Transfer-Encoding", "chunked"); 163 } 164 serf_bucket_headers_setn( hdrs_bkt, "Content-Type", "application/xml" ); 165 serf_bucket_headers_setn( hdrs_bkt, "Content-Length", 166 rtl::OUStringToOString( rtl::OUString::valueOf( aBodyText.getLength() ), RTL_TEXTENCODING_UTF8 ) ); 167 } 168 169 return req_bkt; 170 } 171 172 void SerfPropPatchReqProcImpl::processChunkOfResponseData( const char* /*data*/, 173 apr_size_t /*len*/ ) 174 { 175 // nothing to do; 176 } 177 178 void SerfPropPatchReqProcImpl::handleEndOfResponseData( serf_bucket_t * /*inSerfResponseBucket*/ ) 179 { 180 // nothing to do; 181 } 182 183 } // namespace http_dav_ucp 184