151ba086bSDamjan Jovanovic /************************************************************** 251ba086bSDamjan Jovanovic * 351ba086bSDamjan Jovanovic * Licensed to the Apache Software Foundation (ASF) under one 451ba086bSDamjan Jovanovic * or more contributor license agreements. See the NOTICE file 551ba086bSDamjan Jovanovic * distributed with this work for additional information 651ba086bSDamjan Jovanovic * regarding copyright ownership. The ASF licenses this file 751ba086bSDamjan Jovanovic * to you under the Apache License, Version 2.0 (the 851ba086bSDamjan Jovanovic * "License"); you may not use this file except in compliance 951ba086bSDamjan Jovanovic * with the License. You may obtain a copy of the License at 1051ba086bSDamjan Jovanovic * 1151ba086bSDamjan Jovanovic * http://www.apache.org/licenses/LICENSE-2.0 1251ba086bSDamjan Jovanovic * 1351ba086bSDamjan Jovanovic * Unless required by applicable law or agreed to in writing, 1451ba086bSDamjan Jovanovic * software distributed under the License is distributed on an 1551ba086bSDamjan Jovanovic * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1651ba086bSDamjan Jovanovic * KIND, either express or implied. See the License for the 1751ba086bSDamjan Jovanovic * specific language governing permissions and limitations 1851ba086bSDamjan Jovanovic * under the License. 1951ba086bSDamjan Jovanovic * 2051ba086bSDamjan Jovanovic *************************************************************/ 2151ba086bSDamjan Jovanovic 2251ba086bSDamjan Jovanovic 2351ba086bSDamjan Jovanovic 2451ba086bSDamjan Jovanovic // MARKER(update_precomp.py): autogen include statement, do not remove 2551ba086bSDamjan Jovanovic #include "precompiled_webdav.hxx" 2651ba086bSDamjan Jovanovic 2751ba086bSDamjan Jovanovic #include "CurlRequest.hxx" 2851ba086bSDamjan Jovanovic 29*19cdc44eSDamjan Jovanovic #include <string.h> 30*19cdc44eSDamjan Jovanovic 3151ba086bSDamjan Jovanovic using namespace ::com::sun::star; 3251ba086bSDamjan Jovanovic using namespace http_dav_ucp; 3351ba086bSDamjan Jovanovic 3451ba086bSDamjan Jovanovic CurlRequest::CurlRequest( CURL *curl ) 3551ba086bSDamjan Jovanovic : curl( curl ) 3651ba086bSDamjan Jovanovic , curlUrl( NULL ) 3751ba086bSDamjan Jovanovic , requestHeaders( NULL ) 3851ba086bSDamjan Jovanovic , requestBody( NULL ) 3951ba086bSDamjan Jovanovic , requestBodyOffset( 0 ) 4051ba086bSDamjan Jovanovic , requestBodySize( 0 ) 4151ba086bSDamjan Jovanovic , useChunkedEncoding( false ) 4251ba086bSDamjan Jovanovic , provideCredentialsCallback( NULL ) 4351ba086bSDamjan Jovanovic , provideCredentialsUserdata( NULL ) 4451ba086bSDamjan Jovanovic , statusCode( 0 ) 4551ba086bSDamjan Jovanovic , responseBodyInputStream( new CurlInputStream() ) 4651ba086bSDamjan Jovanovic { 4751ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HEADERFUNCTION, Curl_HeaderReceived ); 4851ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HEADERDATA, this ); 4951ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, Curl_MoreBodyReceived ); 5051ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_WRITEDATA, this ); 5151ba086bSDamjan Jovanovic } 5251ba086bSDamjan Jovanovic 5351ba086bSDamjan Jovanovic CurlRequest::~CurlRequest() 5451ba086bSDamjan Jovanovic { 5551ba086bSDamjan Jovanovic if ( curlUrl != NULL ) 5651ba086bSDamjan Jovanovic curl_url_cleanup( curlUrl ); 5751ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CURLU, NULL ); 5851ba086bSDamjan Jovanovic 5951ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPHEADER, NULL ); 6051ba086bSDamjan Jovanovic if ( requestHeaders != NULL ) 6151ba086bSDamjan Jovanovic curl_slist_free_all( requestHeaders ); 6251ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_READFUNCTION, NULL ); 6351ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_READDATA, NULL ); 6451ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_INFILESIZE, -1 ); 6551ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_SEEKFUNCTION, NULL ); 6651ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_SEEKDATA, NULL ); 6751ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HEADERFUNCTION, NULL ); 6851ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HEADERDATA, NULL ); 6951ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, NULL ); 7051ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, NULL ); 7151ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_WRITEDATA, NULL ); 7251ba086bSDamjan Jovanovic } 7351ba086bSDamjan Jovanovic 7451ba086bSDamjan Jovanovic void CurlRequest::addHeader( const rtl::OString &name, const rtl::OString &value) throw (DAVException) 7551ba086bSDamjan Jovanovic { 7651ba086bSDamjan Jovanovic rtl::OString line = name + ": " + value; 7751ba086bSDamjan Jovanovic struct curl_slist *appended = curl_slist_append( requestHeaders, line.getStr() ); 7851ba086bSDamjan Jovanovic if ( appended != NULL ) 7951ba086bSDamjan Jovanovic { 8051ba086bSDamjan Jovanovic requestHeaders = appended; 8151ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPHEADER, requestHeaders ); 8251ba086bSDamjan Jovanovic } 8351ba086bSDamjan Jovanovic else 8451ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii( "Out of memory" ) ); 8551ba086bSDamjan Jovanovic } 8651ba086bSDamjan Jovanovic 8751ba086bSDamjan Jovanovic void CurlRequest::setRequestBody( const char *body, size_t size ) 8851ba086bSDamjan Jovanovic { 8951ba086bSDamjan Jovanovic requestBody = body; 9051ba086bSDamjan Jovanovic requestBodyOffset = 0; 9151ba086bSDamjan Jovanovic requestBodySize = size; 9251ba086bSDamjan Jovanovic 9351ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_READFUNCTION, Curl_SendMoreBody ); 9451ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_READDATA, this ); 9551ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_SEEKFUNCTION, Curl_SeekCallback ); 9651ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_SEEKDATA, this ); 9751ba086bSDamjan Jovanovic if ( useChunkedEncoding ) 9851ba086bSDamjan Jovanovic addHeader( "Transfer-Encoding", "chunked" ); 9951ba086bSDamjan Jovanovic else 10051ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_INFILESIZE_LARGE, (curl_off_t)size ); 10151ba086bSDamjan Jovanovic } 10251ba086bSDamjan Jovanovic 10351ba086bSDamjan Jovanovic int CurlRequest::Curl_SeekCallback( void *userdata, curl_off_t offset, int origin ) 10451ba086bSDamjan Jovanovic { 10551ba086bSDamjan Jovanovic CurlRequest *request = static_cast< CurlRequest* >( userdata ); 10651ba086bSDamjan Jovanovic if ( origin == SEEK_SET ) 10751ba086bSDamjan Jovanovic request->requestBodyOffset = (size_t) offset; 10851ba086bSDamjan Jovanovic else if ( origin == SEEK_CUR ) 10951ba086bSDamjan Jovanovic request->requestBodyOffset += (size_t) offset; 11051ba086bSDamjan Jovanovic else if ( origin == SEEK_END ) 11151ba086bSDamjan Jovanovic request->requestBodyOffset += (size_t) ((curl_off_t)request->requestBodySize + offset); 11251ba086bSDamjan Jovanovic else 11351ba086bSDamjan Jovanovic return CURL_SEEKFUNC_CANTSEEK; 11451ba086bSDamjan Jovanovic if ( request->requestBodyOffset > request->requestBodySize ) 11551ba086bSDamjan Jovanovic request->requestBodyOffset = request->requestBodySize; 11651ba086bSDamjan Jovanovic return CURL_SEEKFUNC_OK; 11751ba086bSDamjan Jovanovic } 11851ba086bSDamjan Jovanovic 11951ba086bSDamjan Jovanovic size_t CurlRequest::Curl_SendMoreBody( char *buffer, size_t size, size_t nitems, void *userdata ) 12051ba086bSDamjan Jovanovic { 12151ba086bSDamjan Jovanovic CurlRequest *request = static_cast< CurlRequest* >( userdata ); 12251ba086bSDamjan Jovanovic OSL_TRACE("Curl_SendMoreBody"); 12351ba086bSDamjan Jovanovic return request->curlSendMoreBody( buffer, nitems ); 12451ba086bSDamjan Jovanovic } 12551ba086bSDamjan Jovanovic 12651ba086bSDamjan Jovanovic size_t CurlRequest::curlSendMoreBody( char *buffer, size_t len ) 12751ba086bSDamjan Jovanovic { 12851ba086bSDamjan Jovanovic size_t bytesToSend = requestBodySize - requestBodyOffset; 12951ba086bSDamjan Jovanovic if ( bytesToSend > len ) 13051ba086bSDamjan Jovanovic bytesToSend = len; 13151ba086bSDamjan Jovanovic memcpy( buffer, requestBody, bytesToSend ); 13251ba086bSDamjan Jovanovic requestBodyOffset += bytesToSend; 13351ba086bSDamjan Jovanovic return bytesToSend; 13451ba086bSDamjan Jovanovic } 13551ba086bSDamjan Jovanovic 13651ba086bSDamjan Jovanovic void CurlRequest::setProvideCredentialsCallback( bool (*callback)(long statusCode, void *userdata) throw (DAVException), void *userdata ) 13751ba086bSDamjan Jovanovic { 13851ba086bSDamjan Jovanovic provideCredentialsCallback = callback; 13951ba086bSDamjan Jovanovic provideCredentialsUserdata = userdata; 14051ba086bSDamjan Jovanovic } 14151ba086bSDamjan Jovanovic 14251ba086bSDamjan Jovanovic void CurlRequest::setURI( CurlUri uri, rtl::OUString path ) throw (DAVException) 14351ba086bSDamjan Jovanovic { 14451ba086bSDamjan Jovanovic if ( curlUrl != NULL ) 14551ba086bSDamjan Jovanovic { 14651ba086bSDamjan Jovanovic curl_url_cleanup( curlUrl ); 14751ba086bSDamjan Jovanovic curlUrl = NULL; 14851ba086bSDamjan Jovanovic } 14951ba086bSDamjan Jovanovic 15051ba086bSDamjan Jovanovic curlUrl = curl_url(); 15151ba086bSDamjan Jovanovic if ( curlUrl == NULL ) 15251ba086bSDamjan Jovanovic throw DAVException( DAVException::DAV_SESSION_CREATE, rtl::OUString::createFromAscii( "Out of memory" ) ); 15351ba086bSDamjan Jovanovic 15451ba086bSDamjan Jovanovic if ( CurlUri( path ).GetHost().isEmpty() ) 15551ba086bSDamjan Jovanovic { 15651ba086bSDamjan Jovanovic // "path" is really a path, not a URI 15751ba086bSDamjan Jovanovic curl_url_set( curlUrl, CURLUPART_URL, rtl::OUStringToOString( uri.GetURI(), RTL_TEXTENCODING_UTF8 ).getStr(), 0 ); 15851ba086bSDamjan Jovanovic curl_url_set( curlUrl, CURLUPART_PATH, rtl::OUStringToOString( path, RTL_TEXTENCODING_UTF8 ).getStr(), 0 ); 15951ba086bSDamjan Jovanovic } 16051ba086bSDamjan Jovanovic else 16151ba086bSDamjan Jovanovic { 16251ba086bSDamjan Jovanovic // The "path" is a full URI 16351ba086bSDamjan Jovanovic curl_url_set( curlUrl, CURLUPART_URL, rtl::OUStringToOString( path, RTL_TEXTENCODING_UTF8 ).getStr(), 0 ); 16451ba086bSDamjan Jovanovic } 16551ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CURLU, curlUrl ); 16651ba086bSDamjan Jovanovic } 16751ba086bSDamjan Jovanovic 16851ba086bSDamjan Jovanovic CURLcode CurlRequest::copy( CurlUri uri, rtl::OUString path ) throw(DAVException) 16951ba086bSDamjan Jovanovic { 17051ba086bSDamjan Jovanovic setURI( uri, path ); 17151ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 17251ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "COPY" ); 17351ba086bSDamjan Jovanovic return perform(); 17451ba086bSDamjan Jovanovic } 17551ba086bSDamjan Jovanovic 17651ba086bSDamjan Jovanovic CURLcode CurlRequest::delete_( CurlUri uri, rtl::OUString path ) throw (DAVException) 17751ba086bSDamjan Jovanovic { 17851ba086bSDamjan Jovanovic setURI( uri, path ); 17951ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 18051ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "DELETE" ); 18151ba086bSDamjan Jovanovic return perform(); 18251ba086bSDamjan Jovanovic } 18351ba086bSDamjan Jovanovic 18451ba086bSDamjan Jovanovic CURLcode CurlRequest::get( CurlUri uri, rtl::OUString path ) throw(DAVException) 18551ba086bSDamjan Jovanovic { 18651ba086bSDamjan Jovanovic setURI( uri, path ); 18751ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 18851ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "GET" ); 18951ba086bSDamjan Jovanovic return perform(); 19051ba086bSDamjan Jovanovic } 19151ba086bSDamjan Jovanovic 19251ba086bSDamjan Jovanovic CURLcode CurlRequest::head( CurlUri uri, rtl::OUString path ) throw (DAVException) 19351ba086bSDamjan Jovanovic { 19451ba086bSDamjan Jovanovic setURI( uri, path ); 19551ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_NOBODY, 1L ); 19651ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "HEAD" ); 19751ba086bSDamjan Jovanovic return perform(); 19851ba086bSDamjan Jovanovic } 19951ba086bSDamjan Jovanovic 20051ba086bSDamjan Jovanovic CURLcode CurlRequest::lock( CurlUri uri, rtl::OUString path ) throw (DAVException) 20151ba086bSDamjan Jovanovic { 20251ba086bSDamjan Jovanovic setURI( uri, path ); 20351ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 20451ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "LOCK" ); 20551ba086bSDamjan Jovanovic return perform(); 20651ba086bSDamjan Jovanovic } 20751ba086bSDamjan Jovanovic 20851ba086bSDamjan Jovanovic CURLcode CurlRequest::mkcol( CurlUri uri, rtl::OUString path ) throw (DAVException) 20951ba086bSDamjan Jovanovic { 21051ba086bSDamjan Jovanovic setURI( uri, path ); 21151ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 21251ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "MKCOL" ); 21351ba086bSDamjan Jovanovic return perform(); 21451ba086bSDamjan Jovanovic } 21551ba086bSDamjan Jovanovic 21651ba086bSDamjan Jovanovic CURLcode CurlRequest::move( CurlUri uri, rtl::OUString path ) throw (DAVException) 21751ba086bSDamjan Jovanovic { 21851ba086bSDamjan Jovanovic setURI( uri, path ); 21951ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 22051ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "MOVE" ); 22151ba086bSDamjan Jovanovic return perform(); 22251ba086bSDamjan Jovanovic } 22351ba086bSDamjan Jovanovic 22451ba086bSDamjan Jovanovic CURLcode CurlRequest::post( CurlUri uri, rtl::OUString path ) throw (DAVException) 22551ba086bSDamjan Jovanovic { 22651ba086bSDamjan Jovanovic setURI( uri, path ); 22751ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 22851ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "POST" ); 22951ba086bSDamjan Jovanovic return perform(); 23051ba086bSDamjan Jovanovic } 23151ba086bSDamjan Jovanovic 23251ba086bSDamjan Jovanovic CURLcode CurlRequest::propfind( CurlUri uri, rtl::OUString path ) throw (DAVException) 23351ba086bSDamjan Jovanovic { 23451ba086bSDamjan Jovanovic setURI( uri, path ); 23551ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 23651ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "PROPFIND" ); 23751ba086bSDamjan Jovanovic return perform(); 23851ba086bSDamjan Jovanovic } 23951ba086bSDamjan Jovanovic 24051ba086bSDamjan Jovanovic CURLcode CurlRequest::proppatch( CurlUri uri, rtl::OUString path ) throw (DAVException) 24151ba086bSDamjan Jovanovic { 24251ba086bSDamjan Jovanovic setURI( uri, path ); 24351ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 24451ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "PROPPATCH" ); 24551ba086bSDamjan Jovanovic return perform(); 24651ba086bSDamjan Jovanovic } 24751ba086bSDamjan Jovanovic 24851ba086bSDamjan Jovanovic CURLcode CurlRequest::put( CurlUri uri, rtl::OUString path ) throw (DAVException) 24951ba086bSDamjan Jovanovic { 25051ba086bSDamjan Jovanovic setURI( uri, path ); 25151ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_UPLOAD, 1L ); 25251ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "PUT" ); 25351ba086bSDamjan Jovanovic return perform(); 25451ba086bSDamjan Jovanovic } 25551ba086bSDamjan Jovanovic 25651ba086bSDamjan Jovanovic CURLcode CurlRequest::unlock( CurlUri uri, rtl::OUString path ) throw (DAVException) 25751ba086bSDamjan Jovanovic { 25851ba086bSDamjan Jovanovic setURI( uri, path ); 25951ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_HTTPGET, 1L ); 26051ba086bSDamjan Jovanovic curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "UNLOCK" ); 26151ba086bSDamjan Jovanovic return perform(); 26251ba086bSDamjan Jovanovic } 26351ba086bSDamjan Jovanovic 26451ba086bSDamjan Jovanovic CURLcode CurlRequest::perform() throw (DAVException) 26551ba086bSDamjan Jovanovic { 26651ba086bSDamjan Jovanovic CURLcode rc = curl_easy_perform( curl ); 26751ba086bSDamjan Jovanovic long statusCode = 0; 26851ba086bSDamjan Jovanovic curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &statusCode ); 26951ba086bSDamjan Jovanovic if ( ( statusCode == 401 || statusCode == 407 ) && provideCredentialsCallback != NULL ) 27051ba086bSDamjan Jovanovic { 27151ba086bSDamjan Jovanovic bool haveCredentials = provideCredentialsCallback( statusCode, provideCredentialsUserdata ); 27251ba086bSDamjan Jovanovic if ( haveCredentials ) 27351ba086bSDamjan Jovanovic { 27451ba086bSDamjan Jovanovic // rewind body: 27551ba086bSDamjan Jovanovic requestBodyOffset = 0; 27651ba086bSDamjan Jovanovic // retry with credentials: 27751ba086bSDamjan Jovanovic rc = curl_easy_perform( curl ); 27851ba086bSDamjan Jovanovic // If this was to authenticate with the proxy, we may need to authenticate 27951ba086bSDamjan Jovanovic // with the destination host too: 28051ba086bSDamjan Jovanovic if ( statusCode == 407 ) 28151ba086bSDamjan Jovanovic { 28251ba086bSDamjan Jovanovic curl_easy_getinfo( curl, CURLINFO_RESPONSE_CODE, &statusCode ); 28351ba086bSDamjan Jovanovic if ( statusCode == 401 && provideCredentialsCallback != NULL ) 28451ba086bSDamjan Jovanovic { 28551ba086bSDamjan Jovanovic haveCredentials = provideCredentialsCallback( statusCode, provideCredentialsUserdata ); 28651ba086bSDamjan Jovanovic if ( haveCredentials ) 28751ba086bSDamjan Jovanovic { 28851ba086bSDamjan Jovanovic // rewind body: 28951ba086bSDamjan Jovanovic requestBodyOffset = 0; 29051ba086bSDamjan Jovanovic // retry with credentials: 29151ba086bSDamjan Jovanovic rc = curl_easy_perform( curl ); 29251ba086bSDamjan Jovanovic } 29351ba086bSDamjan Jovanovic } 29451ba086bSDamjan Jovanovic } 29551ba086bSDamjan Jovanovic } 29651ba086bSDamjan Jovanovic } 29751ba086bSDamjan Jovanovic return rc; 29851ba086bSDamjan Jovanovic } 29951ba086bSDamjan Jovanovic 30051ba086bSDamjan Jovanovic size_t CurlRequest::Curl_HeaderReceived( char *buffer, size_t size, size_t nitems, void *userdata ) 30151ba086bSDamjan Jovanovic { 30251ba086bSDamjan Jovanovic CurlRequest *request = static_cast< CurlRequest* >( userdata ); 30351ba086bSDamjan Jovanovic OSL_TRACE("Curl_HeaderReceived"); 30451ba086bSDamjan Jovanovic request->curlHeaderReceived( buffer, nitems ); 30551ba086bSDamjan Jovanovic return nitems; 30651ba086bSDamjan Jovanovic } 30751ba086bSDamjan Jovanovic 30851ba086bSDamjan Jovanovic void CurlRequest::curlHeaderReceived( const char *buffer, size_t size ) 30951ba086bSDamjan Jovanovic { 31051ba086bSDamjan Jovanovic rtl::OString lineCrLf( buffer, size ); 31151ba086bSDamjan Jovanovic sal_Int32 cr = lineCrLf.indexOf( "\r" ); 31251ba086bSDamjan Jovanovic if ( cr < 0 ) 31351ba086bSDamjan Jovanovic return; 31451ba086bSDamjan Jovanovic 31551ba086bSDamjan Jovanovic rtl::OString line = lineCrLf.copy( 0, cr ); 31651ba086bSDamjan Jovanovic if ( line.indexOf( "HTTP/" ) == 0 ) 31751ba086bSDamjan Jovanovic { 31851ba086bSDamjan Jovanovic // Status line 31951ba086bSDamjan Jovanovic // Throw away any response headers from a prior response: 32051ba086bSDamjan Jovanovic responseHeaders.clear(); 32151ba086bSDamjan Jovanovic sal_Int32 idxFirstSpace = line.indexOf( ' ' ); 32251ba086bSDamjan Jovanovic if ( idxFirstSpace > 0 ) 32351ba086bSDamjan Jovanovic { 32451ba086bSDamjan Jovanovic int idxSecondSpace = line.indexOf( ' ', idxFirstSpace + 1 ); 32551ba086bSDamjan Jovanovic if ( idxSecondSpace > 0 ) 32651ba086bSDamjan Jovanovic { 32751ba086bSDamjan Jovanovic reasonPhrase = line.copy( idxSecondSpace + 1 ); 32851ba086bSDamjan Jovanovic statusCode = line.copy( idxFirstSpace + 1, idxSecondSpace - idxFirstSpace - 1 ).toInt32(); 32951ba086bSDamjan Jovanovic } 33051ba086bSDamjan Jovanovic else 33151ba086bSDamjan Jovanovic { 33251ba086bSDamjan Jovanovic reasonPhrase = ""; 33351ba086bSDamjan Jovanovic statusCode = line.copy( idxFirstSpace + 1 ).toInt32(); 33451ba086bSDamjan Jovanovic } 33551ba086bSDamjan Jovanovic } 33651ba086bSDamjan Jovanovic } 33751ba086bSDamjan Jovanovic else 33851ba086bSDamjan Jovanovic { 33951ba086bSDamjan Jovanovic // Header line 34051ba086bSDamjan Jovanovic if ( line.getLength() == 0 ) 34151ba086bSDamjan Jovanovic { 34251ba086bSDamjan Jovanovic // End of HTTP header 34351ba086bSDamjan Jovanovic // Discard any intermediate body from 100 Trying or 401 Authentication required: 34451ba086bSDamjan Jovanovic responseBodyInputStream = new CurlInputStream(); 34551ba086bSDamjan Jovanovic return; 34651ba086bSDamjan Jovanovic } 34751ba086bSDamjan Jovanovic sal_Int32 colon = line.indexOf( ':' ); 34851ba086bSDamjan Jovanovic if ( colon < 0 ) 34951ba086bSDamjan Jovanovic { 35051ba086bSDamjan Jovanovic OSL_TRACE("Non-empty HTTP line without a ':'. Folded header deprecated by RFC 7230?"); 35151ba086bSDamjan Jovanovic return; 35251ba086bSDamjan Jovanovic } 35351ba086bSDamjan Jovanovic Header header; 35451ba086bSDamjan Jovanovic header.name = line.copy( 0, colon ).toAsciiLowerCase(); 35551ba086bSDamjan Jovanovic header.value = line.copy( colon + 1 ).trim(); 35651ba086bSDamjan Jovanovic responseHeaders.push_back(header); 35751ba086bSDamjan Jovanovic } 35851ba086bSDamjan Jovanovic } 35951ba086bSDamjan Jovanovic 36051ba086bSDamjan Jovanovic const CurlRequest::Header *CurlRequest::findResponseHeader( const rtl::OString &name ) 36151ba086bSDamjan Jovanovic { 36251ba086bSDamjan Jovanovic std::vector< CurlRequest::Header >::const_iterator it( responseHeaders.begin() ); 36351ba086bSDamjan Jovanovic const std::vector< CurlRequest::Header >::const_iterator end( responseHeaders.end() ); 36451ba086bSDamjan Jovanovic for ( ; it != end; it++ ) 36551ba086bSDamjan Jovanovic { 36651ba086bSDamjan Jovanovic if ( name.equalsIgnoreAsciiCase( it->name ) ) 36751ba086bSDamjan Jovanovic return &(*it); 36851ba086bSDamjan Jovanovic } 36951ba086bSDamjan Jovanovic return NULL; 37051ba086bSDamjan Jovanovic } 37151ba086bSDamjan Jovanovic 37251ba086bSDamjan Jovanovic void CurlRequest::saveResponseBodyTo( const uno::Reference< io::XOutputStream > & xOutStream) 37351ba086bSDamjan Jovanovic { 37451ba086bSDamjan Jovanovic xOutputStream = xOutStream; 37551ba086bSDamjan Jovanovic } 37651ba086bSDamjan Jovanovic 37751ba086bSDamjan Jovanovic size_t CurlRequest::Curl_MoreBodyReceived( char *buffer, size_t size, size_t nitems, void *userdata ) 37851ba086bSDamjan Jovanovic { 37951ba086bSDamjan Jovanovic CurlRequest *request = static_cast< CurlRequest* >( userdata ); 38051ba086bSDamjan Jovanovic request->curlMoreBodyReceived( buffer, nitems ); 38151ba086bSDamjan Jovanovic return nitems; 38251ba086bSDamjan Jovanovic } 38351ba086bSDamjan Jovanovic 38451ba086bSDamjan Jovanovic void CurlRequest::curlMoreBodyReceived( const char *buffer, size_t size ) 38551ba086bSDamjan Jovanovic { 38651ba086bSDamjan Jovanovic if ( xOutputStream.is() ) 38751ba086bSDamjan Jovanovic { 38851ba086bSDamjan Jovanovic const uno::Sequence< sal_Int8 > aDataSeq( (sal_Int8 *)buffer, size ); 38951ba086bSDamjan Jovanovic xOutputStream->writeBytes( aDataSeq ); 39051ba086bSDamjan Jovanovic } 39151ba086bSDamjan Jovanovic else if ( responseBodyInputStream.is() ) 39251ba086bSDamjan Jovanovic responseBodyInputStream->AddToStream( buffer, size ); 39351ba086bSDamjan Jovanovic } 394