From 117628bf7e1b7b7a6554c2f8859ad66077a64076 Mon Sep 17 00:00:00 2001 From: ehofman Date: Thu, 26 Feb 2004 09:46:36 +0000 Subject: [PATCH] Melchior FRANZ: Add proxy support to the metar class. Authorization is untested, but everything else works. Martin will have to tell us ... --- simgear/environment/metar.cxx | 63 +++++++++++++++++++++++------------ simgear/environment/metar.hxx | 4 +-- 2 files changed, 44 insertions(+), 23 deletions(-) diff --git a/simgear/environment/metar.cxx b/simgear/environment/metar.cxx index 8e67bc66..b18f975b 100644 --- a/simgear/environment/metar.cxx +++ b/simgear/environment/metar.cxx @@ -22,7 +22,7 @@ /** * @file metar.cxx - * Interface for encoded SGMetar aviation weather data. + * Interface for encoded Meteorological Aerodrome Reports (METAR). */ #include @@ -36,7 +36,7 @@ #define NaN SGMetarNaN /** - * The constructor takes a SGMetar string, or a four-letter ICAO code. In the + * The constructor takes a Metar string, or a four-letter ICAO code. In the * latter case the metar string is downloaded from * http://weather.noaa.gov/pub/data/observations/metar/stations/. * The constructor throws sg_io_exceptions on failure. The "METAR" @@ -44,17 +44,22 @@ * @a grpcount) and can be left away. A keyword "SPECI" is * likewise accepted. * + * @param m ICAO station id or metar string + * @param proxy proxy host (optional; default: "") + * @param port proxy port (optional; default: "80") + * @param auth proxy authorization information (optional; default: "") + * * @par Examples: * @code * SGMetar *m = new SGMetar("METAR KSFO 061656Z 19004KT 9SM SCT100 OVC200 08/03 A3013"); * double t = m->getTemperature_F(); * delete m; * - * SGMetar n("KSFO"); + * SGMetar n("KSFO", "proxy.provider.foo", "3128", "proxy-password"); * double d = n.getDewpoint_C(); * @endcode */ -SGMetar::SGMetar(const char *m) : +SGMetar::SGMetar(const string& m, const string& proxy, const string& port, const string& auth) : _grpcount(0), _year(-1), _month(-1), @@ -71,14 +76,14 @@ SGMetar::SGMetar(const char *m) : _dewp(NaN), _pressure(NaN) { - if (isalnum(m[0]) && isalnum(m[1]) && isalnum(m[2]) && isalnum(m[3]) && !m[4]) { + if (m.length() == 4 && isalnum(m[0]) && isalnum(m[1]) && isalnum(m[2]) && isalnum(m[3])) { for (int i = 0; i < 4; i++) _icao[i] = toupper(m[i]); _icao[4] = '\0'; - _data = loadData(_icao); + _data = loadData(_icao, proxy, port, auth); } else { - _data = new char[strlen(m) + 2]; // make room for " \0" - strcpy(_data, m); + _data = new char[m.length() + 2]; // make room for " \0" + strcpy(_data, m.c_str()); _url = _data; } normalizeData(); @@ -94,7 +99,7 @@ SGMetar::SGMetar(const char *m) : scanType(); if (!scanId() || !scanDate()) { delete[] _data; - throw sg_io_exception("metar data incomplete (" + _url + ')'); + throw sg_io_exception("metar data bogus (" + _url + ')'); } scanModifier(); @@ -120,7 +125,7 @@ SGMetar::SGMetar(const char *m) : if (_grpcount < 4) { delete[] _data; - throw sg_io_exception("metar data invalid (" + _url + ')'); + throw sg_io_exception("metar data incomplete (" + _url + ')'); } _url = ""; } @@ -145,27 +150,40 @@ SGMetar::~SGMetar() * @endcode * Throws sg_io_exception on failure. Gives up after waiting longer than 10 seconds. * - * @param id four-letter ICAO SGMetar station code, e.g. "KSFO". - * @return pointer to SGMetar data string, allocated by new char[]. + * @param id four-letter ICAO Metar station code, e.g. "KSFO". + * @param proxy proxy host (optional; default: "") + * @param port proxy port (optional; default: "80") + * @param auth proxy authorization information (optional; default: "") + * @return pointer to Metar data string, allocated by new char[]. + * @see rfc2068.txt for proxy spec ("Proxy-Authorization") */ -char *SGMetar::loadData(const char *id) +char *SGMetar::loadData(const char *id, const string& proxy, const string& port, const string& auth) { - string host = "weather.noaa.gov"; + string host = proxy.empty() ? "weather.noaa.gov" : proxy; string path = "/pub/data/observations/metar/stations/"; path += string(id) + ".TXT"; - _url = "http://" + host + path; - - string get = string("GET ") + path + " HTTP/1.0\r\n\r\n"; + _url = "http://weather.noaa.gov" + path; - SGSocket *sock = new SGSocket(host, "80", "tcp"); + SGSocket *sock = new SGSocket(host, port.empty() ? "80" : port, "tcp"); sock->set_timeout(10000); if (!sock->open(SG_IO_OUT)) { delete sock; - throw sg_io_exception("failed to load metar data from " + _url); + throw sg_io_exception("cannot connect to " + host); } + string get = "GET "; + if (!proxy.empty()) + get += "http://weather.noaa.gov"; + get += path + " HTTP/1.0\r\n"; sock->writestring(get.c_str()); + if (!auth.empty()) { + get = "Proxy-Authorization: " + auth + "\r\n"; + sock->writestring(get.c_str()); + } + + sock->writestring("\r\n"); + int i; const int buflen = 512; char buf[2 * buflen]; @@ -195,8 +213,8 @@ char *SGMetar::loadData(const char *id) /** - * Replace any number of subsequent spaces by just one space. - * This makes scanning for things like "ALL RWY" easier. + * Replace any number of subsequent spaces by just one space, and add + * a trailing space. This makes scanning for things like "ALL RWY" easier. */ void SGMetar::normalizeData() { @@ -204,6 +222,9 @@ void SGMetar::normalizeData() for (src = dest = _data; (*dest++ = *src++); ) while (*src == ' ' && src[1] == ' ') src++; + for (dest--; isspace(*--dest); ) ; + *++dest = ' '; + *++dest = '\0'; } diff --git a/simgear/environment/metar.hxx b/simgear/environment/metar.hxx index 29efbf73..f6e0b6b0 100644 --- a/simgear/environment/metar.hxx +++ b/simgear/environment/metar.hxx @@ -147,7 +147,7 @@ protected: class SGMetar { public: - SGMetar(const char *m); + SGMetar(const string& m, const string& proxy = "", const string& port = "", const string &auth = ""); ~SGMetar(); enum ReportType { @@ -253,7 +253,7 @@ protected: int scanNumber(char **str, int *num, int min, int max = 0); bool scanBoundary(char **str); const struct Token *scanToken(char **str, const struct Token *list); - char *loadData(const char *id); + char *loadData(const char *id, const string& proxy, const string& port, const string &auth); void normalizeData(); }; -- 2.39.5