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
CurlRequest(CURL * curl)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
~CurlRequest()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
addHeader(const rtl::OString & name,const rtl::OString & value)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
setRequestBody(const char * body,size_t size)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
Curl_SeekCallback(void * userdata,curl_off_t offset,int origin)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
Curl_SendMoreBody(char * buffer,size_t size,size_t nitems,void * userdata)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
curlSendMoreBody(char * buffer,size_t len)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
setProvideCredentialsCallback(bool (* callback)(long statusCode,void * userdata)throw (DAVException),void * userdata)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
setURI(CurlUri uri,rtl::OUString path)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
copy(CurlUri uri,rtl::OUString path)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
delete_(CurlUri uri,rtl::OUString path)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
get(CurlUri uri,rtl::OUString path)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
head(CurlUri uri,rtl::OUString path)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
lock(CurlUri uri,rtl::OUString path)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
mkcol(CurlUri uri,rtl::OUString path)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
move(CurlUri uri,rtl::OUString path)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
post(CurlUri uri,rtl::OUString path)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
propfind(CurlUri uri,rtl::OUString path)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
proppatch(CurlUri uri,rtl::OUString path)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
put(CurlUri uri,rtl::OUString path)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
unlock(CurlUri uri,rtl::OUString path)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
perform()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
Curl_HeaderReceived(char * buffer,size_t size,size_t nitems,void * userdata)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
curlHeaderReceived(const char * buffer,size_t size)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
findResponseHeader(const rtl::OString & name)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
saveResponseBodyTo(const uno::Reference<io::XOutputStream> & xOutStream)37251ba086bSDamjan Jovanovic void CurlRequest::saveResponseBodyTo( const uno::Reference< io::XOutputStream > & xOutStream)
37351ba086bSDamjan Jovanovic {
37451ba086bSDamjan Jovanovic xOutputStream = xOutStream;
37551ba086bSDamjan Jovanovic }
37651ba086bSDamjan Jovanovic
Curl_MoreBodyReceived(char * buffer,size_t size,size_t nitems,void * userdata)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
curlMoreBodyReceived(const char * buffer,size_t size)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