1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski #include "SerfRequestProcessorImpl.hxx"
23*b1cdbd2cSJim Jagielski #include "webdavuseragent.hxx"
24*b1cdbd2cSJim Jagielski 
25*b1cdbd2cSJim Jagielski namespace
26*b1cdbd2cSJim Jagielski {
27*b1cdbd2cSJim Jagielski // Define a magic value that is used by serf to reset chunked
28*b1cdbd2cSJim Jagielski // encoding.  The value definition is not supported by serf, hence the
29*b1cdbd2cSJim Jagielski // definition here.
30*b1cdbd2cSJim Jagielski static const apr_int64_t SERF_UNKNOWN_LENGTH (-1);
31*b1cdbd2cSJim Jagielski }
32*b1cdbd2cSJim Jagielski 
33*b1cdbd2cSJim Jagielski namespace http_dav_ucp
34*b1cdbd2cSJim Jagielski {
35*b1cdbd2cSJim Jagielski 
SerfRequestProcessorImpl(const char * inPath,const DAVRequestHeaders & inRequestHeaders)36*b1cdbd2cSJim Jagielski SerfRequestProcessorImpl::SerfRequestProcessorImpl( const char* inPath,
37*b1cdbd2cSJim Jagielski                                                     const DAVRequestHeaders& inRequestHeaders )
38*b1cdbd2cSJim Jagielski     : mPathStr( inPath )
39*b1cdbd2cSJim Jagielski     , mrRequestHeaders( inRequestHeaders )
40*b1cdbd2cSJim Jagielski     , mbUseChunkedEncoding( false )
41*b1cdbd2cSJim Jagielski {
42*b1cdbd2cSJim Jagielski }
43*b1cdbd2cSJim Jagielski 
~SerfRequestProcessorImpl()44*b1cdbd2cSJim Jagielski SerfRequestProcessorImpl::~SerfRequestProcessorImpl()
45*b1cdbd2cSJim Jagielski {
46*b1cdbd2cSJim Jagielski }
47*b1cdbd2cSJim Jagielski 
getPathStr() const48*b1cdbd2cSJim Jagielski const char* SerfRequestProcessorImpl::getPathStr() const
49*b1cdbd2cSJim Jagielski {
50*b1cdbd2cSJim Jagielski     return mPathStr;
51*b1cdbd2cSJim Jagielski }
52*b1cdbd2cSJim Jagielski 
activateChunkedEncoding()53*b1cdbd2cSJim Jagielski void SerfRequestProcessorImpl::activateChunkedEncoding()
54*b1cdbd2cSJim Jagielski {
55*b1cdbd2cSJim Jagielski     mbUseChunkedEncoding = true;
56*b1cdbd2cSJim Jagielski }
57*b1cdbd2cSJim Jagielski 
useChunkedEncoding() const58*b1cdbd2cSJim Jagielski bool SerfRequestProcessorImpl::useChunkedEncoding() const
59*b1cdbd2cSJim Jagielski {
60*b1cdbd2cSJim Jagielski     return mbUseChunkedEncoding;
61*b1cdbd2cSJim Jagielski }
62*b1cdbd2cSJim Jagielski 
63*b1cdbd2cSJim Jagielski 
handleChunkedEncoding(serf_bucket_t * pRequestBucket,apr_int64_t nLength) const64*b1cdbd2cSJim Jagielski void SerfRequestProcessorImpl::handleChunkedEncoding (
65*b1cdbd2cSJim Jagielski     serf_bucket_t* pRequestBucket,
66*b1cdbd2cSJim Jagielski     apr_int64_t nLength) const
67*b1cdbd2cSJim Jagielski {
68*b1cdbd2cSJim Jagielski     if (pRequestBucket != NULL)
69*b1cdbd2cSJim Jagielski     {
70*b1cdbd2cSJim Jagielski         if (useChunkedEncoding())
71*b1cdbd2cSJim Jagielski         {
72*b1cdbd2cSJim Jagielski             // Activate chunked encoding.
73*b1cdbd2cSJim Jagielski             serf_bucket_request_set_CL(pRequestBucket, SERF_UNKNOWN_LENGTH);
74*b1cdbd2cSJim Jagielski         }
75*b1cdbd2cSJim Jagielski         else
76*b1cdbd2cSJim Jagielski         {
77*b1cdbd2cSJim Jagielski             // Deactivate chunked encoding by setting the length.
78*b1cdbd2cSJim Jagielski             serf_bucket_request_set_CL(pRequestBucket, nLength);
79*b1cdbd2cSJim Jagielski         }
80*b1cdbd2cSJim Jagielski     }
81*b1cdbd2cSJim Jagielski }
82*b1cdbd2cSJim Jagielski 
83*b1cdbd2cSJim Jagielski 
setRequestHeaders(serf_bucket_t * inoutSerfHeaderBucket)84*b1cdbd2cSJim Jagielski void SerfRequestProcessorImpl::setRequestHeaders( serf_bucket_t* inoutSerfHeaderBucket )
85*b1cdbd2cSJim Jagielski {
86*b1cdbd2cSJim Jagielski     bool bHasUserAgent( false );
87*b1cdbd2cSJim Jagielski     DAVRequestHeaders::const_iterator aHeaderIter( mrRequestHeaders.begin() );
88*b1cdbd2cSJim Jagielski     const DAVRequestHeaders::const_iterator aEnd( mrRequestHeaders.end() );
89*b1cdbd2cSJim Jagielski 
90*b1cdbd2cSJim Jagielski     while ( aHeaderIter != aEnd )
91*b1cdbd2cSJim Jagielski     {
92*b1cdbd2cSJim Jagielski         const rtl::OString aHeader = rtl::OUStringToOString( (*aHeaderIter).first,
93*b1cdbd2cSJim Jagielski                                                                RTL_TEXTENCODING_UTF8 );
94*b1cdbd2cSJim Jagielski         const rtl::OString aValue = rtl::OUStringToOString( (*aHeaderIter).second,
95*b1cdbd2cSJim Jagielski                                                             RTL_TEXTENCODING_UTF8 );
96*b1cdbd2cSJim Jagielski 
97*b1cdbd2cSJim Jagielski         OSL_TRACE( "Request Header - \"%s: %s\"", aHeader.getStr(), aValue.getStr() );
98*b1cdbd2cSJim Jagielski         if ( !bHasUserAgent )
99*b1cdbd2cSJim Jagielski             bHasUserAgent = aHeaderIter->first.equalsAsciiL(
100*b1cdbd2cSJim Jagielski                 RTL_CONSTASCII_STRINGPARAM( "User-Agent" ) );
101*b1cdbd2cSJim Jagielski 
102*b1cdbd2cSJim Jagielski         serf_bucket_headers_setc( inoutSerfHeaderBucket,
103*b1cdbd2cSJim Jagielski                                   aHeader.getStr(),
104*b1cdbd2cSJim Jagielski                                   aValue.getStr() );
105*b1cdbd2cSJim Jagielski 
106*b1cdbd2cSJim Jagielski         ++aHeaderIter;
107*b1cdbd2cSJim Jagielski     }
108*b1cdbd2cSJim Jagielski 
109*b1cdbd2cSJim Jagielski     if ( !bHasUserAgent )
110*b1cdbd2cSJim Jagielski     {
111*b1cdbd2cSJim Jagielski         const rtl::OUString &rUserAgent = WebDAVUserAgent::get();
112*b1cdbd2cSJim Jagielski         serf_bucket_headers_set( inoutSerfHeaderBucket,
113*b1cdbd2cSJim Jagielski                                  "User-Agent",
114*b1cdbd2cSJim Jagielski                                  rtl::OUStringToOString( rUserAgent, RTL_TEXTENCODING_UTF8 ).getStr() );
115*b1cdbd2cSJim Jagielski     }
116*b1cdbd2cSJim Jagielski 
117*b1cdbd2cSJim Jagielski     serf_bucket_headers_set( inoutSerfHeaderBucket, "Accept-Encoding", "gzip");
118*b1cdbd2cSJim Jagielski }
119*b1cdbd2cSJim Jagielski 
processSerfResponseBucket(serf_request_t *,serf_bucket_t * inSerfResponseBucket,apr_pool_t *,apr_status_t & outStatus)120*b1cdbd2cSJim Jagielski bool SerfRequestProcessorImpl::processSerfResponseBucket( serf_request_t * /*inSerfRequest*/,
121*b1cdbd2cSJim Jagielski                                                           serf_bucket_t * inSerfResponseBucket,
122*b1cdbd2cSJim Jagielski                                                           apr_pool_t * /*inAprPool*/,
123*b1cdbd2cSJim Jagielski                                                           apr_status_t & outStatus )
124*b1cdbd2cSJim Jagielski {
125*b1cdbd2cSJim Jagielski     const char* data;
126*b1cdbd2cSJim Jagielski     apr_size_t len;
127*b1cdbd2cSJim Jagielski 
128*b1cdbd2cSJim Jagielski     while (1) {
129*b1cdbd2cSJim Jagielski         outStatus = serf_bucket_read(inSerfResponseBucket, 8096, &data, &len);
130*b1cdbd2cSJim Jagielski         if (SERF_BUCKET_READ_ERROR(outStatus))
131*b1cdbd2cSJim Jagielski         {
132*b1cdbd2cSJim Jagielski             return true;
133*b1cdbd2cSJim Jagielski         }
134*b1cdbd2cSJim Jagielski 
135*b1cdbd2cSJim Jagielski         if ( len > 0 )
136*b1cdbd2cSJim Jagielski         {
137*b1cdbd2cSJim Jagielski             processChunkOfResponseData( data, len );
138*b1cdbd2cSJim Jagielski         }
139*b1cdbd2cSJim Jagielski 
140*b1cdbd2cSJim Jagielski         /* are we done yet? */
141*b1cdbd2cSJim Jagielski         if (APR_STATUS_IS_EOF(outStatus))
142*b1cdbd2cSJim Jagielski         {
143*b1cdbd2cSJim Jagielski             handleEndOfResponseData( inSerfResponseBucket );
144*b1cdbd2cSJim Jagielski 
145*b1cdbd2cSJim Jagielski             outStatus = APR_EOF;
146*b1cdbd2cSJim Jagielski             return true;
147*b1cdbd2cSJim Jagielski         }
148*b1cdbd2cSJim Jagielski 
149*b1cdbd2cSJim Jagielski         /* have we drained the response so far? */
150*b1cdbd2cSJim Jagielski         if ( APR_STATUS_IS_EAGAIN( outStatus ) )
151*b1cdbd2cSJim Jagielski         {
152*b1cdbd2cSJim Jagielski             return false;
153*b1cdbd2cSJim Jagielski         }
154*b1cdbd2cSJim Jagielski     }
155*b1cdbd2cSJim Jagielski 
156*b1cdbd2cSJim Jagielski     /* NOTREACHED */
157*b1cdbd2cSJim Jagielski     return true;
158*b1cdbd2cSJim Jagielski }
159*b1cdbd2cSJim Jagielski 
160*b1cdbd2cSJim Jagielski } // namespace http_dav_ucp
161*b1cdbd2cSJim Jagielski 
162