ReadResult HTTPClient::doReadString(const HTTPRequest& request, const osgDB::Options* options, ProgressCallback* callback ) { initialize(); ReadResult result; HTTPResponse response = this->doGet( request, options, callback ); if ( response.isOK() ) { result = ReadResult( new StringObject(response.getPartAsString(0)) ); } else if ( response.getCode() >= 400 && response.getCode() < 500 && response.getCode() != 404 ) { // for request errors, return an error result with the part data intact // so the user can parse it as needed. We only do this for readString. result = ReadResult( ReadResult::RESULT_SERVER_ERROR, new StringObject(response.getPartAsString(0)) ); } else { result = ReadResult( response.isCancelled() ? ReadResult::RESULT_CANCELED : response.getCode() == HTTPResponse::NOT_FOUND ? ReadResult::RESULT_NOT_FOUND : response.getCode() == HTTPResponse::SERVER_ERROR ? ReadResult::RESULT_SERVER_ERROR : response.getCode() == HTTPResponse::NOT_MODIFIED ? ReadResult::RESULT_NOT_MODIFIED : ReadResult::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.code() ) ) { if (callback) { if ( s_HTTP_DEBUG ) { OE_NOTICE << LC << "Error in HTTPClient for " << request.getURL() << " but it's recoverable" << std::endl; } callback->setNeedsRetry( true ); } } } // encode headers result.setMetadata( response.getHeadersAsConfig() ); // last-modified (file time) result.setLastModifiedTime( getCurlFileTime(_curl_handle) ); return result; }
ReadResult HTTPClient::doReadString(const std::string& location, const osgDB::Options* options, ProgressCallback* callback ) { initialize(); ReadResult result; HTTPResponse response = this->doGet( location, options, callback ); if ( response.isOK() ) { result = ReadResult( new StringObject(response.getPartAsString(0)), response.getHeadersAsConfig()); } else if ( response.getCode() >= 400 && response.getCode() < 500 && response.getCode() != 404 ) { // for request errors, return an error result with the part data intact // so the user can parse it as needed. We only do this for readString. result = ReadResult( ReadResult::RESULT_SERVER_ERROR, new StringObject(response.getPartAsString(0)), response.getHeadersAsConfig() ); } else { result = ReadResult( response.isCancelled() ? ReadResult::RESULT_CANCELED : response.getCode() == HTTPResponse::NOT_FOUND ? ReadResult::RESULT_NOT_FOUND : response.getCode() == HTTPResponse::SERVER_ERROR ? ReadResult::RESULT_SERVER_ERROR : ReadResult::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.code() ) ) { if (callback) { OE_DEBUG << "Error in HTTPClient for " << location << " but it's recoverable" << std::endl; callback->setNeedsRetry( true ); } } } // last-modified (file time) TimeStamp filetime = 0; if ( CURLE_OK == curl_easy_getinfo(_curl_handle, CURLINFO_FILETIME, &filetime) ) { result.setLastModifiedTime( filetime ); } return result; }
bool HTTPClient::doDownload(const std::string& url, const std::string& filename) { initialize(); // 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 << " (" << response.getCode() << ")" << std::endl; return false; } }
ReadResult HTTPClient::doReadString(const std::string& location, const osgDB::Options* options, ProgressCallback* callback ) { initialize(); ReadResult result; HTTPResponse response = this->doGet( location, options, callback ); if ( response.isOK() ) { result = ReadResult( new StringObject(response.getPartAsString(0)), response.getHeadersAsConfig()); } else { result = ReadResult( response.isCancelled() ? ReadResult::RESULT_CANCELED : response.getCode() == HTTPResponse::NOT_FOUND ? ReadResult::RESULT_NOT_FOUND : response.getCode() == HTTPResponse::SERVER_ERROR ? ReadResult::RESULT_SERVER_ERROR : ReadResult::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.code() ) ) { if (callback) { OE_DEBUG << "Error in HTTPClient for " << location << " but it's recoverable" << std::endl; callback->setNeedsRetry( true ); } } } return result; }
ReadResult HTTPClient::doReadNode(const std::string& location, const osgDB::Options* options, ProgressCallback* callback) { initialize(); ReadResult result; HTTPResponse response = this->doGet(location, options, callback); if (response.isOK()) { osgDB::ReaderWriter* reader = getReader(location, response); if (!reader) { OE_WARN << LC << "Can't find an OSG plugin to read "<<location<<std::endl; result = ReadResult(ReadResult::RESULT_NO_READER); } else { osgDB::ReaderWriter::ReadResult rr = reader->readNode(response.getPartStream(0), options); if ( rr.validNode() ) { result = ReadResult(rr.takeNode(), response.getHeadersAsConfig()); } else { if ( !rr.message().empty() ) { OE_WARN << LC << "HTTP error: " << rr.message() << std::endl; } OE_WARN << LC << reader->className() << " failed to read node from " << location << std::endl; result = ReadResult(ReadResult::RESULT_READER_ERROR); } } } else { result = ReadResult( response.isCancelled() ? ReadResult::RESULT_CANCELED : response.getCode() == HTTPResponse::NOT_FOUND ? ReadResult::RESULT_NOT_FOUND : response.getCode() == HTTPResponse::SERVER_ERROR ? ReadResult::RESULT_SERVER_ERROR : ReadResult::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.code() ) ) { if (callback) { OE_DEBUG << "Error in HTTPClient for " << location << " but it's recoverable" << std::endl; callback->setNeedsRetry( true ); } } } return result; }
HTTPClient::ResultCode HTTPClient::doReadString(const std::string& filename, std::string& output, ProgressBase* callback ) { 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 {
ReadResult HTTPClient::doReadObject(const HTTPRequest& request, const osgDB::Options* options, ProgressCallback* callback) { initialize(); ReadResult result; HTTPResponse response = this->doGet(request, options, callback); if (response.isOK()) { osgDB::ReaderWriter* reader = getReader(request.getURL(), response); if (!reader) { result = ReadResult(ReadResult::RESULT_NO_READER); } else { osgDB::ReaderWriter::ReadResult rr = reader->readObject(response.getPartStream(0), options); if ( rr.validObject() ) { result = ReadResult(rr.takeObject()); } else { if ( s_HTTP_DEBUG ) { OE_WARN << LC << reader->className() << " failed to read object from " << request.getURL() << "; message = " << rr.message() << std::endl; } result = ReadResult(ReadResult::RESULT_READER_ERROR); result.setErrorDetail( rr.message() ); } } // last-modified (file time) result.setLastModifiedTime( getCurlFileTime(_curl_handle) ); } else { result = ReadResult( response.isCancelled() ? ReadResult::RESULT_CANCELED : response.getCode() == HTTPResponse::NOT_FOUND ? ReadResult::RESULT_NOT_FOUND : response.getCode() == HTTPResponse::SERVER_ERROR ? ReadResult::RESULT_SERVER_ERROR : response.getCode() == HTTPResponse::NOT_MODIFIED ? ReadResult::RESULT_NOT_MODIFIED : ReadResult::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.code() ) ) { if (callback) { if ( s_HTTP_DEBUG ) { OE_NOTICE << LC << "Error in HTTPClient for " << request.getURL() << " but it's recoverable" << std::endl; } callback->setNeedsRetry( true ); } } } result.setMetadata( response.getHeadersAsConfig() ); return result; }
HTTPClient::ResultCode HTTPClient::doReadNodeFile(const std::string& filename, osg::ref_ptr<osg::Node>& output, const osgDB::ReaderWriter::Options *options, ProgressBase *callback) { ResultCode result = RESULT_OK; if ( osgDB::containsServerAddress( filename ) ) { HTTPResponse response = this->doGet(filename, options, callback); if (response.isOK()) { // Try to find a reader by file extension. If this fails, we will fetch the file // anyway and try to get a reader via mime-type. std::string ext = osgDB::getFileExtension( filename ); osgDB::ReaderWriter *reader = osgDB::Registry::instance()->getReaderWriterForExtension( ext ); //If we didn't get a reader by extension, try to get it via mime type if (!reader) { std::string mimeType = response.getMimeType(); //OE_DEBUG << LC << "Looking up extension for mime-type " << mimeType << std::endl; if ( mimeType.length() > 0 ) { reader = owUtil::Registry::instance().getReaderWriterForMimeType(mimeType); } } // if we still didn't get it, bad news 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; }
ReadResult HTTPClient::doReadImage(const std::string& location, const osgDB::Options* options, ProgressCallback* callback) { initialize(); ReadResult result; HTTPResponse response = this->doGet(location, options, callback); if (response.isOK()) { osgDB::ReaderWriter* reader = getReader(location, response); if (!reader) { result = ReadResult(ReadResult::RESULT_NO_READER); } else { osgDB::ReaderWriter::ReadResult rr = reader->readImage(response.getPartStream(0), options); if ( rr.validImage() ) { result = ReadResult(rr.takeImage(), response.getHeadersAsConfig() ); } else { if ( !rr.message().empty() ) { OE_WARN << LC << "HTTP error: " << rr.message() << std::endl; } OE_WARN << LC << reader->className() << " failed to read image from " << location << std::endl; result = ReadResult(ReadResult::RESULT_READER_ERROR); } } // last-modified (file time) TimeStamp filetime = 0; if ( CURLE_OK == curl_easy_getinfo(_curl_handle, CURLINFO_FILETIME, &filetime) ) { result.setLastModifiedTime( filetime ); } } else { result = ReadResult( response.isCancelled() ? ReadResult::RESULT_CANCELED : response.getCode() == HTTPResponse::NOT_FOUND ? ReadResult::RESULT_NOT_FOUND : response.getCode() == HTTPResponse::SERVER_ERROR ? ReadResult::RESULT_SERVER_ERROR : ReadResult::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.code() ) ) { if (callback) { OE_DEBUG << "Error in HTTPClient for " << location << " but it's recoverable" << std::endl; callback->setNeedsRetry( true ); } } } // set the source name if ( result.getImage() ) result.getImage()->setName( location ); return result; }
HTTPClient::ResultCode HTTPClient::doReadImageFile(const std::string& filename, osg::ref_ptr<osg::Image>& output, const osgDB::ReaderWriter::Options *options, osgEarth::ProgressCallback *callback) { ResultCode result = RESULT_OK; if ( osgDB::containsServerAddress( filename ) ) { HTTPResponse response = this->doGet(filename, options, callback); if (response.isOK()) { osgDB::ReaderWriter* reader = 0L; // try to look up a reader by mime-type first: std::string mimeType = response.getMimeType(); OE_DEBUG << LC << "Looking up extension for mime-type " << mimeType << std::endl; if ( !mimeType.empty() ) { reader = osgEarth::Registry::instance()->getReaderWriterForMimeType(mimeType); } if ( !reader ) { // Try to find a reader by file extension. If this fails, we will fetch the file // anyway and try to get a reader via mime-type. std::string ext = osgDB::getFileExtension( filename ); reader = osgDB::Registry::instance()->getReaderWriterForExtension( ext ); //OE_NOTICE << "Reading " << filename << " with mime " << response.getMimeType() << std::endl; } 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; }