osgEarth 2.1.1
Public Types | Static Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes

osgEarth::HTTPClient Class Reference

Inheritance diagram for osgEarth::HTTPClient:
Collaboration diagram for osgEarth::HTTPClient:

List of all members.

Public Types

enum  ResultCode {
  RESULT_OK, RESULT_CANCELED, RESULT_NOT_FOUND, RESULT_SERVER_ERROR,
  RESULT_TIMEOUT, RESULT_NO_READER, RESULT_READER_ERROR, RESULT_UNKNOWN_ERROR
}

Static Public Member Functions

static bool isRecoverable (ResultCode code)
static std::string getResultCodeString (ResultCode code)
static const std::string & getUserAgent ()
static void setUserAgent (const std::string &userAgent)
static void setProxySettings (const ProxySettings &proxySettings)
static ResultCode readImageFile (const std::string &uri, osg::ref_ptr< osg::Image > &output, const osgDB::ReaderWriter::Options *options=0, ProgressCallback *callback=0)
static ResultCode readNodeFile (const std::string &uri, osg::ref_ptr< osg::Node > &output, const osgDB::ReaderWriter::Options *options=0, ProgressCallback *callback=0)
static ResultCode readObjectFile (const std::string &url, osg::ref_ptr< osg::Object > &output, const osgDB::ReaderWriter::Options *options=0, ProgressCallback *callback=0)
static ResultCode readString (const std::string &uri, std::string &output, ProgressCallback *callback=0)
static bool download (const std::string &uri, const std::string &localPath)
static HTTPResponse get (const HTTPRequest &request, const osgDB::ReaderWriter::Options *=0, ProgressCallback *callback=0)
static HTTPResponse get (const std::string &url, const osgDB::ReaderWriter::Options *options=0, ProgressCallback *callback=0)

Private Member Functions

 HTTPClient ()
 ~HTTPClient ()
void readOptions (const osgDB::ReaderWriter::Options *options, std::string &proxy_host, std::string &proxy_port) const
HTTPResponse doGet (const HTTPRequest &request, const osgDB::ReaderWriter::Options *options=0, ProgressCallback *callback=0) const
HTTPResponse doGet (const std::string &url, const osgDB::ReaderWriter::Options *options=0, ProgressCallback *callback=0) const
ResultCode doReadObjectFile (const std::string &url, osg::ref_ptr< osg::Object > &output, const osgDB::ReaderWriter::Options *options=0, ProgressCallback *callback=0)
ResultCode doReadImageFile (const std::string &filename, osg::ref_ptr< osg::Image > &output, const osgDB::ReaderWriter::Options *options=0, ProgressCallback *callback=0)
ResultCode doReadNodeFile (const std::string &filename, osg::ref_ptr< osg::Node > &output, const osgDB::ReaderWriter::Options *options=0, ProgressCallback *callback=0)
ResultCode doReadString (const std::string &filename, std::string &output, ProgressCallback *callback=0)
bool doDownload (const std::string &url, const std::string &filename)
void decodeMultipartStream (const std::string &boundary, HTTPResponse::Part *input, HTTPResponse::Parts &output) const

Static Private Member Functions

static HTTPClientgetClient ()

Private Attributes

void * _curl_handle
std::string _previousPassword
long _previousHttpAuthentication

Detailed Description

Utility class for making HTTP requests.

TODO: This class will actually read data from disk as well, and therefore should probably be renamed. It analyzes the URI and decides whether to make an HTTP request or to read from disk.

Definition at line 173 of file HTTPClient.


Member Enumeration Documentation

Enumerator:
RESULT_OK 
RESULT_CANCELED 
RESULT_NOT_FOUND 
RESULT_SERVER_ERROR 
RESULT_TIMEOUT 
RESULT_NO_READER 
RESULT_READER_ERROR 
RESULT_UNKNOWN_ERROR 

Definition at line 176 of file HTTPClient.


Constructor & Destructor Documentation

HTTPClient::HTTPClient ( ) [private]

Definition at line 299 of file HTTPClient.cpp.

