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/misc/strutils.hxx>
#include <simgear/props/tiedpropertylist.hxx>
#include <simgear/io/HTTPRequest.hxx>
#include <simgear/io/HTTPMemoryRequest.hxx>
#include <simgear/timing/sg_time.hxx>
#include <simgear/structure/event_mgr.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:
NoaaMetarGetRequest(MetarDataHandler* metarDataHandler, const string& stationId ) :
Request("http://weather.noaa.gov/pub/data/observations/metar/stations/" + stationId + ".TXT"),
_fromProxy(false),
_metarDataHandler(metarDataHandler)
{
}
NoaaMetarGetRequest( MetarDataHandler* metarDataHandler,
const std::string& stationId ):
MemoryRequest(NOAA_BASE_URL + stationId + ".TXT"),
_metarDataHandler(metarDataHandler)
{
std::ostringstream buf;
buf << globals->get_time_params()->get_cur_time();
requestHeader("X-TIME") = buf.str();
}
virtual string_list requestHeaders() const
{
string_list reply;
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()
virtual void onDone()
{
if( responseCode() != 200 )
{
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
// { return _fromProxy; }
private:
string _metar;
bool _fromProxy;
MetarDataHandler * _metarDataHandler;
};
_metarDataHandler->handleMetarData
(
simgear::strutils::simplify(responseBody())
);
}
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,
"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));
}
private:
MetarDataHandler * _metarDataHandler;
};
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/sound/soundmgr_openal.hxx>
#include <simgear/timing/sg_time.hxx>
#include <simgear/io/HTTPRequest.hxx>
#include <simgear/io/HTTPMemoryRequest.hxx>
#include <FDM/flight.hxx>
#include <GUI/gui.h>
@ -1292,23 +1292,18 @@ do_load_xml_to_proptree(const SGPropertyNode * arg)
return true;
}
class RemoteXMLRequest : public simgear::HTTP::Request
class RemoteXMLRequest:
public simgear::HTTP::MemoryRequest
{
public:
SGPropertyNode_ptr _complete;
SGPropertyNode_ptr _status;
SGPropertyNode_ptr _failed;
SGPropertyNode_ptr _target;
string propsData;
mutable string _requestBody;
int _requestBodyLength;
string _method;
RemoteXMLRequest(const std::string& url, SGPropertyNode* targetNode) :
simgear::HTTP::Request(url),
_target(targetNode),
_requestBodyLength(-1),
_method("GET")
simgear::HTTP::MemoryRequest(url),
_target(targetNode)
{
}
@ -1326,45 +1321,10 @@ public:
{
_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:
virtual int requestBodyLength() const
{
return _requestBodyLength;
}
virtual void getBodyData(char* s, int& count) const
{
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()
virtual void onFail()
{
SG_LOG(SG_IO, SG_INFO, "network level failure in RemoteXMLRequest");
if (_failed) {
@ -1372,16 +1332,14 @@ protected:
}
}
virtual void responseComplete()
virtual void onDone()
{
simgear::HTTP::Request::responseComplete();
int response = responseCode();
bool failed = false;
if (response == 200) {
try {
const char* buffer = propsData.c_str();
readProperties(buffer, propsData.size(), _target, true);
const char* buffer = responseBody().c_str();
readProperties(buffer, responseBody().size(), _target, true);
} catch (const sg_exception &e) {
SG_LOG(SG_IO, SG_WARN, "parsing XML from remote, failed: " << e.getFormattedMessage());
failed = true;
@ -1420,7 +1378,7 @@ do_load_xml_from_url(const SGPropertyNode * arg)
RemoteXMLRequest* req = new RemoteXMLRequest(url, targetnode);
if (arg->hasChild("body"))
req->setRequestData(arg->getChild("body"));
req->setBodyData(arg->getChild("body"));
// connect up optional reporting properties
if (arg->hasValue("complete"))

View file

@ -30,59 +30,17 @@
#include <boost/algorithm/string.hpp>
#include <simgear/debug/logstream.hxx>
#include <simgear/environment/metar.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/io/HTTPClient.hxx>
#include <simgear/io/HTTPRequest.hxx>
#include <simgear/io/HTTPMemoryRequest.hxx>
#include <simgear/io/raw_socket.hxx>
#include <simgear/timing/timestamp.hxx>
using namespace std;
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
#if defined(__linux__) || defined(__sun) || defined(__CYGWIN__) \
|| defined( __FreeBSD__ ) || defined ( sgi )
@ -579,8 +537,15 @@ int main(int argc, char *argv[])
shown = true;
}
try {
MetarRequest* mr = new MetarRequest(argv[i]);
try
{
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.makeRequest(mr);
@ -588,16 +553,24 @@ int main(int argc, char *argv[])
SGTimeStamp start(SGTimeStamp::now());
while (start.elapsedMSec() < 8000) {
http.update();
if (mr->complete || mr->failed) {
if( mr->isComplete() )
break;
}
SGTimeStamp::sleepForMSec(1);
}
if (!mr->complete) {
throw sg_io_exception("metar download failed (or timed out)");
if( !mr->isComplete() )
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");

View file

@ -49,13 +49,12 @@ void FGHTTPClient::shutdown()
_http.reset();
}
void FGHTTPClient::update(double dt)
void FGHTTPClient::update(double)
{
SG_UNUSED(dt);
_http->update();
}
void FGHTTPClient::makeRequest(const simgear::HTTP::Request_ptr& req)
{
_http->makeRequest(req);
}
}

View file

@ -32,11 +32,14 @@ public:
virtual ~FGHTTPClient();
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 shutdown();
virtual void update(double dt);
virtual void update(double);
private:
std::auto_ptr<simgear::HTTP::Client> _http;
};