19646dec5SDamjan Jovanovic /************************************************************** 29646dec5SDamjan Jovanovic * 39646dec5SDamjan Jovanovic * Licensed to the Apache Software Foundation (ASF) under one 49646dec5SDamjan Jovanovic * or more contributor license agreements. See the NOTICE file 59646dec5SDamjan Jovanovic * distributed with this work for additional information 69646dec5SDamjan Jovanovic * regarding copyright ownership. The ASF licenses this file 79646dec5SDamjan Jovanovic * to you under the Apache License, Version 2.0 (the 89646dec5SDamjan Jovanovic * "License"); you may not use this file except in compliance 99646dec5SDamjan Jovanovic * with the License. You may obtain a copy of the License at 109646dec5SDamjan Jovanovic * 119646dec5SDamjan Jovanovic * http://www.apache.org/licenses/LICENSE-2.0 129646dec5SDamjan Jovanovic * 139646dec5SDamjan Jovanovic * Unless required by applicable law or agreed to in writing, 149646dec5SDamjan Jovanovic * software distributed under the License is distributed on an 159646dec5SDamjan Jovanovic * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 169646dec5SDamjan Jovanovic * KIND, either express or implied. See the License for the 179646dec5SDamjan Jovanovic * specific language governing permissions and limitations 189646dec5SDamjan Jovanovic * under the License. 199646dec5SDamjan Jovanovic * 209646dec5SDamjan Jovanovic *************************************************************/ 219646dec5SDamjan Jovanovic 229646dec5SDamjan Jovanovic 239646dec5SDamjan Jovanovic 249646dec5SDamjan Jovanovic // MARKER(update_precomp.py): autogen include statement, do not remove 259646dec5SDamjan Jovanovic #include "precompiled_webdav.hxx" 269646dec5SDamjan Jovanovic 279646dec5SDamjan Jovanovic #include "CurlRequest.hxx" 289646dec5SDamjan Jovanovic 29*b28b64c2SDamjan Jovanovic #include <string.h> 30*b28b64c2SDamjan Jovanovic 319646dec5SDamjan Jovanovic using namespace ::com::sun::star; 329646dec5SDamjan Jovanovic using namespace http_dav_ucp; 339646dec5SDamjan Jovanovic 349646dec5SDamjan Jovanovic CurlRequest::CurlRequest( CURL *curl ) 359646dec5SDamjan Jovanovic : curl( curl ) 369646dec5SDamjan Jovanovic , curlUrl( NULL ) 379646dec5SDamjan Jovanovic , requestHeaders( NULL ) 389646dec5SDamjan Jovanovic , requestBody( NULL ) 399646dec5SDamjan Jovanovic , requestBodyOffset( 0 ) 409646dec5SDamjan Jovanovic , requestBodySize( 0 ) 419646dec5SDamjan Jovanovic , useChunkedEncoding( false ) 429646dec5SDamjan Jovanovic , provideCredentialsCallback( NULL ) 439646dec5SDamjan Jovanovic , provideCredentialsUserdata( NULL ) 449646dec5SDamjan Jovanovic , statusCode( 0 ) 459646dec5SDamjan Jovanovic , responseBodyInputStream( new CurlInputStream() ) 469646dec5SDamjan Jovanovic { 479646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HEADERFUNCTION, Curl_HeaderReceived ); 489646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HEADERDATA, this ); 499646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, Curl_MoreBodyReceived ); 509646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_WRITEDATA, this ); 519646dec5SDamjan Jovanovic } 529646dec5SDamjan Jovanovic 539646dec5SDamjan Jovanovic CurlRequest::~CurlRequest() 549646dec5SDamjan Jovanovic { 559646dec5SDamjan Jovanovic if ( curlUrl != NULL ) 569646dec5SDamjan Jovanovic curl_url_cleanup( curlUrl ); 579646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CURLU, NULL ); 589646dec5SDamjan Jovanovic 599646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPHEADER, NULL ); 609646dec5SDamjan Jovanovic if ( requestHeaders != NULL ) 619646dec5SDamjan Jovanovic curl_slist_free_all( requestHeaders ); 629646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_READFUNCTION, NULL ); 639646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_READDATA, NULL ); 649646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_INFILESIZE, -1 ); 659646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_SEEKFUNCTION, NULL ); 669646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_SEEKDATA, NULL ); 679646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HEADERFUNCTION, NULL ); 689646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HEADERDATA, NULL ); 699646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, NULL ); 709646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, NULL ); 719646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_WRITEDATA, NULL ); 729646dec5SDamjan Jovanovic } 739646dec5SDamjan Jovanovic 749646dec5SDamjan Jovanovic void CurlRequest::addHeader( const rtl::OString &name, const rtl::OString &value) throw (DAVException) 759646dec5SDamjan Jovanovic { 769646dec5SDamjan Jovanovic rtl::OString line = name + ": " + value; 779646dec5SDamjan Jovanovic struct curl_slist *appended = curl_slist_append( requestHeaders, line.getStr() ); 789646dec5SDamjan Jovanovic if ( appended != NULL ) 799646dec5SDamjan Jovanovic { 809646dec5SDamjan Jovanovic requestHeaders = appended; 819646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPHEADER, requestHeaders ); 829646dec5SDamjan Jovanovic } 839646dec5SDamjan Jovanovic else 849646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii( "Out of memory" ) ); 859646dec5SDamjan Jovanovic } 869646dec5SDamjan Jovanovic 879646dec5SDamjan Jovanovic void CurlRequest::setRequestBody( const char *body, size_t size ) 889646dec5SDamjan Jovanovic { 899646dec5SDamjan Jovanovic requestBody = body; 909646dec5SDamjan Jovanovic requestBodyOffset = 0; 919646dec5SDamjan Jovanovic requestBodySize = size; 929646dec5SDamjan Jovanovic 939646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_READFUNCTION, Curl_SendMoreBody ); 949646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_READDATA, this ); 959646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_SEEKFUNCTION, Curl_SeekCallback ); 969646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_SEEKDATA, this ); 979646dec5SDamjan Jovanovic if ( useChunkedEncoding ) 989646dec5SDamjan Jovanovic addHeader( "Transfer-Encoding", "chunked" ); 999646dec5SDamjan Jovanovic else 1009646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)size ); 1019646dec5SDamjan Jovanovic } 1029646dec5SDamjan Jovanovic 1039646dec5SDamjan Jovanovic int CurlRequest::Curl_SeekCallback( void *userdata, curl_off_t offset, int origin ) 1049646dec5SDamjan Jovanovic { 1059646dec5SDamjan Jovanovic CurlRequest *request = static_cast< CurlRequest* >( userdata ); 1069646dec5SDamjan Jovanovic if ( origin == SEEK_SET ) 1079646dec5SDamjan Jovanovic request->requestBodyOffset = (size_t) offset; 1089646dec5SDamjan Jovanovic else if ( origin == SEEK_CUR ) 1099646dec5SDamjan Jovanovic request->requestBodyOffset += (size_t) offset; 1109646dec5SDamjan Jovanovic else if ( origin == SEEK_END ) 1119646dec5SDamjan Jovanovic request->requestBodyOffset += (size_t) ((curl_off_t)request->requestBodySize + offset); 1129646dec5SDamjan Jovanovic else 1139646dec5SDamjan Jovanovic return CURL_SEEKFUNC_CANTSEEK; 1149646dec5SDamjan Jovanovic if ( request->requestBodyOffset > request->requestBodySize ) 1159646dec5SDamjan Jovanovic request->requestBodyOffset = request->requestBodySize; 1169646dec5SDamjan Jovanovic return CURL_SEEKFUNC_OK; 1179646dec5SDamjan Jovanovic } 1189646dec5SDamjan Jovanovic 1199646dec5SDamjan Jovanovic size_t CurlRequest::Curl_SendMoreBody( char *buffer, size_t size, size_t nitems, void *userdata ) 1209646dec5SDamjan Jovanovic { 1219646dec5SDamjan Jovanovic CurlRequest *request = static_cast< CurlRequest* >( userdata ); 1229646dec5SDamjan Jovanovic OSL_TRACE("Curl_SendMoreBody"); 1239646dec5SDamjan Jovanovic return request->curlSendMoreBody( buffer, nitems ); 1249646dec5SDamjan Jovanovic } 1259646dec5SDamjan Jovanovic 1269646dec5SDamjan Jovanovic size_t CurlRequest::curlSendMoreBody( char *buffer, size_t len ) 1279646dec5SDamjan Jovanovic { 1289646dec5SDamjan Jovanovic size_t bytesToSend = requestBodySize - requestBodyOffset; 1299646dec5SDamjan Jovanovic if ( bytesToSend > len ) 1309646dec5SDamjan Jovanovic bytesToSend = len; 1319646dec5SDamjan Jovanovic memcpy( buffer, requestBody, bytesToSend ); 1329646dec5SDamjan Jovanovic requestBodyOffset += bytesToSend; 1339646dec5SDamjan Jovanovic return bytesToSend; 1349646dec5SDamjan Jovanovic } 1359646dec5SDamjan Jovanovic 1369646dec5SDamjan Jovanovic void CurlRequest::setProvideCredentialsCallback( bool (*callback)(long statusCode, void *userdata) throw (DAVException), void *userdata ) 1379646dec5SDamjan Jovanovic { 1389646dec5SDamjan Jovanovic provideCredentialsCallback = callback; 1399646dec5SDamjan Jovanovic provideCredentialsUserdata = userdata; 1409646dec5SDamjan Jovanovic } 1419646dec5SDamjan Jovanovic 1429646dec5SDamjan Jovanovic void CurlRequest::setURI( CurlUri uri, rtl::OUString path ) throw (DAVException) 1439646dec5SDamjan Jovanovic { 1449646dec5SDamjan Jovanovic if ( curlUrl != NULL ) 1459646dec5SDamjan Jovanovic { 1469646dec5SDamjan Jovanovic curl_url_cleanup( curlUrl ); 1479646dec5SDamjan Jovanovic curlUrl = NULL; 1489646dec5SDamjan Jovanovic } 1499646dec5SDamjan Jovanovic 1509646dec5SDamjan Jovanovic curlUrl = curl_url(); 1519646dec5SDamjan Jovanovic if ( curlUrl == NULL ) 1529646dec5SDamjan Jovanovic throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii( "Out of memory" ) ); 1539646dec5SDamjan Jovanovic 1549646dec5SDamjan Jovanovic if ( CurlUri( path ).GetHost().isEmpty() ) 1559646dec5SDamjan Jovanovic { 1569646dec5SDamjan Jovanovic // "path" is really a path, not a URI 1579646dec5SDamjan Jovanovic curl_url_set( curlUrl, CURLUPART_URL, rtl::OUStringToOString( uri.GetURI(), RTL_TEXTENCODING_UTF8 ).getStr(), 0 ); 1589646dec5SDamjan Jovanovic curl_url_set( curlUrl, CURLUPART_PATH, rtl::OUStringToOString( path, RTL_TEXTENCODING_UTF8 ).getStr(), 0 ); 1599646dec5SDamjan Jovanovic } 1609646dec5SDamjan Jovanovic else 1619646dec5SDamjan Jovanovic { 1629646dec5SDamjan Jovanovic // The "path" is a full URI 1639646dec5SDamjan Jovanovic curl_url_set( curlUrl, CURLUPART_URL, rtl::OUStringToOString( path, RTL_TEXTENCODING_UTF8 ).getStr(), 0 ); 1649646dec5SDamjan Jovanovic } 1659646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CURLU, curlUrl ); 1669646dec5SDamjan Jovanovic } 1679646dec5SDamjan Jovanovic 1689646dec5SDamjan Jovanovic CURLcode CurlRequest::copy( CurlUri uri, rtl::OUString path ) throw(DAVException) 1699646dec5SDamjan Jovanovic { 1709646dec5SDamjan Jovanovic setURI( uri, path ); 1719646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 1729646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "COPY" ); 1739646dec5SDamjan Jovanovic return perform(); 1749646dec5SDamjan Jovanovic } 1759646dec5SDamjan Jovanovic 1769646dec5SDamjan Jovanovic CURLcode CurlRequest::delete_( CurlUri uri, rtl::OUString path ) throw (DAVException) 1779646dec5SDamjan Jovanovic { 1789646dec5SDamjan Jovanovic setURI( uri, path ); 1799646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 1809646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "DELETE" ); 1819646dec5SDamjan Jovanovic return perform(); 1829646dec5SDamjan Jovanovic } 1839646dec5SDamjan Jovanovic 1849646dec5SDamjan Jovanovic CURLcode CurlRequest::get( CurlUri uri, rtl::OUString path ) throw(DAVException) 1859646dec5SDamjan Jovanovic { 1869646dec5SDamjan Jovanovic setURI( uri, path ); 1879646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 1889646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "GET" ); 1899646dec5SDamjan Jovanovic return perform(); 1909646dec5SDamjan Jovanovic } 1919646dec5SDamjan Jovanovic 1929646dec5SDamjan Jovanovic CURLcode CurlRequest::head( CurlUri uri, rtl::OUString path ) throw (DAVException) 1939646dec5SDamjan Jovanovic { 1949646dec5SDamjan Jovanovic setURI( uri, path ); 1959646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_NOBODY, 1L ); 1969646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "HEAD" ); 1979646dec5SDamjan Jovanovic return perform(); 1989646dec5SDamjan Jovanovic } 1999646dec5SDamjan Jovanovic 2009646dec5SDamjan Jovanovic CURLcode CurlRequest::lock( CurlUri uri, rtl::OUString path ) throw (DAVException) 2019646dec5SDamjan Jovanovic { 2029646dec5SDamjan Jovanovic setURI( uri, path ); 2039646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 2049646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "LOCK" ); 2059646dec5SDamjan Jovanovic return perform(); 2069646dec5SDamjan Jovanovic } 2079646dec5SDamjan Jovanovic 2089646dec5SDamjan Jovanovic CURLcode CurlRequest::mkcol( CurlUri uri, rtl::OUString path ) throw (DAVException) 2099646dec5SDamjan Jovanovic { 2109646dec5SDamjan Jovanovic setURI( uri, path ); 2119646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 2129646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "MKCOL" ); 2139646dec5SDamjan Jovanovic return perform(); 2149646dec5SDamjan Jovanovic } 2159646dec5SDamjan Jovanovic 2169646dec5SDamjan Jovanovic CURLcode CurlRequest::move( CurlUri uri, rtl::OUString path ) throw (DAVException) 2179646dec5SDamjan Jovanovic { 2189646dec5SDamjan Jovanovic setURI( uri, path ); 2199646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 2209646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "MOVE" ); 2219646dec5SDamjan Jovanovic return perform(); 2229646dec5SDamjan Jovanovic } 2239646dec5SDamjan Jovanovic 2249646dec5SDamjan Jovanovic CURLcode CurlRequest::post( CurlUri uri, rtl::OUString path ) throw (DAVException) 2259646dec5SDamjan Jovanovic { 2269646dec5SDamjan Jovanovic setURI( uri, path ); 2279646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 2289646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "POST" ); 2299646dec5SDamjan Jovanovic return perform(); 2309646dec5SDamjan Jovanovic } 2319646dec5SDamjan Jovanovic 2329646dec5SDamjan Jovanovic CURLcode CurlRequest::propfind( CurlUri uri, rtl::OUString path ) throw (DAVException) 2339646dec5SDamjan Jovanovic { 2349646dec5SDamjan Jovanovic setURI( uri, path ); 2359646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 2369646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "PROPFIND" ); 2379646dec5SDamjan Jovanovic return perform(); 2389646dec5SDamjan Jovanovic } 2399646dec5SDamjan Jovanovic 2409646dec5SDamjan Jovanovic CURLcode CurlRequest::proppatch( CurlUri uri, rtl::OUString path ) throw (DAVException) 2419646dec5SDamjan Jovanovic { 2429646dec5SDamjan Jovanovic setURI( uri, path ); 2439646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 2449646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "PROPPATCH" ); 2459646dec5SDamjan Jovanovic return perform(); 2469646dec5SDamjan Jovanovic } 2479646dec5SDamjan Jovanovic 2489646dec5SDamjan Jovanovic CURLcode CurlRequest::put( CurlUri uri, rtl::OUString path ) throw (DAVException) 2499646dec5SDamjan Jovanovic { 2509646dec5SDamjan Jovanovic setURI( uri, path ); 2519646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 2529646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "PUT" ); 2539646dec5SDamjan Jovanovic return perform(); 2549646dec5SDamjan Jovanovic } 2559646dec5SDamjan Jovanovic 2569646dec5SDamjan Jovanovic CURLcode CurlRequest::unlock( CurlUri uri, rtl::OUString path ) throw (DAVException) 2579646dec5SDamjan Jovanovic { 2589646dec5SDamjan Jovanovic setURI( uri, path ); 2599646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 2609646dec5SDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "UNLOCK" ); 2619646dec5SDamjan Jovanovic return perform(); 2629646dec5SDamjan Jovanovic } 2639646dec5SDamjan Jovanovic 2649646dec5SDamjan Jovanovic CURLcode CurlRequest::perform() throw (DAVException) 2659646dec5SDamjan Jovanovic { 2669646dec5SDamjan Jovanovic CURLcode rc = curl_easy_perform( curl ); 2679646dec5SDamjan Jovanovic long statusCode = 0; 2689646dec5SDamjan Jovanovic curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &statusCode ); 2699646dec5SDamjan Jovanovic if ( ( statusCode == 401 || statusCode == 407 ) && provideCredentialsCallback != NULL ) 2709646dec5SDamjan Jovanovic { 2719646dec5SDamjan Jovanovic bool haveCredentials = provideCredentialsCallback( statusCode, provideCredentialsUserdata ); 2729646dec5SDamjan Jovanovic if ( haveCredentials ) 2739646dec5SDamjan Jovanovic { 2749646dec5SDamjan Jovanovic // rewind body: 2759646dec5SDamjan Jovanovic requestBodyOffset = 0; 2769646dec5SDamjan Jovanovic // retry with credentials: 2779646dec5SDamjan Jovanovic rc = curl_easy_perform( curl ); 2789646dec5SDamjan Jovanovic // If this was to authenticate with the proxy, we may need to authenticate 2799646dec5SDamjan Jovanovic // with the destination host too: 2809646dec5SDamjan Jovanovic if ( statusCode == 407 ) 2819646dec5SDamjan Jovanovic { 2829646dec5SDamjan Jovanovic curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &statusCode ); 2839646dec5SDamjan Jovanovic if ( statusCode == 401 && provideCredentialsCallback != NULL ) 2849646dec5SDamjan Jovanovic { 2859646dec5SDamjan Jovanovic haveCredentials = provideCredentialsCallback( statusCode, provideCredentialsUserdata ); 2869646dec5SDamjan Jovanovic if ( haveCredentials ) 2879646dec5SDamjan Jovanovic { 2889646dec5SDamjan Jovanovic // rewind body: 2899646dec5SDamjan Jovanovic requestBodyOffset = 0; 2909646dec5SDamjan Jovanovic // retry with credentials: 2919646dec5SDamjan Jovanovic rc = curl_easy_perform( curl ); 2929646dec5SDamjan Jovanovic } 2939646dec5SDamjan Jovanovic } 2949646dec5SDamjan Jovanovic } 2959646dec5SDamjan Jovanovic } 2969646dec5SDamjan Jovanovic } 2979646dec5SDamjan Jovanovic return rc; 2989646dec5SDamjan Jovanovic } 2999646dec5SDamjan Jovanovic 3009646dec5SDamjan Jovanovic size_t CurlRequest::Curl_HeaderReceived( char *buffer, size_t size, size_t nitems, void *userdata ) 3019646dec5SDamjan Jovanovic { 3029646dec5SDamjan Jovanovic CurlRequest *request = static_cast< CurlRequest* >( userdata ); 3039646dec5SDamjan Jovanovic OSL_TRACE("Curl_HeaderReceived"); 3049646dec5SDamjan Jovanovic request->curlHeaderReceived( buffer, nitems ); 3059646dec5SDamjan Jovanovic return nitems; 3069646dec5SDamjan Jovanovic } 3079646dec5SDamjan Jovanovic 3089646dec5SDamjan Jovanovic void CurlRequest::curlHeaderReceived( const char *buffer, size_t size ) 3099646dec5SDamjan Jovanovic { 3109646dec5SDamjan Jovanovic rtl::OString lineCrLf( buffer, size ); 3119646dec5SDamjan Jovanovic sal_Int32 cr = lineCrLf.indexOf( "\r" ); 3129646dec5SDamjan Jovanovic if ( cr < 0 ) 3139646dec5SDamjan Jovanovic return; 3149646dec5SDamjan Jovanovic 3159646dec5SDamjan Jovanovic rtl::OString line = lineCrLf.copy( 0, cr ); 3169646dec5SDamjan Jovanovic if ( line.indexOf( "HTTP/" ) == 0 ) 3179646dec5SDamjan Jovanovic { 3189646dec5SDamjan Jovanovic // Status line 3199646dec5SDamjan Jovanovic // Throw away any response headers from a prior response: 3209646dec5SDamjan Jovanovic responseHeaders.clear(); 3219646dec5SDamjan Jovanovic sal_Int32 idxFirstSpace = line.indexOf( ' ' ); 3229646dec5SDamjan Jovanovic if ( idxFirstSpace > 0 ) 3239646dec5SDamjan Jovanovic { 3249646dec5SDamjan Jovanovic int idxSecondSpace = line.indexOf( ' ', idxFirstSpace + 1 ); 3259646dec5SDamjan Jovanovic if ( idxSecondSpace > 0 ) 3269646dec5SDamjan Jovanovic { 3279646dec5SDamjan Jovanovic reasonPhrase = line.copy( idxSecondSpace + 1 ); 3289646dec5SDamjan Jovanovic statusCode = line.copy( idxFirstSpace + 1, idxSecondSpace - idxFirstSpace - 1 ).toInt32(); 3299646dec5SDamjan Jovanovic } 3309646dec5SDamjan Jovanovic else 3319646dec5SDamjan Jovanovic { 3329646dec5SDamjan Jovanovic reasonPhrase = ""; 3339646dec5SDamjan Jovanovic statusCode = line.copy( idxFirstSpace + 1 ).toInt32(); 3349646dec5SDamjan Jovanovic } 3359646dec5SDamjan Jovanovic } 3369646dec5SDamjan Jovanovic } 3379646dec5SDamjan Jovanovic else 3389646dec5SDamjan Jovanovic { 3399646dec5SDamjan Jovanovic // Header line 3409646dec5SDamjan Jovanovic if ( line.getLength() == 0 ) 3419646dec5SDamjan Jovanovic { 3429646dec5SDamjan Jovanovic // End of HTTP header 3439646dec5SDamjan Jovanovic // Discard any intermediate body from 100 Trying or 401 Authentication required: 3449646dec5SDamjan Jovanovic responseBodyInputStream = new CurlInputStream(); 3459646dec5SDamjan Jovanovic return; 3469646dec5SDamjan Jovanovic } 3479646dec5SDamjan Jovanovic sal_Int32 colon = line.indexOf( ':' ); 3489646dec5SDamjan Jovanovic if ( colon < 0 ) 3499646dec5SDamjan Jovanovic { 3509646dec5SDamjan Jovanovic OSL_TRACE("Non-empty HTTP line without a ':'. Folded header deprecated by RFC 7230?"); 3519646dec5SDamjan Jovanovic return; 3529646dec5SDamjan Jovanovic } 3539646dec5SDamjan Jovanovic Header header; 3549646dec5SDamjan Jovanovic header.name = line.copy( 0, colon ).toAsciiLowerCase(); 3559646dec5SDamjan Jovanovic header.value = line.copy( colon + 1 ).trim(); 3569646dec5SDamjan Jovanovic responseHeaders.push_back(header); 3579646dec5SDamjan Jovanovic } 3589646dec5SDamjan Jovanovic } 3599646dec5SDamjan Jovanovic 3609646dec5SDamjan Jovanovic const CurlRequest::Header *CurlRequest::findResponseHeader( const rtl::OString &name ) 3619646dec5SDamjan Jovanovic { 3629646dec5SDamjan Jovanovic std::vector< CurlRequest::Header >::const_iterator it( responseHeaders.begin() ); 3639646dec5SDamjan Jovanovic const std::vector< CurlRequest::Header >::const_iterator end( responseHeaders.end() ); 3649646dec5SDamjan Jovanovic for ( ; it != end; it++ ) 3659646dec5SDamjan Jovanovic { 3669646dec5SDamjan Jovanovic if ( name.equalsIgnoreAsciiCase( it->name ) ) 3679646dec5SDamjan Jovanovic return &(*it); 3689646dec5SDamjan Jovanovic } 3699646dec5SDamjan Jovanovic return NULL; 3709646dec5SDamjan Jovanovic } 3719646dec5SDamjan Jovanovic 3729646dec5SDamjan Jovanovic void CurlRequest::saveResponseBodyTo( const uno::Reference< io::XOutputStream > & xOutStream) 3739646dec5SDamjan Jovanovic { 3749646dec5SDamjan Jovanovic xOutputStream = xOutStream; 3759646dec5SDamjan Jovanovic } 3769646dec5SDamjan Jovanovic 3779646dec5SDamjan Jovanovic size_t CurlRequest::Curl_MoreBodyReceived( char *buffer, size_t size, size_t nitems, void *userdata ) 3789646dec5SDamjan Jovanovic { 3799646dec5SDamjan Jovanovic CurlRequest *request = static_cast< CurlRequest* >( userdata ); 3809646dec5SDamjan Jovanovic request->curlMoreBodyReceived( buffer, nitems ); 3819646dec5SDamjan Jovanovic return nitems; 3829646dec5SDamjan Jovanovic } 3839646dec5SDamjan Jovanovic 3849646dec5SDamjan Jovanovic void CurlRequest::curlMoreBodyReceived( const char *buffer, size_t size ) 3859646dec5SDamjan Jovanovic { 3869646dec5SDamjan Jovanovic if ( xOutputStream.is() ) 3879646dec5SDamjan Jovanovic { 3889646dec5SDamjan Jovanovic const uno::Sequence< sal_Int8 > aDataSeq( (sal_Int8 *)buffer, size ); 3899646dec5SDamjan Jovanovic xOutputStream->writeBytes( aDataSeq ); 3909646dec5SDamjan Jovanovic } 3919646dec5SDamjan Jovanovic else if ( responseBodyInputStream.is() ) 3929646dec5SDamjan Jovanovic responseBodyInputStream->AddToStream( buffer, size ); 3939646dec5SDamjan Jovanovic } 394