1*51ba086bSDamjan Jovanovic /************************************************************** 2*51ba086bSDamjan Jovanovic * 3*51ba086bSDamjan Jovanovic * Licensed to the Apache Software Foundation (ASF) under one 4*51ba086bSDamjan Jovanovic * or more contributor license agreements. See the NOTICE file 5*51ba086bSDamjan Jovanovic * distributed with this work for additional information 6*51ba086bSDamjan Jovanovic * regarding copyright ownership. The ASF licenses this file 7*51ba086bSDamjan Jovanovic * to you under the Apache License, Version 2.0 (the 8*51ba086bSDamjan Jovanovic * "License"); you may not use this file except in compliance 9*51ba086bSDamjan Jovanovic * with the License. You may obtain a copy of the License at 10*51ba086bSDamjan Jovanovic * 11*51ba086bSDamjan Jovanovic * http://www.apache.org/licenses/LICENSE-2.0 12*51ba086bSDamjan Jovanovic * 13*51ba086bSDamjan Jovanovic * Unless required by applicable law or agreed to in writing, 14*51ba086bSDamjan Jovanovic * software distributed under the License is distributed on an 15*51ba086bSDamjan Jovanovic * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*51ba086bSDamjan Jovanovic * KIND, either express or implied. See the License for the 17*51ba086bSDamjan Jovanovic * specific language governing permissions and limitations 18*51ba086bSDamjan Jovanovic * under the License. 19*51ba086bSDamjan Jovanovic * 20*51ba086bSDamjan Jovanovic *************************************************************/ 21*51ba086bSDamjan Jovanovic 22*51ba086bSDamjan Jovanovic 23*51ba086bSDamjan Jovanovic 24*51ba086bSDamjan Jovanovic // MARKER(update_precomp.py): autogen include statement, do not remove 25*51ba086bSDamjan Jovanovic #include "precompiled_webdav.hxx" 26*51ba086bSDamjan Jovanovic 27*51ba086bSDamjan Jovanovic #include "CurlRequest.hxx" 28*51ba086bSDamjan Jovanovic 29*51ba086bSDamjan Jovanovic using namespace ::com::sun::star; 30*51ba086bSDamjan Jovanovic using namespace http_dav_ucp; 31*51ba086bSDamjan Jovanovic 32*51ba086bSDamjan Jovanovic CurlRequest::CurlRequest( CURL *curl ) 33*51ba086bSDamjan Jovanovic : curl( curl ) 34*51ba086bSDamjan Jovanovic , curlUrl( NULL ) 35*51ba086bSDamjan Jovanovic , requestHeaders( NULL ) 36*51ba086bSDamjan Jovanovic , requestBody( NULL ) 37*51ba086bSDamjan Jovanovic , requestBodyOffset( 0 ) 38*51ba086bSDamjan Jovanovic , requestBodySize( 0 ) 39*51ba086bSDamjan Jovanovic , useChunkedEncoding( false ) 40*51ba086bSDamjan Jovanovic , provideCredentialsCallback( NULL ) 41*51ba086bSDamjan Jovanovic , provideCredentialsUserdata( NULL ) 42*51ba086bSDamjan Jovanovic , statusCode( 0 ) 43*51ba086bSDamjan Jovanovic , responseBodyInputStream( new CurlInputStream() ) 44*51ba086bSDamjan Jovanovic { 45*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HEADERFUNCTION, Curl_HeaderReceived ); 46*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HEADERDATA, this ); 47*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, Curl_MoreBodyReceived ); 48*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_WRITEDATA, this ); 49*51ba086bSDamjan Jovanovic } 50*51ba086bSDamjan Jovanovic 51*51ba086bSDamjan Jovanovic CurlRequest::~CurlRequest() 52*51ba086bSDamjan Jovanovic { 53*51ba086bSDamjan Jovanovic if ( curlUrl != NULL ) 54*51ba086bSDamjan Jovanovic curl_url_cleanup( curlUrl ); 55*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CURLU, NULL ); 56*51ba086bSDamjan Jovanovic 57*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPHEADER, NULL ); 58*51ba086bSDamjan Jovanovic if ( requestHeaders != NULL ) 59*51ba086bSDamjan Jovanovic curl_slist_free_all( requestHeaders ); 60*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_READFUNCTION, NULL ); 61*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_READDATA, NULL ); 62*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_INFILESIZE, -1 ); 63*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_SEEKFUNCTION, NULL ); 64*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_SEEKDATA, NULL ); 65*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HEADERFUNCTION, NULL ); 66*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HEADERDATA, NULL ); 67*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, NULL ); 68*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, NULL ); 69*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_WRITEDATA, NULL ); 70*51ba086bSDamjan Jovanovic } 71*51ba086bSDamjan Jovanovic 72*51ba086bSDamjan Jovanovic void CurlRequest::addHeader( const rtl::OString &name, const rtl::OString &value) throw (DAVException) 73*51ba086bSDamjan Jovanovic { 74*51ba086bSDamjan Jovanovic rtl::OString line = name + ": " + value; 75*51ba086bSDamjan Jovanovic struct curl_slist *appended = curl_slist_append( requestHeaders, line.getStr() ); 76*51ba086bSDamjan Jovanovic if ( appended != NULL ) 77*51ba086bSDamjan Jovanovic { 78*51ba086bSDamjan Jovanovic requestHeaders = appended; 79*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPHEADER, requestHeaders ); 80*51ba086bSDamjan Jovanovic } 81*51ba086bSDamjan Jovanovic else 82*51ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii( "Out of memory" ) ); 83*51ba086bSDamjan Jovanovic } 84*51ba086bSDamjan Jovanovic 85*51ba086bSDamjan Jovanovic void CurlRequest::setRequestBody( const char *body, size_t size ) 86*51ba086bSDamjan Jovanovic { 87*51ba086bSDamjan Jovanovic requestBody = body; 88*51ba086bSDamjan Jovanovic requestBodyOffset = 0; 89*51ba086bSDamjan Jovanovic requestBodySize = size; 90*51ba086bSDamjan Jovanovic 91*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_READFUNCTION, Curl_SendMoreBody ); 92*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_READDATA, this ); 93*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_SEEKFUNCTION, Curl_SeekCallback ); 94*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_SEEKDATA, this ); 95*51ba086bSDamjan Jovanovic if ( useChunkedEncoding ) 96*51ba086bSDamjan Jovanovic addHeader( "Transfer-Encoding", "chunked" ); 97*51ba086bSDamjan Jovanovic else 98*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)size ); 99*51ba086bSDamjan Jovanovic } 100*51ba086bSDamjan Jovanovic 101*51ba086bSDamjan Jovanovic int CurlRequest::Curl_SeekCallback( void *userdata, curl_off_t offset, int origin ) 102*51ba086bSDamjan Jovanovic { 103*51ba086bSDamjan Jovanovic CurlRequest *request = static_cast< CurlRequest* >( userdata ); 104*51ba086bSDamjan Jovanovic if ( origin == SEEK_SET ) 105*51ba086bSDamjan Jovanovic request->requestBodyOffset = (size_t) offset; 106*51ba086bSDamjan Jovanovic else if ( origin == SEEK_CUR ) 107*51ba086bSDamjan Jovanovic request->requestBodyOffset += (size_t) offset; 108*51ba086bSDamjan Jovanovic else if ( origin == SEEK_END ) 109*51ba086bSDamjan Jovanovic request->requestBodyOffset += (size_t) ((curl_off_t)request->requestBodySize + offset); 110*51ba086bSDamjan Jovanovic else 111*51ba086bSDamjan Jovanovic return CURL_SEEKFUNC_CANTSEEK; 112*51ba086bSDamjan Jovanovic if ( request->requestBodyOffset > request->requestBodySize ) 113*51ba086bSDamjan Jovanovic request->requestBodyOffset = request->requestBodySize; 114*51ba086bSDamjan Jovanovic return CURL_SEEKFUNC_OK; 115*51ba086bSDamjan Jovanovic } 116*51ba086bSDamjan Jovanovic 117*51ba086bSDamjan Jovanovic size_t CurlRequest::Curl_SendMoreBody( char *buffer, size_t size, size_t nitems, void *userdata ) 118*51ba086bSDamjan Jovanovic { 119*51ba086bSDamjan Jovanovic CurlRequest *request = static_cast< CurlRequest* >( userdata ); 120*51ba086bSDamjan Jovanovic OSL_TRACE("Curl_SendMoreBody"); 121*51ba086bSDamjan Jovanovic return request->curlSendMoreBody( buffer, nitems ); 122*51ba086bSDamjan Jovanovic } 123*51ba086bSDamjan Jovanovic 124*51ba086bSDamjan Jovanovic size_t CurlRequest::curlSendMoreBody( char *buffer, size_t len ) 125*51ba086bSDamjan Jovanovic { 126*51ba086bSDamjan Jovanovic size_t bytesToSend = requestBodySize - requestBodyOffset; 127*51ba086bSDamjan Jovanovic if ( bytesToSend > len ) 128*51ba086bSDamjan Jovanovic bytesToSend = len; 129*51ba086bSDamjan Jovanovic memcpy( buffer, requestBody, bytesToSend ); 130*51ba086bSDamjan Jovanovic requestBodyOffset += bytesToSend; 131*51ba086bSDamjan Jovanovic return bytesToSend; 132*51ba086bSDamjan Jovanovic } 133*51ba086bSDamjan Jovanovic 134*51ba086bSDamjan Jovanovic void CurlRequest::setProvideCredentialsCallback( bool (*callback)(long statusCode, void *userdata) throw (DAVException), void *userdata ) 135*51ba086bSDamjan Jovanovic { 136*51ba086bSDamjan Jovanovic provideCredentialsCallback = callback; 137*51ba086bSDamjan Jovanovic provideCredentialsUserdata = userdata; 138*51ba086bSDamjan Jovanovic } 139*51ba086bSDamjan Jovanovic 140*51ba086bSDamjan Jovanovic void CurlRequest::setURI( CurlUri uri, rtl::OUString path ) throw (DAVException) 141*51ba086bSDamjan Jovanovic { 142*51ba086bSDamjan Jovanovic if ( curlUrl != NULL ) 143*51ba086bSDamjan Jovanovic { 144*51ba086bSDamjan Jovanovic curl_url_cleanup( curlUrl ); 145*51ba086bSDamjan Jovanovic curlUrl = NULL; 146*51ba086bSDamjan Jovanovic } 147*51ba086bSDamjan Jovanovic 148*51ba086bSDamjan Jovanovic curlUrl = curl_url(); 149*51ba086bSDamjan Jovanovic if ( curlUrl == NULL ) 150*51ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii( "Out of memory" ) ); 151*51ba086bSDamjan Jovanovic 152*51ba086bSDamjan Jovanovic if ( CurlUri( path ).GetHost().isEmpty() ) 153*51ba086bSDamjan Jovanovic { 154*51ba086bSDamjan Jovanovic // "path" is really a path, not a URI 155*51ba086bSDamjan Jovanovic curl_url_set( curlUrl, CURLUPART_URL, rtl::OUStringToOString( uri.GetURI(), RTL_TEXTENCODING_UTF8 ).getStr(), 0 ); 156*51ba086bSDamjan Jovanovic curl_url_set( curlUrl, CURLUPART_PATH, rtl::OUStringToOString( path, RTL_TEXTENCODING_UTF8 ).getStr(), 0 ); 157*51ba086bSDamjan Jovanovic } 158*51ba086bSDamjan Jovanovic else 159*51ba086bSDamjan Jovanovic { 160*51ba086bSDamjan Jovanovic // The "path" is a full URI 161*51ba086bSDamjan Jovanovic curl_url_set( curlUrl, CURLUPART_URL, rtl::OUStringToOString( path, RTL_TEXTENCODING_UTF8 ).getStr(), 0 ); 162*51ba086bSDamjan Jovanovic } 163*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CURLU, curlUrl ); 164*51ba086bSDamjan Jovanovic } 165*51ba086bSDamjan Jovanovic 166*51ba086bSDamjan Jovanovic CURLcode CurlRequest::copy( CurlUri uri, rtl::OUString path ) throw(DAVException) 167*51ba086bSDamjan Jovanovic { 168*51ba086bSDamjan Jovanovic setURI( uri, path ); 169*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 170*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "COPY" ); 171*51ba086bSDamjan Jovanovic return perform(); 172*51ba086bSDamjan Jovanovic } 173*51ba086bSDamjan Jovanovic 174*51ba086bSDamjan Jovanovic CURLcode CurlRequest::delete_( CurlUri uri, rtl::OUString path ) throw (DAVException) 175*51ba086bSDamjan Jovanovic { 176*51ba086bSDamjan Jovanovic setURI( uri, path ); 177*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 178*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "DELETE" ); 179*51ba086bSDamjan Jovanovic return perform(); 180*51ba086bSDamjan Jovanovic } 181*51ba086bSDamjan Jovanovic 182*51ba086bSDamjan Jovanovic CURLcode CurlRequest::get( CurlUri uri, rtl::OUString path ) throw(DAVException) 183*51ba086bSDamjan Jovanovic { 184*51ba086bSDamjan Jovanovic setURI( uri, path ); 185*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 186*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "GET" ); 187*51ba086bSDamjan Jovanovic return perform(); 188*51ba086bSDamjan Jovanovic } 189*51ba086bSDamjan Jovanovic 190*51ba086bSDamjan Jovanovic CURLcode CurlRequest::head( CurlUri uri, rtl::OUString path ) throw (DAVException) 191*51ba086bSDamjan Jovanovic { 192*51ba086bSDamjan Jovanovic setURI( uri, path ); 193*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_NOBODY, 1L ); 194*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "HEAD" ); 195*51ba086bSDamjan Jovanovic return perform(); 196*51ba086bSDamjan Jovanovic } 197*51ba086bSDamjan Jovanovic 198*51ba086bSDamjan Jovanovic CURLcode CurlRequest::lock( CurlUri uri, rtl::OUString path ) throw (DAVException) 199*51ba086bSDamjan Jovanovic { 200*51ba086bSDamjan Jovanovic setURI( uri, path ); 201*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 202*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "LOCK" ); 203*51ba086bSDamjan Jovanovic return perform(); 204*51ba086bSDamjan Jovanovic } 205*51ba086bSDamjan Jovanovic 206*51ba086bSDamjan Jovanovic CURLcode CurlRequest::mkcol( CurlUri uri, rtl::OUString path ) throw (DAVException) 207*51ba086bSDamjan Jovanovic { 208*51ba086bSDamjan Jovanovic setURI( uri, path ); 209*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 210*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "MKCOL" ); 211*51ba086bSDamjan Jovanovic return perform(); 212*51ba086bSDamjan Jovanovic } 213*51ba086bSDamjan Jovanovic 214*51ba086bSDamjan Jovanovic CURLcode CurlRequest::move( CurlUri uri, rtl::OUString path ) throw (DAVException) 215*51ba086bSDamjan Jovanovic { 216*51ba086bSDamjan Jovanovic setURI( uri, path ); 217*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 218*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "MOVE" ); 219*51ba086bSDamjan Jovanovic return perform(); 220*51ba086bSDamjan Jovanovic } 221*51ba086bSDamjan Jovanovic 222*51ba086bSDamjan Jovanovic CURLcode CurlRequest::post( CurlUri uri, rtl::OUString path ) throw (DAVException) 223*51ba086bSDamjan Jovanovic { 224*51ba086bSDamjan Jovanovic setURI( uri, path ); 225*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 226*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "POST" ); 227*51ba086bSDamjan Jovanovic return perform(); 228*51ba086bSDamjan Jovanovic } 229*51ba086bSDamjan Jovanovic 230*51ba086bSDamjan Jovanovic CURLcode CurlRequest::propfind( CurlUri uri, rtl::OUString path ) throw (DAVException) 231*51ba086bSDamjan Jovanovic { 232*51ba086bSDamjan Jovanovic setURI( uri, path ); 233*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 234*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "PROPFIND" ); 235*51ba086bSDamjan Jovanovic return perform(); 236*51ba086bSDamjan Jovanovic } 237*51ba086bSDamjan Jovanovic 238*51ba086bSDamjan Jovanovic CURLcode CurlRequest::proppatch( CurlUri uri, rtl::OUString path ) throw (DAVException) 239*51ba086bSDamjan Jovanovic { 240*51ba086bSDamjan Jovanovic setURI( uri, path ); 241*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 242*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "PROPPATCH" ); 243*51ba086bSDamjan Jovanovic return perform(); 244*51ba086bSDamjan Jovanovic } 245*51ba086bSDamjan Jovanovic 246*51ba086bSDamjan Jovanovic CURLcode CurlRequest::put( CurlUri uri, rtl::OUString path ) throw (DAVException) 247*51ba086bSDamjan Jovanovic { 248*51ba086bSDamjan Jovanovic setURI( uri, path ); 249*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 250*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "PUT" ); 251*51ba086bSDamjan Jovanovic return perform(); 252*51ba086bSDamjan Jovanovic } 253*51ba086bSDamjan Jovanovic 254*51ba086bSDamjan Jovanovic CURLcode CurlRequest::unlock( CurlUri uri, rtl::OUString path ) throw (DAVException) 255*51ba086bSDamjan Jovanovic { 256*51ba086bSDamjan Jovanovic setURI( uri, path ); 257*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 258*51ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "UNLOCK" ); 259*51ba086bSDamjan Jovanovic return perform(); 260*51ba086bSDamjan Jovanovic } 261*51ba086bSDamjan Jovanovic 262*51ba086bSDamjan Jovanovic CURLcode CurlRequest::perform() throw (DAVException) 263*51ba086bSDamjan Jovanovic { 264*51ba086bSDamjan Jovanovic CURLcode rc = curl_easy_perform( curl ); 265*51ba086bSDamjan Jovanovic long statusCode = 0; 266*51ba086bSDamjan Jovanovic curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &statusCode ); 267*51ba086bSDamjan Jovanovic if ( ( statusCode == 401 || statusCode == 407 ) && provideCredentialsCallback != NULL ) 268*51ba086bSDamjan Jovanovic { 269*51ba086bSDamjan Jovanovic bool haveCredentials = provideCredentialsCallback( statusCode, provideCredentialsUserdata ); 270*51ba086bSDamjan Jovanovic if ( haveCredentials ) 271*51ba086bSDamjan Jovanovic { 272*51ba086bSDamjan Jovanovic // rewind body: 273*51ba086bSDamjan Jovanovic requestBodyOffset = 0; 274*51ba086bSDamjan Jovanovic // retry with credentials: 275*51ba086bSDamjan Jovanovic rc = curl_easy_perform( curl ); 276*51ba086bSDamjan Jovanovic // If this was to authenticate with the proxy, we may need to authenticate 277*51ba086bSDamjan Jovanovic // with the destination host too: 278*51ba086bSDamjan Jovanovic if ( statusCode == 407 ) 279*51ba086bSDamjan Jovanovic { 280*51ba086bSDamjan Jovanovic curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &statusCode ); 281*51ba086bSDamjan Jovanovic if ( statusCode == 401 && provideCredentialsCallback != NULL ) 282*51ba086bSDamjan Jovanovic { 283*51ba086bSDamjan Jovanovic haveCredentials = provideCredentialsCallback( statusCode, provideCredentialsUserdata ); 284*51ba086bSDamjan Jovanovic if ( haveCredentials ) 285*51ba086bSDamjan Jovanovic { 286*51ba086bSDamjan Jovanovic // rewind body: 287*51ba086bSDamjan Jovanovic requestBodyOffset = 0; 288*51ba086bSDamjan Jovanovic // retry with credentials: 289*51ba086bSDamjan Jovanovic rc = curl_easy_perform( curl ); 290*51ba086bSDamjan Jovanovic } 291*51ba086bSDamjan Jovanovic } 292*51ba086bSDamjan Jovanovic } 293*51ba086bSDamjan Jovanovic } 294*51ba086bSDamjan Jovanovic } 295*51ba086bSDamjan Jovanovic return rc; 296*51ba086bSDamjan Jovanovic } 297*51ba086bSDamjan Jovanovic 298*51ba086bSDamjan Jovanovic size_t CurlRequest::Curl_HeaderReceived( char *buffer, size_t size, size_t nitems, void *userdata ) 299*51ba086bSDamjan Jovanovic { 300*51ba086bSDamjan Jovanovic CurlRequest *request = static_cast< CurlRequest* >( userdata ); 301*51ba086bSDamjan Jovanovic OSL_TRACE("Curl_HeaderReceived"); 302*51ba086bSDamjan Jovanovic request->curlHeaderReceived( buffer, nitems ); 303*51ba086bSDamjan Jovanovic return nitems; 304*51ba086bSDamjan Jovanovic } 305*51ba086bSDamjan Jovanovic 306*51ba086bSDamjan Jovanovic void CurlRequest::curlHeaderReceived( const char *buffer, size_t size ) 307*51ba086bSDamjan Jovanovic { 308*51ba086bSDamjan Jovanovic rtl::OString lineCrLf( buffer, size ); 309*51ba086bSDamjan Jovanovic sal_Int32 cr = lineCrLf.indexOf( "\r" ); 310*51ba086bSDamjan Jovanovic if ( cr < 0 ) 311*51ba086bSDamjan Jovanovic return; 312*51ba086bSDamjan Jovanovic 313*51ba086bSDamjan Jovanovic rtl::OString line = lineCrLf.copy( 0, cr ); 314*51ba086bSDamjan Jovanovic if ( line.indexOf( "HTTP/" ) == 0 ) 315*51ba086bSDamjan Jovanovic { 316*51ba086bSDamjan Jovanovic // Status line 317*51ba086bSDamjan Jovanovic // Throw away any response headers from a prior response: 318*51ba086bSDamjan Jovanovic responseHeaders.clear(); 319*51ba086bSDamjan Jovanovic sal_Int32 idxFirstSpace = line.indexOf( ' ' ); 320*51ba086bSDamjan Jovanovic if ( idxFirstSpace > 0 ) 321*51ba086bSDamjan Jovanovic { 322*51ba086bSDamjan Jovanovic int idxSecondSpace = line.indexOf( ' ', idxFirstSpace + 1 ); 323*51ba086bSDamjan Jovanovic if ( idxSecondSpace > 0 ) 324*51ba086bSDamjan Jovanovic { 325*51ba086bSDamjan Jovanovic reasonPhrase = line.copy( idxSecondSpace + 1 ); 326*51ba086bSDamjan Jovanovic statusCode = line.copy( idxFirstSpace + 1, idxSecondSpace - idxFirstSpace - 1 ).toInt32(); 327*51ba086bSDamjan Jovanovic } 328*51ba086bSDamjan Jovanovic else 329*51ba086bSDamjan Jovanovic { 330*51ba086bSDamjan Jovanovic reasonPhrase = ""; 331*51ba086bSDamjan Jovanovic statusCode = line.copy( idxFirstSpace + 1 ).toInt32(); 332*51ba086bSDamjan Jovanovic } 333*51ba086bSDamjan Jovanovic } 334*51ba086bSDamjan Jovanovic } 335*51ba086bSDamjan Jovanovic else 336*51ba086bSDamjan Jovanovic { 337*51ba086bSDamjan Jovanovic // Header line 338*51ba086bSDamjan Jovanovic if ( line.getLength() == 0 ) 339*51ba086bSDamjan Jovanovic { 340*51ba086bSDamjan Jovanovic // End of HTTP header 341*51ba086bSDamjan Jovanovic // Discard any intermediate body from 100 Trying or 401 Authentication required: 342*51ba086bSDamjan Jovanovic responseBodyInputStream = new CurlInputStream(); 343*51ba086bSDamjan Jovanovic return; 344*51ba086bSDamjan Jovanovic } 345*51ba086bSDamjan Jovanovic sal_Int32 colon = line.indexOf( ':' ); 346*51ba086bSDamjan Jovanovic if ( colon < 0 ) 347*51ba086bSDamjan Jovanovic { 348*51ba086bSDamjan Jovanovic OSL_TRACE("Non-empty HTTP line without a ':'. Folded header deprecated by RFC 7230?"); 349*51ba086bSDamjan Jovanovic return; 350*51ba086bSDamjan Jovanovic } 351*51ba086bSDamjan Jovanovic Header header; 352*51ba086bSDamjan Jovanovic header.name = line.copy( 0, colon ).toAsciiLowerCase(); 353*51ba086bSDamjan Jovanovic header.value = line.copy( colon + 1 ).trim(); 354*51ba086bSDamjan Jovanovic responseHeaders.push_back(header); 355*51ba086bSDamjan Jovanovic } 356*51ba086bSDamjan Jovanovic } 357*51ba086bSDamjan Jovanovic 358*51ba086bSDamjan Jovanovic const CurlRequest::Header *CurlRequest::findResponseHeader( const rtl::OString &name ) 359*51ba086bSDamjan Jovanovic { 360*51ba086bSDamjan Jovanovic std::vector< CurlRequest::Header >::const_iterator it( responseHeaders.begin() ); 361*51ba086bSDamjan Jovanovic const std::vector< CurlRequest::Header >::const_iterator end( responseHeaders.end() ); 362*51ba086bSDamjan Jovanovic for ( ; it != end; it++ ) 363*51ba086bSDamjan Jovanovic { 364*51ba086bSDamjan Jovanovic if ( name.equalsIgnoreAsciiCase( it->name ) ) 365*51ba086bSDamjan Jovanovic return &(*it); 366*51ba086bSDamjan Jovanovic } 367*51ba086bSDamjan Jovanovic return NULL; 368*51ba086bSDamjan Jovanovic } 369*51ba086bSDamjan Jovanovic 370*51ba086bSDamjan Jovanovic void CurlRequest::saveResponseBodyTo( const uno::Reference< io::XOutputStream > & xOutStream) 371*51ba086bSDamjan Jovanovic { 372*51ba086bSDamjan Jovanovic xOutputStream = xOutStream; 373*51ba086bSDamjan Jovanovic } 374*51ba086bSDamjan Jovanovic 375*51ba086bSDamjan Jovanovic size_t CurlRequest::Curl_MoreBodyReceived( char *buffer, size_t size, size_t nitems, void *userdata ) 376*51ba086bSDamjan Jovanovic { 377*51ba086bSDamjan Jovanovic CurlRequest *request = static_cast< CurlRequest* >( userdata ); 378*51ba086bSDamjan Jovanovic request->curlMoreBodyReceived( buffer, nitems ); 379*51ba086bSDamjan Jovanovic return nitems; 380*51ba086bSDamjan Jovanovic } 381*51ba086bSDamjan Jovanovic 382*51ba086bSDamjan Jovanovic void CurlRequest::curlMoreBodyReceived( const char *buffer, size_t size ) 383*51ba086bSDamjan Jovanovic { 384*51ba086bSDamjan Jovanovic if ( xOutputStream.is() ) 385*51ba086bSDamjan Jovanovic { 386*51ba086bSDamjan Jovanovic const uno::Sequence< sal_Int8 > aDataSeq( (sal_Int8 *)buffer, size ); 387*51ba086bSDamjan Jovanovic xOutputStream->writeBytes( aDataSeq ); 388*51ba086bSDamjan Jovanovic } 389*51ba086bSDamjan Jovanovic else if ( responseBodyInputStream.is() ) 390*51ba086bSDamjan Jovanovic responseBodyInputStream->AddToStream( buffer, size ); 391*51ba086bSDamjan Jovanovic }