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