#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>
{
}
-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)
- {
- }
-
- 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()
+ 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 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;
- };
-
- 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));
- }
+ _metarDataHandler->handleMetarData
+ (
+ simgear::strutils::simplify(responseBody())
+ );
+ }
+
+ virtual void onFail()
+ {
+ SG_LOG(SG_ENVIRONMENT, SG_INFO, "metar download failure");
+ }
+
+ 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));
+ }
}
/* -------------------------------------------------------------------------------- */
#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>
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)
{
}
{
_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) {
}
}
- 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;
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"))
#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 )
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);
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");
_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);
-}
\ No newline at end of file
+}
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;
};