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 #include "SerfRequestProcessorImpl.hxx" 23 #include "webdavuseragent.hxx" 24 25 namespace 26 { 27 // Define a magic value that is used by serf to reset chunked 28 // encoding. The value definition is not supported by serf, hence the 29 // definition here. 30 static const apr_int64_t SERF_UNKNOWN_LENGTH (-1); 31 } 32 33 namespace http_dav_ucp 34 { 35 36 SerfRequestProcessorImpl::SerfRequestProcessorImpl( const char* inPath, 37 const DAVRequestHeaders& inRequestHeaders ) 38 : mPathStr( inPath ) 39 , mrRequestHeaders( inRequestHeaders ) 40 , mbUseChunkedEncoding( false ) 41 { 42 } 43 44 SerfRequestProcessorImpl::~SerfRequestProcessorImpl() 45 { 46 } 47 48 const char* SerfRequestProcessorImpl::getPathStr() const 49 { 50 return mPathStr; 51 } 52 53 void SerfRequestProcessorImpl::activateChunkedEncoding() 54 { 55 mbUseChunkedEncoding = true; 56 } 57 58 bool SerfRequestProcessorImpl::useChunkedEncoding() const 59 { 60 return mbUseChunkedEncoding; 61 } 62 63 64 void SerfRequestProcessorImpl::handleChunkedEncoding ( 65 serf_bucket_t* pRequestBucket, 66 apr_int64_t nLength) const 67 { 68 if (pRequestBucket != NULL) 69 { 70 if (useChunkedEncoding()) 71 { 72 // Activate chunked encoding. 73 serf_bucket_request_set_CL(pRequestBucket, SERF_UNKNOWN_LENGTH); 74 } 75 else 76 { 77 // Deactivate chunked encoding by setting the length. 78 serf_bucket_request_set_CL(pRequestBucket, nLength); 79 } 80 } 81 } 82 83 84 void SerfRequestProcessorImpl::setRequestHeaders( serf_bucket_t* inoutSerfHeaderBucket ) 85 { 86 bool bHasUserAgent( false ); 87 DAVRequestHeaders::const_iterator aHeaderIter( mrRequestHeaders.begin() ); 88 const DAVRequestHeaders::const_iterator aEnd( mrRequestHeaders.end() ); 89 90 while ( aHeaderIter != aEnd ) 91 { 92 const rtl::OString aHeader = rtl::OUStringToOString( (*aHeaderIter).first, 93 RTL_TEXTENCODING_UTF8 ); 94 const rtl::OString aValue = rtl::OUStringToOString( (*aHeaderIter).second, 95 RTL_TEXTENCODING_UTF8 ); 96 97 OSL_TRACE( "Request Header - \"%s: %s\"", aHeader.getStr(), aValue.getStr() ); 98 if ( !bHasUserAgent ) 99 bHasUserAgent = aHeaderIter->first.equalsAsciiL( 100 RTL_CONSTASCII_STRINGPARAM( "User-Agent" ) ); 101 102 serf_bucket_headers_setc( inoutSerfHeaderBucket, 103 aHeader.getStr(), 104 aValue.getStr() ); 105 106 ++aHeaderIter; 107 } 108 109 if ( !bHasUserAgent ) 110 { 111 const rtl::OUString &rUserAgent = WebDAVUserAgent::get(); 112 serf_bucket_headers_set( inoutSerfHeaderBucket, 113 "User-Agent", 114 rtl::OUStringToOString( rUserAgent, RTL_TEXTENCODING_UTF8 ).getStr() ); 115 } 116 117 serf_bucket_headers_set( inoutSerfHeaderBucket, "Accept-Encoding", "gzip"); 118 } 119 120 bool SerfRequestProcessorImpl::processSerfResponseBucket( serf_request_t * /*inSerfRequest*/, 121 serf_bucket_t * inSerfResponseBucket, 122 apr_pool_t * /*inAprPool*/, 123 apr_status_t & outStatus ) 124 { 125 const char* data; 126 apr_size_t len; 127 128 while (1) { 129 outStatus = serf_bucket_read(inSerfResponseBucket, 8096, &data, &len); 130 if (SERF_BUCKET_READ_ERROR(outStatus)) 131 { 132 return true; 133 } 134 135 if ( len > 0 ) 136 { 137 processChunkOfResponseData( data, len ); 138 } 139 140 /* are we done yet? */ 141 if (APR_STATUS_IS_EOF(outStatus)) 142 { 143 handleEndOfResponseData( inSerfResponseBucket ); 144 145 outStatus = APR_EOF; 146 return true; 147 } 148 149 /* have we drained the response so far? */ 150 if ( APR_STATUS_IS_EAGAIN( outStatus ) ) 151 { 152 return false; 153 } 154 } 155 156 /* NOTREACHED */ 157 return true; 158 } 159 160 } // namespace http_dav_ucp 161 162