Update/refactor for simgear HTTP changes.
This commit is contained in:
parent
f08ea4a7bb
commit
8a582e6376
5 changed files with 97 additions and 175 deletions
|
@ -33,7 +33,7 @@
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
#include <simgear/misc/strutils.hxx>
|
#include <simgear/misc/strutils.hxx>
|
||||||
#include <simgear/props/tiedpropertylist.hxx>
|
#include <simgear/props/tiedpropertylist.hxx>
|
||||||
#include <simgear/io/HTTPRequest.hxx>
|
#include <simgear/io/HTTPMemoryRequest.hxx>
|
||||||
#include <simgear/timing/sg_time.hxx>
|
#include <simgear/timing/sg_time.hxx>
|
||||||
#include <simgear/structure/event_mgr.hxx>
|
#include <simgear/structure/event_mgr.hxx>
|
||||||
#include <simgear/structure/commands.hxx>
|
#include <simgear/structure/commands.hxx>
|
||||||
|
@ -391,80 +391,69 @@ NoaaMetarRealWxController::NoaaMetarRealWxController( SGPropertyNode_ptr rootNod
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoaaMetarRealWxController::requestMetar( MetarDataHandler * metarDataHandler, const std::string & id )
|
void NoaaMetarRealWxController::requestMetar
|
||||||
|
(
|
||||||
|
MetarDataHandler* metarDataHandler,
|
||||||
|
const std::string& id
|
||||||
|
)
|
||||||
{
|
{
|
||||||
class NoaaMetarGetRequest : public simgear::HTTP::Request
|
static const std::string NOAA_BASE_URL =
|
||||||
{
|
"http://weather.noaa.gov/pub/data/observations/metar/stations/";
|
||||||
|
class NoaaMetarGetRequest:
|
||||||
|
public simgear::HTTP::MemoryRequest
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
NoaaMetarGetRequest(MetarDataHandler* metarDataHandler, const string& stationId ) :
|
NoaaMetarGetRequest( MetarDataHandler* metarDataHandler,
|
||||||
Request("http://weather.noaa.gov/pub/data/observations/metar/stations/" + stationId + ".TXT"),
|
const std::string& stationId ):
|
||||||
_fromProxy(false),
|
MemoryRequest(NOAA_BASE_URL + stationId + ".TXT"),
|
||||||
_metarDataHandler(metarDataHandler)
|
_metarDataHandler(metarDataHandler)
|
||||||
{
|
{
|
||||||
}
|
std::ostringstream buf;
|
||||||
|
buf << globals->get_time_params()->get_cur_time();
|
||||||
|
requestHeader("X-TIME") = buf.str();
|
||||||
|
}
|
||||||
|
|
||||||
virtual string_list requestHeaders() const
|
virtual void onDone()
|
||||||
{
|
{
|
||||||
string_list reply;
|
if( responseCode() != 200 )
|
||||||
reply.push_back("X-TIME");
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string header(const std::string& name) const
|
|
||||||
{
|
|
||||||
string reply;
|
|
||||||
|
|
||||||
if( name == "X-TIME" ) {
|
|
||||||
std::ostringstream buf;
|
|
||||||
buf << globals->get_time_params()->get_cur_time();
|
|
||||||
reply = buf.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
return reply;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void responseHeader(const string& key, const string& value)
|
|
||||||
{
|
|
||||||
if (key == "x-metarproxy") {
|
|
||||||
_fromProxy = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void gotBodyData(const char* s, int n)
|
|
||||||
{
|
|
||||||
_metar += string(s, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void responseComplete()
|
|
||||||
{
|
|
||||||
if (responseCode() == 200) {
|
|
||||||
_metarDataHandler->handleMetarData( simgear::strutils::simplify(_metar) );
|
|
||||||
} else {
|
|
||||||
SG_LOG(SG_ENVIRONMENT, SG_WARN, "metar download failed:" << url() << ": reason:" << responseReason());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void failed()
|
|
||||||
{
|
{
|
||||||
SG_LOG(SG_ENVIRONMENT, SG_INFO, "metar download failure");
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_ENVIRONMENT,
|
||||||
|
SG_WARN,
|
||||||
|
"metar download failed:" << url() << ": reason:" << responseReason()
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool fromMetarProxy() const
|
_metarDataHandler->handleMetarData
|
||||||
// { return _fromProxy; }
|
(
|
||||||
private:
|
simgear::strutils::simplify(responseBody())
|
||||||
string _metar;
|
);
|
||||||
bool _fromProxy;
|
}
|
||||||
MetarDataHandler * _metarDataHandler;
|
|
||||||
};
|
|
||||||
|
|
||||||
string upperId = boost::to_upper_copy(id);
|
virtual void onFail()
|
||||||
|
{
|
||||||
|
SG_LOG(SG_ENVIRONMENT, SG_INFO, "metar download failure");
|
||||||
|
}
|
||||||
|
|
||||||
SG_LOG(SG_ENVIRONMENT, SG_INFO,
|
private:
|
||||||
"NoaaMetarRealWxController::update(): spawning load request for station-id '" << upperId << "'" );
|
MetarDataHandler * _metarDataHandler;
|
||||||
FGHTTPClient* http = static_cast<FGHTTPClient*>(globals->get_subsystem("http"));
|
};
|
||||||
if (http) {
|
|
||||||
http->makeRequest(new NoaaMetarGetRequest(metarDataHandler, upperId));
|
string upperId = boost::to_upper_copy(id);
|
||||||
}
|
|
||||||
|
SG_LOG
|
||||||
|
(
|
||||||
|
SG_ENVIRONMENT,
|
||||||
|
SG_INFO,
|
||||||
|
"NoaaMetarRealWxController::update(): "
|
||||||
|
"spawning load request for station-id '" << upperId << "'"
|
||||||
|
);
|
||||||
|
FGHTTPClient* http = static_cast<FGHTTPClient*>(globals->get_subsystem("http"));
|
||||||
|
if (http) {
|
||||||
|
http->makeRequest(new NoaaMetarGetRequest(metarDataHandler, upperId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------------------- */
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
#include <simgear/structure/event_mgr.hxx>
|
#include <simgear/structure/event_mgr.hxx>
|
||||||
#include <simgear/sound/soundmgr_openal.hxx>
|
#include <simgear/sound/soundmgr_openal.hxx>
|
||||||
#include <simgear/timing/sg_time.hxx>
|
#include <simgear/timing/sg_time.hxx>
|
||||||
#include <simgear/io/HTTPRequest.hxx>
|
#include <simgear/io/HTTPMemoryRequest.hxx>
|
||||||
|
|
||||||
#include <FDM/flight.hxx>
|
#include <FDM/flight.hxx>
|
||||||
#include <GUI/gui.h>
|
#include <GUI/gui.h>
|
||||||
|
@ -1292,23 +1292,18 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RemoteXMLRequest : public simgear::HTTP::Request
|
class RemoteXMLRequest:
|
||||||
|
public simgear::HTTP::MemoryRequest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SGPropertyNode_ptr _complete;
|
SGPropertyNode_ptr _complete;
|
||||||
SGPropertyNode_ptr _status;
|
SGPropertyNode_ptr _status;
|
||||||
SGPropertyNode_ptr _failed;
|
SGPropertyNode_ptr _failed;
|
||||||
SGPropertyNode_ptr _target;
|
SGPropertyNode_ptr _target;
|
||||||
string propsData;
|
|
||||||
mutable string _requestBody;
|
|
||||||
int _requestBodyLength;
|
|
||||||
string _method;
|
|
||||||
|
|
||||||
RemoteXMLRequest(const std::string& url, SGPropertyNode* targetNode) :
|
RemoteXMLRequest(const std::string& url, SGPropertyNode* targetNode) :
|
||||||
simgear::HTTP::Request(url),
|
simgear::HTTP::MemoryRequest(url),
|
||||||
_target(targetNode),
|
_target(targetNode)
|
||||||
_requestBodyLength(-1),
|
|
||||||
_method("GET")
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1326,45 +1321,10 @@ public:
|
||||||
{
|
{
|
||||||
_failed = p;
|
_failed = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setRequestData(const SGPropertyNode* body)
|
|
||||||
{
|
|
||||||
_method = "POST";
|
|
||||||
std::stringstream buf;
|
|
||||||
writeProperties(buf, body, true);
|
|
||||||
_requestBody = buf.str();
|
|
||||||
_requestBodyLength = _requestBody.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string method() const
|
|
||||||
{
|
|
||||||
return _method;
|
|
||||||
}
|
|
||||||
protected:
|
protected:
|
||||||
virtual int requestBodyLength() const
|
|
||||||
{
|
|
||||||
return _requestBodyLength;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void getBodyData(char* s, int& count) const
|
virtual void onFail()
|
||||||
{
|
|
||||||
int toRead = std::min(count, (int) _requestBody.size());
|
|
||||||
memcpy(s, _requestBody.c_str(), toRead);
|
|
||||||
count = toRead;
|
|
||||||
_requestBody = _requestBody.substr(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::string requestBodyType() const
|
|
||||||
{
|
|
||||||
return "application/xml";
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void gotBodyData(const char* s, int n)
|
|
||||||
{
|
|
||||||
propsData += string(s, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void failed()
|
|
||||||
{
|
{
|
||||||
SG_LOG(SG_IO, SG_INFO, "network level failure in RemoteXMLRequest");
|
SG_LOG(SG_IO, SG_INFO, "network level failure in RemoteXMLRequest");
|
||||||
if (_failed) {
|
if (_failed) {
|
||||||
|
@ -1372,16 +1332,14 @@ protected:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void responseComplete()
|
virtual void onDone()
|
||||||
{
|
{
|
||||||
simgear::HTTP::Request::responseComplete();
|
|
||||||
|
|
||||||
int response = responseCode();
|
int response = responseCode();
|
||||||
bool failed = false;
|
bool failed = false;
|
||||||
if (response == 200) {
|
if (response == 200) {
|
||||||
try {
|
try {
|
||||||
const char* buffer = propsData.c_str();
|
const char* buffer = responseBody().c_str();
|
||||||
readProperties(buffer, propsData.size(), _target, true);
|
readProperties(buffer, responseBody().size(), _target, true);
|
||||||
} catch (const sg_exception &e) {
|
} catch (const sg_exception &e) {
|
||||||
SG_LOG(SG_IO, SG_WARN, "parsing XML from remote, failed: " << e.getFormattedMessage());
|
SG_LOG(SG_IO, SG_WARN, "parsing XML from remote, failed: " << e.getFormattedMessage());
|
||||||
failed = true;
|
failed = true;
|
||||||
|
@ -1420,7 +1378,7 @@ do_load_xml_from_url(const SGPropertyNode * arg)
|
||||||
RemoteXMLRequest* req = new RemoteXMLRequest(url, targetnode);
|
RemoteXMLRequest* req = new RemoteXMLRequest(url, targetnode);
|
||||||
|
|
||||||
if (arg->hasChild("body"))
|
if (arg->hasChild("body"))
|
||||||
req->setRequestData(arg->getChild("body"));
|
req->setBodyData(arg->getChild("body"));
|
||||||
|
|
||||||
// connect up optional reporting properties
|
// connect up optional reporting properties
|
||||||
if (arg->hasValue("complete"))
|
if (arg->hasValue("complete"))
|
||||||
|
|
|
@ -30,59 +30,17 @@
|
||||||
|
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
#include <simgear/debug/logstream.hxx>
|
|
||||||
#include <simgear/environment/metar.hxx>
|
#include <simgear/environment/metar.hxx>
|
||||||
#include <simgear/structure/exception.hxx>
|
#include <simgear/structure/exception.hxx>
|
||||||
|
|
||||||
#include <simgear/io/HTTPClient.hxx>
|
#include <simgear/io/HTTPClient.hxx>
|
||||||
#include <simgear/io/HTTPRequest.hxx>
|
#include <simgear/io/HTTPMemoryRequest.hxx>
|
||||||
#include <simgear/io/raw_socket.hxx>
|
#include <simgear/io/raw_socket.hxx>
|
||||||
#include <simgear/timing/timestamp.hxx>
|
#include <simgear/timing/timestamp.hxx>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace simgear;
|
using namespace simgear;
|
||||||
|
|
||||||
class MetarRequest : public HTTP::Request
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool complete;
|
|
||||||
bool failed;
|
|
||||||
string metarData;
|
|
||||||
bool fromProxy;
|
|
||||||
|
|
||||||
MetarRequest(const std::string& stationId) :
|
|
||||||
HTTP::Request("http://weather.noaa.gov/pub/data/observations/metar/stations/" + boost::to_upper_copy(stationId) + ".TXT"),
|
|
||||||
complete(false),
|
|
||||||
failed(false)
|
|
||||||
{
|
|
||||||
fromProxy = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
virtual void responseHeader(const string& key, const string& value)
|
|
||||||
{
|
|
||||||
if (key == "x-metarproxy") {
|
|
||||||
fromProxy = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void gotBodyData(const char* s, int n)
|
|
||||||
{
|
|
||||||
metarData += string(s, n);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void responseComplete()
|
|
||||||
{
|
|
||||||
if (responseCode() == 200) {
|
|
||||||
complete = true;
|
|
||||||
} else {
|
|
||||||
SG_LOG(SG_ENVIRONMENT, SG_WARN, "metar download failed:" << url() << ": reason:" << responseReason());
|
|
||||||
failed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// text color
|
// text color
|
||||||
#if defined(__linux__) || defined(__sun) || defined(__CYGWIN__) \
|
#if defined(__linux__) || defined(__sun) || defined(__CYGWIN__) \
|
||||||
|| defined( __FreeBSD__ ) || defined ( sgi )
|
|| defined( __FreeBSD__ ) || defined ( sgi )
|
||||||
|
@ -579,8 +537,15 @@ int main(int argc, char *argv[])
|
||||||
shown = true;
|
shown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try
|
||||||
MetarRequest* mr = new MetarRequest(argv[i]);
|
{
|
||||||
|
static const std::string NOAA_BASE_URL =
|
||||||
|
"http://weather.noaa.gov/pub/data/observations/metar/stations/";
|
||||||
|
HTTP::MemoryRequest* mr = new HTTP::MemoryRequest
|
||||||
|
(
|
||||||
|
NOAA_BASE_URL
|
||||||
|
+ boost::to_upper_copy<std::string>(argv[i]) + ".TXT"
|
||||||
|
);
|
||||||
HTTP::Request_ptr own(mr);
|
HTTP::Request_ptr own(mr);
|
||||||
http.makeRequest(mr);
|
http.makeRequest(mr);
|
||||||
|
|
||||||
|
@ -588,16 +553,24 @@ int main(int argc, char *argv[])
|
||||||
SGTimeStamp start(SGTimeStamp::now());
|
SGTimeStamp start(SGTimeStamp::now());
|
||||||
while (start.elapsedMSec() < 8000) {
|
while (start.elapsedMSec() < 8000) {
|
||||||
http.update();
|
http.update();
|
||||||
if (mr->complete || mr->failed) {
|
if( mr->isComplete() )
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
SGTimeStamp::sleepForMSec(1);
|
SGTimeStamp::sleepForMSec(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mr->complete) {
|
if( !mr->isComplete() )
|
||||||
throw sg_io_exception("metar download failed (or timed out)");
|
throw sg_io_exception("metar download timed out");
|
||||||
|
if( mr->responseCode() != 200 )
|
||||||
|
{
|
||||||
|
std::cerr << "metar download failed: "
|
||||||
|
<< mr->url()
|
||||||
|
<< " (" << mr->responseCode()
|
||||||
|
<< " " << mr->responseReason() << ")"
|
||||||
|
<< std::endl;
|
||||||
|
throw sg_io_exception("metar download failed");
|
||||||
}
|
}
|
||||||
SGMetar *m = new SGMetar(mr->metarData);
|
|
||||||
|
SGMetar *m = new SGMetar(mr->responseBody());
|
||||||
|
|
||||||
//SGMetar *m = new SGMetar("2004/01/11 01:20\nLOWG 110120Z AUTO VRB01KT 0050 1600N R35/0600 FG M06/M06 Q1019 88//////\n");
|
//SGMetar *m = new SGMetar("2004/01/11 01:20\nLOWG 110120Z AUTO VRB01KT 0050 1600N R35/0600 FG M06/M06 Q1019 88//////\n");
|
||||||
|
|
||||||
|
|
|
@ -49,13 +49,12 @@ void FGHTTPClient::shutdown()
|
||||||
_http.reset();
|
_http.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGHTTPClient::update(double dt)
|
void FGHTTPClient::update(double)
|
||||||
{
|
{
|
||||||
SG_UNUSED(dt);
|
|
||||||
_http->update();
|
_http->update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FGHTTPClient::makeRequest(const simgear::HTTP::Request_ptr& req)
|
void FGHTTPClient::makeRequest(const simgear::HTTP::Request_ptr& req)
|
||||||
{
|
{
|
||||||
_http->makeRequest(req);
|
_http->makeRequest(req);
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,11 +32,14 @@ public:
|
||||||
virtual ~FGHTTPClient();
|
virtual ~FGHTTPClient();
|
||||||
|
|
||||||
void makeRequest(const simgear::HTTP::Request_ptr& req);
|
void makeRequest(const simgear::HTTP::Request_ptr& req);
|
||||||
|
|
||||||
|
simgear::HTTP::Client* client() { return _http.get(); }
|
||||||
|
simgear::HTTP::Client const* client() const { return _http.get(); }
|
||||||
|
|
||||||
virtual void init();
|
virtual void init();
|
||||||
virtual void shutdown();
|
virtual void shutdown();
|
||||||
virtual void update(double dt);
|
virtual void update(double);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::auto_ptr<simgear::HTTP::Client> _http;
|
std::auto_ptr<simgear::HTTP::Client> _http;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue