Added two options to the .net loader:

hostname=<hostname>  - Specify the host to connect to to retreive files
  server_prefix=<directory> - Specify a prefix to each file indicating
                              a directory for the server to look into
Also, the .net server now does not require a file to have the .net
suffix.  ALl this together now means that you can do this:

    osgviewer -e net -O "hostname=openscenegraph.org server_prefix=BlueMarble" earth.ive

And view the whole earth streamed from a server.
This commit is contained in:
Don BURNS
2004-08-29 00:57:02 +00:00
parent 3e74db50e5
commit 2f4a384fa9
2 changed files with 148 additions and 29 deletions

View File

@@ -1,7 +1,8 @@
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <osg/Notify>
#include <osgDB/Input>
#include <osgDB/Registry>
@@ -13,14 +14,27 @@
#include "sockinet.h"
extern bool goGetTheFile(const std::string &host, const std::string & file, const std::string &saveDir );
/*
* Semantics:
* Two methods for using the .net loader.
* 1) Add a hostname prefix and a '.net' suffix on a model when passing
* to osgDB::readNodeFile()
* e.g: osgDB::readNodeFile( "openscenegraph.org:cow.osg.net" );
*
* 2) Explicitely load the .net plugin and pass the plugin options including
* hostname=<hostname>
*
* Method #1 takes precedence. SO, if the hostname option is passed the
* plugin, but the name also contains a hostname prefix, the hostname
* prefix on the file name will override the option
*/
class NetReader : public osgDB::ReaderWriter
{
public:
NetReader() {}
virtual const char* className() { return "Network Reader"; }
virtual const char* className() { return "HTTP Protocol Model Reader"; }
virtual bool acceptsExtension(const std::string& extension)
{
@@ -30,39 +44,144 @@ class NetReader : public osgDB::ReaderWriter
virtual ReadResult readObject(const std::string& fileName, const Options* opt)
{ return readNode(fileName,opt); }
virtual ReadResult readNode(const std::string& fileName, const Options* )
virtual ReadResult readNode(const std::string& inFileName, const Options *options )
{
std::string ext = osgDB::getFileExtension(fileName);
std::string hostname;
std::string server_prefix;
int port = 80;
if (options)
{
std::istringstream iss(options->getOptionString());
std::string opt;
while (iss >> opt)
{
int index = opt.find( "=" );
if( opt.substr( 0, index ) == "hostname" ||
opt.substr( 0, index ) == "HOSTNAME" )
{
hostname = opt.substr( index+1 );
}
else if( opt.substr( 0, index ) == "port" ||
opt.substr( 0, index ) == "PORT" )
{
port = atoi( opt.substr(index+1).c_str() );
}
else if( opt.substr( 0, index ) == "server_prefix" ||
opt.substr( 0, index ) == "server_prefix" )
{
server_prefix = opt.substr(index+1);
}
}
}
/* * we accept all extensions
std::string ext = osgDB::getFileExtension(inFileName);
if (!acceptsExtension(ext))
return ReadResult::FILE_NOT_HANDLED;
*/
int index = fileName.find(":");
if( index == -1 )
return ReadResult::FILE_NOT_HANDLED;
std::string fileName;
int index = inFileName.find(":");
// If we haven't been given a hostname as an option
// and it hasn't been prefixed to the name, we fail
if( index != -1 )
{
hostname = inFileName.substr( 0, index);
// need to strip the inFileName of the hostname prefix
fileName = inFileName.substr( index+1 );
}
else
{
if( hostname.empty() )
return ReadResult::FILE_NOT_HANDLED;
else
fileName = inFileName;
}
std::string host = fileName.substr( 0, index);
int rindex = fileName.rfind( "." );
std::string file = fileName.substr( index+1, rindex-index-1 );
// Let's also strip the possible .net extension
if( osgDB::getFileExtension( fileName ) == "net" )
{
int rindex = fileName.rfind( "." );
fileName = fileName.substr( 0, rindex );
}
iosockinet sio (sockbuf::sock_stream);
sio->connect( host.c_str(), 80 );
sio << "GET /" << file << " HTTP/1.1\n" << "Host:\n\n";
try {
sio->connect( hostname.c_str(), port );
}
catch( sockerr e )
{
osg::notify(osg::WARN) << "osgPlugin .net reader: Unable to connect to host " << hostname << std::endl;
return ReadResult::FILE_NOT_FOUND;
}
if( !server_prefix.empty() )
fileName = server_prefix + '/' + fileName;
sio << "GET /" << fileName << " HTTP/1.1\n" << "Host:\n\n";
sio.flush();
char linebuff[256];
do
{
sio.getline( linebuff, sizeof( linebuff ));
std::istringstream iss(linebuff);
std::string directive;
iss >> directive;
if( directive.substr(0,4) == "HTTP" )
{
iss >> directive;
// Code 200. We be ok.
if( directive == "200" )
;
// Code 400 Bad Request
else if( directive == "400" )
{
osg::notify(osg::WARN) <<
"osgPluing .net: http server response 400 - Bad Request" << std::endl;
return ReadResult::FILE_NOT_FOUND;
}
// Code 401 Bad Request
else if( directive == "401" )
{
osg::notify(osg::WARN) <<
"osgPluing .net: http server response 401 - Unauthorized Access" << std::endl;
return ReadResult::FILE_NOT_FOUND;
}
// Code 403 Bad Request
else if( directive == "403" )
{
osg::notify(osg::WARN) <<
"osgPluing .net: http server response 403 - Access Forbidden" << std::endl;
return ReadResult::FILE_NOT_FOUND;
}
// Code 404 File not found
else if( directive == "404" )
{
osg::notify(osg::WARN) <<
"osgPluing .net: http server response 404 - File Not Found" << std::endl;
return ReadResult::FILE_NOT_FOUND;
}
// Code 405 Method not allowed
else if( directive == "405" )
{
osg::notify(osg::WARN) <<
"osgPluing .net: http server response 405 - Method Not Allowed" << std::endl;
return ReadResult::FILE_NOT_FOUND;
}
// There's more....
}
} while( linebuff[0] != '\r' );
// Invoke the reader corresponding to the extension
osgDB::ReaderWriter *reader =
osgDB::Registry::instance()->getReaderWriterForExtension( osgDB::getFileExtension(file));
osgDB::Registry::instance()->getReaderWriterForExtension( osgDB::getFileExtension(fileName));
ReadResult readResult = ReadResult::FILE_NOT_HANDLED;
if( reader == 0L )
return ReadResult::FILE_NOT_HANDLED;
else
if( reader != 0L )
readResult = reader->readNode( sio );
return readResult;