{
    _previousHttpAuthentication = 0;
    _curl_handle = curl_easy_init();


        //Get the user agent
        std::string userAgent = _userAgent;
        const char* userAgentEnv = getenv("OSGEARTH_USERAGENT");
    if (userAgentEnv)
    {
                userAgent = std::string(userAgentEnv);        
    }

        OE_DEBUG << LC << "HTTPClient setting userAgent=" << userAgent << std::endl;

    curl_easy_setopt( _curl_handle, CURLOPT_USERAGENT, userAgent.c_str() );
    curl_easy_setopt( _curl_handle, CURLOPT_WRITEFUNCTION, osgEarth::StreamObjectReadCallback );
    curl_easy_setopt( _curl_handle, CURLOPT_FOLLOWLOCATION, (void*)1 );
    curl_easy_setopt( _curl_handle, CURLOPT_MAXREDIRS, (void*)5 );
    curl_easy_setopt( _curl_handle, CURLOPT_PROGRESSFUNCTION, &CurlProgressCallback);
    curl_easy_setopt( _curl_handle, CURLOPT_NOPROGRESS, (void*)0 ); //FALSE);
    //curl_easy_setopt( _curl_handle, CURLOPT_TIMEOUT, 1L );
}

Here is the call graph for this function:

Here is the caller graph for this function:

HTTPClient::~HTTPClient ( ) [private]

Definition at line 324 of file HTTPClient.cpp.

{
    if (_curl_handle) curl_easy_cleanup( _curl_handle );
    _curl_handle = 0;
}

Member Function Documentation

void HTTPClient::decodeMultipartStream ( const std::string &  boundary,
HTTPResponse::Part input,
HTTPResponse::Parts output 
) const [private]

Definition at line 397 of file HTTPClient.cpp.

