1
0
Fork 0

Update/refactor for simgear HTTP changes.

This commit is contained in:
Thomas Geymayer 2013-10-27 19:03:35 +01:00
parent f08ea4a7bb
commit 8a582e6376
5 changed files with 97 additions and 175 deletions

View file

@ -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));
}
} }
/* -------------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------------- */

View file

@ -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"))

View file

@ -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");

View file

@ -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);
} }

View file

@ -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;
}; };