Added osgDB::AuthenticationMap/Details to osgDB and curl plugin to add the ability

to authenticate http transfers
This commit is contained in:
Robert Osfield
2008-07-17 11:55:55 +00:00
parent a6c72dc21c
commit adaf71fa19
5 changed files with 164 additions and 11 deletions

View File

@@ -32,6 +32,54 @@ class Archive;
/** list of directories to search through which searching for files. */
typedef std::deque<std::string> FilePathList;
class AuthenticationDetails : public osg::Referenced
{
public:
/** Http authentication techniques, see libcurl docs for details on names and associated functionality.*/
enum HttpAuthentication
{
BASIC = 1<<0,
DIGEST = 1<<1,
NTLM = 1<<2,
GSSNegotiate = 1<<2,
ANY = ~0,
ANYSAFE = ~BASIC
};
AuthenticationDetails(const std::string& u, const std::string& p, HttpAuthentication auth=BASIC):
username(u),
password(p),
httpAuthentication(auth) {}
std::string username;
std::string password;
HttpAuthentication httpAuthentication;
protected:
virtual ~AuthenticationDetails() {}
};
class OSGDB_EXPORT AuthenticationMap : public osg::Referenced
{
public:
AuthenticationMap() {}
virtual void addAuthenticationDetails(const std::string& path, AuthenticationDetails* details);
virtual const AuthenticationDetails* getAuthenticationDetails(const std::string& path) const;
protected:
virtual ~AuthenticationMap() {}
typedef std::map<std::string, osg::ref_ptr<AuthenticationDetails> > AuthenticationDetailsMap;
AuthenticationDetailsMap _authenticationMap;
};
/** pure virtual base class for reading and writing of non native formats. */
class OSGDB_EXPORT ReaderWriter : public osg::Object
{
@@ -159,6 +207,12 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object
BuildKdTreesHint getBuildKdTreesHint() const { return _buildKdTreesHint; }
/** Set the password map to be used by plugins when access files from secure locations.*/
void setAuthenticationMap(AuthenticationMap* authenticationMap) { _authenticationMap = authenticationMap; }
/** Get the password map to be used by plugins when access files from secure locations.*/
const AuthenticationMap* getAuthenticationMap() const { return _authenticationMap.get(); }
/** Sets a plugindata value PluginData with a string */
void setPluginData(const std::string& s, void* v) const { _pluginData[s] = v; }
@@ -180,10 +234,11 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object
virtual ~Options() {}
std::string _str;
FilePathList _databasePaths;
CacheHintOptions _objectCacheHint;
BuildKdTreesHint _buildKdTreesHint;
std::string _str;
FilePathList _databasePaths;
CacheHintOptions _objectCacheHint;
BuildKdTreesHint _buildKdTreesHint;
osg::ref_ptr<AuthenticationMap> _authenticationMap;
typedef std::map<std::string,void*> PluginDataMap;
mutable PluginDataMap _pluginData;
@@ -247,6 +302,7 @@ class OSGDB_EXPORT ReaderWriter : public osg::Object
ReadStatus _status;
std::string _message;
osg::ref_ptr<osg::Object> _object;
};
class WriteResult

View File

@@ -334,16 +334,29 @@ class OSGDB_EXPORT Registry : public osg::Referenced
}
/** Set whether the KdTrees should be built for geometry in the loader model. */
void setBuildKdTreesHint(ReaderWriter::Options::BuildKdTreesHint hint) { _buildKdTreesHint = hint; }
/** Get whether the KdTrees should be built for geometry in the loader model. */
ReaderWriter::Options::BuildKdTreesHint getBuildKdTreesHint() const { return _buildKdTreesHint; }
/** Set the KdTreeBuilder visitor that is used to build KdTree on loaded models.*/
void setKdTreeBuilder(osg::KdTreeBuilder* builder) { _kdTreeBuilder = builder; }
/** Get the KdTreeBuilder visitor that is used to build KdTree on loaded models.*/
osg::KdTreeBuilder* getKdTreeBuilder() { return _kdTreeBuilder.get(); }
/** Set the password map to be used by plugins when access files from secure locations.*/
void setAuthenticationMap(AuthenticationMap* authenticationMap) { _authenticationMap = authenticationMap; }
/** Get the password map to be used by plugins when access files from secure locations.*/
const AuthenticationMap* getAuthenticationMap() const { return _authenticationMap.get(); }
void setCreateNodeFromImage(bool flag) { _createNodeFromImage = flag; }
bool getCreateNodeFromImage() const { return _createNodeFromImage; }
void setOptions(ReaderWriter::Options* opt) { _options = opt; }
ReaderWriter::Options* getOptions() { return _options.get(); }
@@ -478,6 +491,8 @@ class OSGDB_EXPORT Registry : public osg::Referenced
ReaderWriter::Options::BuildKdTreesHint _buildKdTreesHint;
osg::ref_ptr<osg::KdTreeBuilder> _kdTreeBuilder;
osg::ref_ptr<AuthenticationMap> _authenticationMap;
bool _createNodeFromImage;
osg::Object* readObject(DotOsgWrapperMap& dowMap,Input& fr);

View File

@@ -15,8 +15,43 @@
#include <osgDB/FileNameUtils>
#include <osgDB/Archive>
#include <map>
using namespace osgDB;
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// PasswordMap
//
void AuthenticationMap::addAuthenticationDetails(const std::string& path, AuthenticationDetails* details)
{
_authenticationMap[path] = details;
}
const AuthenticationDetails* AuthenticationMap::getAuthenticationDetails(const std::string& path) const
{
// see if the full filename has its own authentication details
AuthenticationDetailsMap::const_iterator itr = _authenticationMap.find(path);
if (itr != _authenticationMap.end()) return itr->second.get();
// now look to see if the paths to the file have their own authentication details
std::string basePath = osgDB::getFilePath(path);
while(!basePath.empty())
{
itr = _authenticationMap.find(basePath);
if (itr != _authenticationMap.end()) return itr->second.get();
basePath = osgDB::getFilePath(basePath);
}
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////
//
// ReaderWriter
//
osg::Object* ReaderWriter::ReadResult::getObject() { return _object.get(); }
osg::Image* ReaderWriter::ReadResult::getImage() { return dynamic_cast<osg::Image*>(_object.get()); }
osg::HeightField* ReaderWriter::ReadResult::getHeightField() { return dynamic_cast<osg::HeightField*>(_object.get()); }

View File

@@ -75,6 +75,8 @@ size_t EasyCurl::StreamMemoryCallback(void *ptr, size_t size, size_t nmemb, void
EasyCurl::EasyCurl()
{
osg::notify(osg::INFO)<<"EasyCurl::EasyCurl()"<<std::endl;
_previousHttpAuthentication = 0;
_curl = curl_easy_init();
@@ -92,14 +94,55 @@ EasyCurl::~EasyCurl()
}
osgDB::ReaderWriter::ReadResult EasyCurl::read(const std::string& proxyAddress, const std::string& fileName, StreamObject& sp)
osgDB::ReaderWriter::ReadResult EasyCurl::read(const std::string& proxyAddress, const std::string& fileName, StreamObject& sp, const osgDB::ReaderWriter::Options *options)
{
const osgDB::AuthenticationMap* authenticationMap = (options && options->getAuthenticationMap()) ?
options->getAuthenticationMap() :
osgDB::Registry::instance()->getAuthenticationMap();
if(!proxyAddress.empty())
{
osg::notify(osg::NOTICE)<<"Setting proxy: "<<proxyAddress<<std::endl;
osg::notify(osg::INFO)<<"Setting proxy: "<<proxyAddress<<std::endl;
curl_easy_setopt(_curl, CURLOPT_PROXY, proxyAddress.c_str()); //Sets proxy address and port on libcurl
}
const osgDB::AuthenticationDetails* details = authenticationMap ?
authenticationMap->getAuthenticationDetails(fileName) :
0;
// configure/reset authentication if required.
if (details)
{
const std::string colon(":");
std::string password(details->username + colon + details->password);
curl_easy_setopt(_curl, CURLOPT_USERPWD, password.c_str());
_previousPassword = password;
// use for https.
// curl_easy_setopt(_curl, CURLOPT_KEYPASSWD, password.c_str());
if (details->httpAuthentication != _previousHttpAuthentication)
{
curl_easy_setopt(_curl, CURLOPT_HTTPAUTH, details->httpAuthentication);
_previousHttpAuthentication = details->httpAuthentication;
}
}
else
{
if (!_previousPassword.empty())
{
curl_easy_setopt(_curl, CURLOPT_USERPWD, 0);
_previousPassword.clear();
}
// need to reset if previously set.
if (_previousHttpAuthentication!=0)
{
curl_easy_setopt(_curl, CURLOPT_HTTPAUTH, 0);
_previousHttpAuthentication = 0;
}
}
curl_easy_setopt(_curl, CURLOPT_URL, fileName.c_str());
curl_easy_setopt(_curl, CURLOPT_WRITEDATA, (void *)&sp);
@@ -248,12 +291,13 @@ osgDB::ReaderWriter::ReadResult ReaderWriterCURL::readFile(ObjectType objectType
EasyCurl::StreamObject sp(&buffer, std::string());
ReadResult curlResult = getEasyCurl().read(proxyAddress, fileName, sp);
ReadResult curlResult = getEasyCurl().read(proxyAddress, fileName, sp, options);
if (curlResult.status()==ReadResult::FILE_LOADED)
{
osg::ref_ptr<Options> local_opt = const_cast<Options*>(options);
if (!local_opt) local_opt = new Options;
osg::ref_ptr<Options> local_opt = options ?
static_cast<Options*>(options->clone(osg::CopyOp::SHALLOW_COPY)) :
new Options;
local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName));

View File

@@ -50,7 +50,7 @@ class EasyCurl : public osg::Referenced
EasyCurl();
osgDB::ReaderWriter::ReadResult read(const std::string& proxyAddress, const std::string& fileName, StreamObject& sp);
osgDB::ReaderWriter::ReadResult read(const std::string& proxyAddress, const std::string& fileName, StreamObject& sp, const osgDB::ReaderWriter::Options *options);
protected:
@@ -62,6 +62,9 @@ class EasyCurl : public osg::Referenced
CURL* _curl;
std::string _previousPassword;
long _previousHttpAuthentication;
};