{
    std::string bstr = std::string("--") + boundary;
    std::string line;
    char tempbuf[256];

    // first thing in the stream should be the boundary.
    input->_stream.read( tempbuf, bstr.length() );
    tempbuf[bstr.length()] = 0;
    line = tempbuf;
    if ( line != bstr )
    {
        OE_WARN << LC 
            << "decodeMultipartStream: protocol violation; "
            << "expecting boundary; instead got: \"" 
            << line
            << "\"" << std::endl;
        return;
    }

    for( bool done=false; !done; )
    {
        osg::ref_ptr<HTTPResponse::Part> next_part = new HTTPResponse::Part();

        // first finish off the boundary.
        std::getline( input->_stream, line );
        if ( line == "--" )
        {
            done = true;
        }
        else
        {
            // read all headers. this ends with a blank line.
            line = " ";
            while( line.length() > 0 && !done )
            {
                std::getline( input->_stream, line );

                // check for EOS:
                if ( line == "--" )
                {
                    done = true;
                }
                else
                {
                    std::vector<std::string> tized = tokenize_str( line, ":" );
                    if ( tized.size() >= 2 )
                        next_part->_headers[tized[0]] = tized[1];
                }
            }
        }

        if ( !done )
        {
            // read data until we reach the boundary
            unsigned int bstr_ptr = 0;
            std::string temp;
            //unsigned int c = 0;
            while( bstr_ptr < bstr.length() )
            {
                char b;
                input->_stream.read( &b, 1 );
                if ( b == bstr[bstr_ptr] )
                {
                    bstr_ptr++;
                }
                else
                {
                    for( unsigned int i=0; i<bstr_ptr; i++ )
                    {
                        next_part->_stream << bstr[i];
                    }
                    next_part->_stream << b;
                    next_part->_size += bstr_ptr + 1;
                    bstr_ptr = 0;
                }
            }
            output.push_back( next_part.get() );
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool HTTPClient::doDownload ( const std::string &  url,
const std::string &  filename 
) [private]

Convenience method for downloading a URL directly to a file

Definition at line 761 of file HTTPClient.cpp.

{
    // download the data
    HTTPResponse response = this->doGet( HTTPRequest(url) );

    if ( response.isOK() )
    {
        unsigned int part_num = response.getNumParts() > 1? 1 : 0;
        std::istream& input_stream = response.getPartStream( part_num );

        std::ofstream fout;
        fout.open(filename.c_str(), std::ios::out | std::ios::binary);

        input_stream.seekg (0, std::ios::end);
        int length = input_stream.tellg();
        input_stream.seekg (0, std::ios::beg);

        char *buffer = new char[length];
        input_stream.read(buffer, length);
        fout.write(buffer, length);
        delete[] buffer;
        fout.close();
        return true;
    }
    else
    {
        OE_WARN << LC << "Error downloading file " << filename << std::endl;
        return false;
    } 
}

Here is the call graph for this function:

Here is the caller graph for this function:

HTTPResponse HTTPClient::doGet ( const HTTPRequest request,
const osgDB::ReaderWriter::Options *  options = 0,
ProgressCallback callback = 0 
) const [private]

Definition at line 540 of file HTTPClient.cpp.

{
    OE_DEBUG << LC << "doGet " << request.getURL() << std::endl;

    const osgDB::AuthenticationMap* authenticationMap = (options && options->getAuthenticationMap()) ? 
            options->getAuthenticationMap() :
            osgDB::Registry::instance()->getAuthenticationMap();

    std::string proxy_host;
    std::string proxy_port = "8080";

        std::string proxy_auth;

        //Try to get the proxy settings from the global settings
        if (_proxySettings.isSet())
        {
                proxy_host = _proxySettings.get().hostName();
                std::stringstream buf;
                buf << _proxySettings.get().port();
                proxy_port = buf.str();

                std::string proxy_username = _proxySettings.get().userName();
                std::string proxy_password = _proxySettings.get().password();
                if (!proxy_username.empty() && !proxy_password.empty())
                {
                        proxy_auth = proxy_username + ":" + proxy_password;
                }
        }

        //Try to get the proxy settings from the local options that are passed in.
    readOptions( options, proxy_host, proxy_port );

        //Try to get the proxy settings from the environment variable
    const char* proxyEnvAddress = getenv("OSG_CURL_PROXY");
    if (proxyEnvAddress) //Env Proxy Settings
    {
                proxy_host = std::string(proxyEnvAddress);

        const char* proxyEnvPort = getenv("OSG_CURL_PROXYPORT"); //Searching Proxy Port on Env
                if (proxyEnvPort)
                {
                        proxy_port = std::string( proxyEnvPort );
                }
    }

        const char* proxyEnvAuth = getenv("OSGEARTH_CURL_PROXYAUTH");   
        if (proxyEnvAuth)
        {
                proxy_auth = std::string(proxyEnvAuth);
        }

    // Set up proxy server:
    std::string proxy_addr;
    if ( !proxy_host.empty() )
    {
        std::stringstream buf;
        buf << proxy_host << ":" << proxy_port;
                std::string bufStr;
                bufStr = buf.str();
        proxy_addr = bufStr;
    
        OE_DEBUG << LC << "setting proxy: " << proxy_addr << std::endl;
                //curl_easy_setopt( _curl_handle, CURLOPT_HTTPPROXYTUNNEL, 1 ); 
        curl_easy_setopt( _curl_handle, CURLOPT_PROXY, proxy_addr.c_str() );

                //Setup the proxy authentication if setup
                if (!proxy_auth.empty())
                {
                        OE_DEBUG << LC << "Setting up proxy authentication " << proxy_auth << std::endl;
                        curl_easy_setopt( _curl_handle, CURLOPT_PROXYUSERPWD, proxy_auth.c_str());
                }
    }

    const osgDB::AuthenticationDetails* details = authenticationMap ?
        authenticationMap->getAuthenticationDetails(request.getURL()) :
        0;

        if (details)
        {
            const std::string colon(":");
            std::string password(details->username + colon + details->password);
            curl_easy_setopt(_curl_handle, CURLOPT_USERPWD, password.c_str());
            const_cast<HTTPClient*>(this)->_previousPassword = password;

            // use for https.
            // curl_easy_setopt(_curl, CURLOPT_KEYPASSWD, password.c_str());

#if LIBCURL_VERSION_NUM >= 0x070a07
            if (details->httpAuthentication != _previousHttpAuthentication)
            { 
                curl_easy_setopt(_curl_handle, CURLOPT_HTTPAUTH, details->httpAuthentication); 
                const_cast<HTTPClient*>(this)->_previousHttpAuthentication = details->httpAuthentication;
            }
#endif
    }
    else
    {
        if (!_previousPassword.empty())
        {
            curl_easy_setopt(_curl_handle, CURLOPT_USERPWD, 0);
            const_cast<HTTPClient*>(this)->_previousPassword.clear();
        }

#if LIBCURL_VERSION_NUM >= 0x070a07
        // need to reset if previously set.
        if (_previousHttpAuthentication!=0)
        {
            curl_easy_setopt(_curl_handle, CURLOPT_HTTPAUTH, 0); 
            const_cast<HTTPClient*>(this)->_previousHttpAuthentication = 0;
        }
#endif
    }

    osg::ref_ptr<HTTPResponse::Part> part = new HTTPResponse::Part();
    StreamObject sp( &part->_stream );

    //Take a temporary ref to the callback
    osg::ref_ptr<ProgressCallback> progressCallback = callback;
    curl_easy_setopt( _curl_handle, CURLOPT_URL, request.getURL().c_str() );
    if (callback)
    {
        curl_easy_setopt(_curl_handle, CURLOPT_PROGRESSDATA, progressCallback.get());
    }

    char errorBuf[CURL_ERROR_SIZE];
    errorBuf[0] = 0;
    curl_easy_setopt( _curl_handle, CURLOPT_ERRORBUFFER, (void*)errorBuf );

    curl_easy_setopt( _curl_handle, CURLOPT_WRITEDATA, (void*)&sp);
    CURLcode res = curl_easy_perform( _curl_handle );
    curl_easy_setopt( _curl_handle, CURLOPT_WRITEDATA, (void*)0 );
    curl_easy_setopt( _curl_handle, CURLOPT_PROGRESSDATA, (void*)0);

    long response_code = 0L;
        if (!proxy_addr.empty())
        {
                long connect_code = 0L;
        curl_easy_getinfo( _curl_handle, CURLINFO_HTTP_CONNECTCODE, &connect_code );
                OE_DEBUG << LC << "proxy connect code " << connect_code << std::endl;
        }
        
    curl_easy_getinfo( _curl_handle, CURLINFO_RESPONSE_CODE, &response_code );     

        OE_DEBUG << LC << "got response, code = " << response_code << std::endl;

    HTTPResponse response( response_code );
   
    if ( response_code == 200L && res != CURLE_ABORTED_BY_CALLBACK && res != CURLE_OPERATION_TIMEDOUT ) //res == 0 )
    {
        // check for multipart content:
        char* content_type_cp;
        curl_easy_getinfo( _curl_handle, CURLINFO_CONTENT_TYPE, &content_type_cp );
        if ( content_type_cp == NULL )
        {
            OE_NOTICE << LC
                << "NULL Content-Type (protocol violation) " 
                << "URL=" << request.getURL() << std::endl;
            return NULL;
        }

        // NOTE:
        //   WCS 1.1 specified a "multipart/mixed" response, but ArcGIS Server gives a "multipart/related"
        //   content type ...

        std::string content_type( content_type_cp );
        //OE_NOTICE << "[osgEarth.HTTPClient] content-type = \"" << content_type << "\"" << std::endl;
        if ( content_type.length() > 9 && ::strstr( content_type.c_str(), "multipart" ) == content_type.c_str() )
        //if ( content_type == "multipart/mixed; boundary=wcs" ) //todo: parse this.
        {
            //OE_NOTICE << "[osgEarth.HTTPClient] detected multipart data; decoding..." << std::endl;
            //TODO: parse out the "wcs" -- this is WCS-specific
            decodeMultipartStream( "wcs", part.get(), response._parts );
        }
        else
        {
            //OE_NOTICE << "[osgEarth.HTTPClient] detected single part data" << std::endl;
            response._parts.push_back( part.get() );
        }
    }
    else if (res == CURLE_ABORTED_BY_CALLBACK || res == CURLE_OPERATION_TIMEDOUT)
    {
        //If we were aborted by a callback, then it was cancelled by a user
        response._cancelled = true;
    }
    else
    {        
        //if ( callback )
        //{
        //    if ( errorBuf[0] ) {
        //        callback->message() = errorBuf;
        //    }
        //    else {
        //        std::stringstream buf;
        //        buf << "HTTP Code " << response.getCode();
        //        callback->message() = buf.str();
        //    }
        //}
        //else {
        //    OE_NOTICE << "[osgEarth] [HTTP] error, code = " << code << std::endl;
        //}
    }

    // Store the mime-type, if any. (Note: CURL manages the buffer returned by
    // this call.)
    char* ctbuf = NULL;
    if ( curl_easy_getinfo(_curl_handle, CURLINFO_CONTENT_TYPE, &ctbuf) == 0 && ctbuf )
    {
        response._mimeType = ctbuf;
    }

    return response;
}

Here is the call graph for this function:

Here is the caller graph for this function:

HTTPResponse HTTPClient::doGet ( const std::string &  url,
const osgDB::ReaderWriter::Options *  options = 0,
ProgressCallback callback = 0 
) const [private]

Definition at line 755 of file HTTPClient.cpp.

{
    return doGet( HTTPRequest( url ), options, callback );
}

Here is the call graph for this function:

HTTPClient::ResultCode HTTPClient::doReadImageFile ( const std::string &  filename,
osg::ref_ptr< osg::Image > &  output,
const osgDB::ReaderWriter::Options *  options = 0,
osgEarth::ProgressCallback callback = 0 
) [private]

Definition at line 818 of file HTTPClient.cpp.

{
    ResultCode result = RESULT_OK;

    if ( osgDB::containsServerAddress( filename ) )
    {
        HTTPResponse response = this->doGet(filename, options, callback);

        if (response.isOK())
        {
            osgDB::ReaderWriter* reader = getReader(filename, response);
            if (!reader)
            {
                OE_WARN << LC << "Can't find an OSG plugin to read "<<filename<<std::endl;
                result = RESULT_NO_READER;
            }

            else 
            {
                osgDB::ReaderWriter::ReadResult rr = reader->readImage(response.getPartStream(0), options);
                if ( rr.validImage() )
                {
                    output = rr.takeImage();
                }
                else 
                {
                    if ( !rr.message().empty() )
                    {
                        OE_WARN << LC << "HTTP error: " << rr.message() << std::endl;
                    }
                    OE_WARN << LC << reader->className() << " failed to read image from " << filename << std::endl;
                    result = RESULT_READER_ERROR;
                }
            }
        }
        else
        {
            result =
                response.isCancelled() ? RESULT_CANCELED :
                response.getCode() == HTTPResponse::NOT_FOUND ? RESULT_NOT_FOUND :
                response.getCode() == HTTPResponse::SERVER_ERROR ? RESULT_SERVER_ERROR :
                RESULT_UNKNOWN_ERROR;

            //If we have an error but it's recoverable, like a server error or timeout then set the callback to retry.
            if (HTTPClient::isRecoverable( result ) )
            {
                if (callback)
                {
                    OE_DEBUG << "Error in HTTPClient for " << filename << " but it's recoverable" << std::endl;
                    callback->setNeedsRetry( true );
                }
            }

            //if ( response.isCancelled() )
            //    OE_NOTICE << "HTTP cancel: " << filename << std::endl;
            //else
            //    OE_NOTICE << "HTTP ERROR " << response.getCode() << ": " << filename << std::endl;

            /*if (response.isCancelled())
                OE_NOTICE << "Request for " << filename << " was cancelled " << std::endl;*/
        }
    }
    else
    {
        output = osgDB::readImageFile( filename, options );
        if ( !output.valid() )
            result = RESULT_NOT_FOUND;
    }

    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

HTTPClient::ResultCode HTTPClient::doReadNodeFile ( const std::string &  filename,
osg::ref_ptr< osg::Node > &  output,
const osgDB::ReaderWriter::Options *  options = 0,
osgEarth::ProgressCallback callback = 0 
) [private]

Definition at line 894 of file HTTPClient.cpp.

{
    ResultCode result = RESULT_OK;

    if ( osgDB::containsServerAddress( filename ) )
    {
        HTTPResponse response = this->doGet(filename, options, callback);
        if (response.isOK())
        {
            osgDB::ReaderWriter* reader = getReader(filename, response);
            if (!reader)
            {
                OE_NOTICE<<LC<<"Error: No ReaderWriter for file "<<filename<<std::endl;
                result = RESULT_NO_READER;
            }

            else
            {
                osgDB::ReaderWriter::ReadResult rr = reader->readNode(response.getPartStream(0), options);
                if ( rr.validNode() )
                {
                    output = rr.takeNode();
                }
                else
                {
                    if ( rr.error() )
                    {
                        OE_WARN << LC << "HTTP Reader Error: " << rr.message() << std::endl;
                    }
                    result = RESULT_READER_ERROR;
                }
            }
        }
        else
        {
            result =
                response.isCancelled() ? RESULT_CANCELED :
                response.getCode() == HTTPResponse::NOT_FOUND ? RESULT_NOT_FOUND :
                response.getCode() == HTTPResponse::SERVER_ERROR ? RESULT_SERVER_ERROR :
                RESULT_UNKNOWN_ERROR;

            //If we have an error but it's recoverable, like a server error or timeout then set the callback to retry.
            if (HTTPClient::isRecoverable( result ) )
            {
                if (callback)
                {
                    OE_DEBUG << "Error in HTTPClient for " << filename << " but it's recoverable" << std::endl;
                    callback->setNeedsRetry( true );
                }
            }
               
            /*if (response.isCancelled())
                OE_NOTICE << "Request for " << filename << " was cancelled " << std::endl;*/
        }
    }
    else
    {
        output = osgDB::readNodeFile( filename, options );
        if ( !output.valid() )
            result = RESULT_NOT_FOUND;
    }

    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

HTTPClient::ResultCode HTTPClient::doReadObjectFile ( const std::string &  url,
osg::ref_ptr< osg::Object > &  output,
const osgDB::ReaderWriter::Options *  options = 0,
osgEarth::ProgressCallback callback = 0 
) [private]

Definition at line 963 of file HTTPClient.cpp.

{
    ResultCode result = RESULT_OK;

    if ( osgDB::containsServerAddress( url ) )
    {
        HTTPResponse response = this->doGet(url, options, callback);
        if ( response.isOK() )
        {
            osgDB::ReaderWriter* reader = getReader( url, response );
            if ( !reader )
            {
                OE_WARN << LC << "Error: No ReaderWriter for file " << url << std::endl;
                result = RESULT_NO_READER;
            }
            else
            {
                osgDB::ReaderWriter::ReadResult rr = reader->readObject( response.getPartStream(0), options );
                if ( rr.validNode() )
                {
                    output = rr.takeObject();
                }
                else
                {
                    if ( rr.error() )
                    {
                        OE_WARN << LC << "HTTP Reader Error: " << rr.message() << std::endl;
                    }
                    result = RESULT_READER_ERROR;
                }
            }
        }
        else
        {
            result =
                response.isCancelled() ? RESULT_CANCELED :
                response.getCode() == HTTPResponse::NOT_FOUND ? RESULT_NOT_FOUND :
                response.getCode() == HTTPResponse::SERVER_ERROR ? RESULT_SERVER_ERROR :
                RESULT_UNKNOWN_ERROR;

            //If we have an error but it's recoverable, like a server error or timeout then set the callback to retry.
            if (HTTPClient::isRecoverable( result ) )
            {
                if (callback)
                {
                    OE_DEBUG << "Error in HTTPClient for " << url << " but it's recoverable" << std::endl;
                    callback->setNeedsRetry( true );
                }
            }
        }
    }
    else
    {
        output = osgDB::readObjectFile( url, options );
        if ( !output.valid() )
            result = RESULT_NOT_FOUND;
    }

    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

HTTPClient::ResultCode HTTPClient::doReadString ( const std::string &  filename,
std::string &  output,
osgEarth::ProgressCallback callback = 0 
) [private]

Definition at line 1029 of file HTTPClient.cpp.

{
    ResultCode result = RESULT_OK;

    if ( osgDB::containsServerAddress( filename ) )
    {
        HTTPResponse response = this->doGet( filename, NULL, callback );
        if ( response.isOK() )
        {
            output = response.getPartAsString( 0 );
        }
        else
        {
            result =
                response.isCancelled() ? RESULT_CANCELED :
                response.getCode() == HTTPResponse::NOT_FOUND ? RESULT_NOT_FOUND :
                response.getCode() == HTTPResponse::SERVER_ERROR ? RESULT_SERVER_ERROR :
                RESULT_UNKNOWN_ERROR;

            //If we have an error but it's recoverable, like a server error or timeout then set the callback to retry.
            if (HTTPClient::isRecoverable( result ) )
            {
                if (callback)
                {
                    OE_DEBUG << "Error in HTTPClient for " << filename << " but it's recoverable" << std::endl;
                    callback->setNeedsRetry( true );
                }
            }
        }
    }
    else
    {
        std::ifstream input( filename.c_str() );
        if ( input.is_open() )
        {
            input >> std::noskipws;
            std::stringstream buf;
            buf << input.rdbuf();
                        std::string bufStr;
                    bufStr = buf.str();
            output = bufStr;
        }
        else
        {
            result = RESULT_NOT_FOUND;
        }
    }

    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

bool HTTPClient::download ( const std::string &  uri,
const std::string &  localPath 
) [static]

Downloads a file directly to disk.

Definition at line 533 of file HTTPClient.cpp.

{
    return getClient().doDownload( uri, localPath );
}

Here is the call graph for this function:

HTTPResponse HTTPClient::get ( const HTTPRequest request,
const osgDB::ReaderWriter::Options *  options = 0,
ProgressCallback callback = 0 
) [static]

Performs an HTTP "GET".

Definition at line 482 of file HTTPClient.cpp.

{
    return getClient().doGet( request, options, callback );
}

Here is the call graph for this function:

Here is the caller graph for this function:

HTTPResponse HTTPClient::get ( const std::string &  url,
const osgDB::ReaderWriter::Options *  options = 0,
ProgressCallback callback = 0 
) [static]

Definition at line 490 of file HTTPClient.cpp.

{
    return getClient().doGet( url, options, callback);
}

Here is the call graph for this function:

HTTPClient & HTTPClient::getClient ( ) [static, private]

Definition at line 261 of file HTTPClient.cpp.

{
#if 1
    static Threading::PerThread< osg::ref_ptr<HTTPClient> > s_clientPerThread;

    osg::ref_ptr<HTTPClient>& client = s_clientPerThread.get();
    if ( !client.valid() )
        client = new HTTPClient();

    return *client.get();
#else
    typedef std::map< OpenThreads::Thread*, osg::ref_ptr<HTTPClient> > ThreadClientMap;        
    static Threading::ReadWriteMutex   _threadClientMapMutex;
    static ThreadClientMap             _threadClientMap;

    OpenThreads::Thread* current = OpenThreads::Thread::CurrentThread();

    // first try the map:
    {
        Threading::ScopedReadLock sharedLock(_threadClientMapMutex);
        ThreadClientMap::iterator i = _threadClientMap.find(current);
        if ( i != _threadClientMap.end() )
            return *i->second.get();
    }

    // not there; add it.
    {
        Threading::ScopedWriteLock exclusiveLock(_threadClientMapMutex);

        // normally, we'd double check b/c of the race condition, but since the map is being 
        // indexed by the actual thread pointer, there's no chance of a race.
        HTTPClient* client = new HTTPClient();
        _threadClientMap[current] = client;
        return *client;
    }
#endif
}

Here is the call graph for this function:

Here is the caller graph for this function:

static std::string osgEarth::HTTPClient::getResultCodeString ( ResultCode  code) [inline, static]

Definition at line 200 of file HTTPClient.

        {
            return
                code == RESULT_OK ? "OK" :
                code == RESULT_CANCELED ? "Read canceled" :
                code == RESULT_NOT_FOUND ? "Target not found" :
                code == RESULT_SERVER_ERROR ? "Server error" :
                code == RESULT_TIMEOUT ? "Read timed out" :
                code == RESULT_NO_READER ? "No suitable ReaderWriter found" :
                code == RESULT_READER_ERROR ? "ReaderWriter error" :
                "Unknown error";
        }

Here is the caller graph for this function:

const std::string & HTTPClient::getUserAgent ( ) [static]

Gest the user-agent string that all HTTP requests will use. TODO: This should probably move into the Registry

Definition at line 336 of file HTTPClient.cpp.

{
        return _userAgent;
}
static bool osgEarth::HTTPClient::isRecoverable ( ResultCode  code) [inline, static]

Returns true is the result code represents a recoverable situation, i.e. one in which retrying might work.

Definition at line 191 of file HTTPClient.

        {
            return
                code == RESULT_OK ||
                code == RESULT_SERVER_ERROR ||
                code == RESULT_TIMEOUT ||
                code == RESULT_CANCELED;
        }

Here is the caller graph for this function:

HTTPClient::ResultCode HTTPClient::readImageFile ( const std::string &  uri,
osg::ref_ptr< osg::Image > &  output,
const osgDB::ReaderWriter::Options *  options = 0,
osgEarth::ProgressCallback callback = 0 
) [static]

Reads an image. Based on the structure of the URI, it will either try to fetch the data using HTTP or simply read the file from disk.

Definition at line 498 of file HTTPClient.cpp.

{
    return getClient().doReadImageFile( filename, output, options, callback );
}

Here is the call graph for this function:

Here is the caller graph for this function:

HTTPClient::ResultCode HTTPClient::readNodeFile ( const std::string &  uri,
osg::ref_ptr< osg::Node > &  output,
const osgDB::ReaderWriter::Options *  options = 0,
osgEarth::ProgressCallback callback = 0 
) [static]

Reads an osg::Node. Based on the structure of the URI, it will either try to fetch the data using HTTP or simply read the file from disk.

Definition at line 507 of file HTTPClient.cpp.

{
    return getClient().doReadNodeFile( filename, output, options, callback );
}

Here is the call graph for this function:

Here is the caller graph for this function:

HTTPClient::ResultCode HTTPClient::readObjectFile ( const std::string &  url,
osg::ref_ptr< osg::Object > &  output,
const osgDB::ReaderWriter::Options *  options = 0,
ProgressCallback callback = 0 
) [static]

Reads an object. Based on the structure of the URI, it will either try to fetch the data using HTTP or simply read the file from disk.

Definition at line 516 of file HTTPClient.cpp.

{
    return getClient().doReadObjectFile( url, output, options, callback );
}

Here is the call graph for this function:

Here is the caller graph for this function:

void HTTPClient::readOptions ( const osgDB::ReaderWriter::Options *  options,
std::string &  proxy_host,
std::string &  proxy_port 
) const [private]

Definition at line 347 of file HTTPClient.cpp.

{
    // try to set proxy host/port by reading the CURL proxy options
    if ( options )
    {
        std::istringstream iss( options->getOptionString() );
        std::string opt;
        while( iss >> opt )
        {
            int index = opt.find( "=" );
            if( opt.substr( 0, index ) == "OSG_CURL_PROXY" )
            {
                proxy_host = opt.substr( index+1 );
            }
            else if ( opt.substr( 0, index ) == "OSG_CURL_PROXYPORT" )
            {
                proxy_port = opt.substr( index+1 );
            }
        }
    }
}

Here is the caller graph for this function:

HTTPClient::ResultCode HTTPClient::readString ( const std::string &  uri,
std::string &  output,
osgEarth::ProgressCallback callback = 0 
) [static]

Reads a string. Based on the structure of the URI, it will either try to fetch the data using HTTP or simply read the file from disk.

Definition at line 525 of file HTTPClient.cpp.

{
    return getClient().doReadString( filename, output, callback );
}

Here is the call graph for this function:

Here is the caller graph for this function:

void HTTPClient::setProxySettings ( const ProxySettings proxySettings) [static]

Sets up proxy info to use in all HTTP requests. TODO: This should probably move into the Registry

Definition at line 331 of file HTTPClient.cpp.

{
        _proxySettings = proxySettings;
}

Here is the caller graph for this function:

void HTTPClient::setUserAgent ( const std::string &  userAgent) [static]

Sets a user-agent string to use in all HTTP requests. TODO: This should probably move into the Registry

Definition at line 341 of file HTTPClient.cpp.

{
        _userAgent = userAgent;
}

Member Data Documentation

Definition at line 330 of file HTTPClient.

Definition at line 332 of file HTTPClient.

Definition at line 331 of file HTTPClient.


The documentation for this class was generated from the following files:
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines