// httpd.hxx -- FGFS http property manager interface / external script // and control class // // Written by Curtis Olson, started June 2001. // // Copyright (C) 2001 Curtis L. Olson - curt@flightgear.org // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // // $Id$ #ifdef HAVE_CONFIG_H # include #endif #include #include #include #include #include #include // atoi() atof() #include STL_STRING #include STL_STRSTREAM #include
#include
#include "httpd.hxx" SG_USING_STD(string); #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS) SG_USING_STD(cout); SG_USING_STD(istrstream); #endif bool FGHttpd::open() { if ( is_enabled() ) { SG_LOG( SG_IO, SG_ALERT, "This shouldn't happen, but the channel " << "is already in use, ignoring" ); return false; } server = new HttpdServer( port ); set_hz( 5 ); // default to processing requests @ 5Hz set_enabled( true ); return true; } bool FGHttpd::process() { netChannel::poll(); return true; } bool FGHttpd::close() { delete server; return true; } // Handle http GET requests void HttpdChannel::foundTerminator (void) { const string s = buffer.getData(); if ( s.find( "GET " ) == 0 ) { printf("echo: %s\n", s.c_str()); string rest = s.substr(4); string request; string tmp; unsigned int pos = rest.find( " " ); if ( pos != string::npos ) { request = rest.substr( 0, pos ); } else { request = "/"; } SGPropertyNode *node = NULL; pos = request.find( "?" ); if ( pos != string::npos ) { // request to update property value string args = request.substr( pos + 1 ); request = request.substr( 0, pos ); printf("'%s' '%s'\n", request.c_str(), args.c_str()); // parse args looking for "value=" bool done = false; while ( ! done ) { string arg; pos = args.find("&"); if ( pos != string::npos ) { arg = args.substr( 0, pos ); args = args.substr( pos + 1 ); } else { arg = args; done = true; } printf(" arg = %s\n", arg.c_str() ); unsigned int apos = arg.find("="); if ( apos != string::npos ) { string a = arg.substr( 0, apos ); string b = arg.substr( apos + 1 ); printf(" a = %s b = %s\n", a.c_str(), b.c_str() ); if ( a == "value" ) { fgSetString( request, b ); } } } } node = globals->get_props()->getNode(request); string response = ""; response += ""; response += getTerminator(); response += ""; response += getTerminator(); response += "HUD - "; response += request; response += ""; response += getTerminator(); response += ""; response += getTerminator(); response += ""; response += getTerminator(); if ( node->nChildren() > 0 ) { // request is a path with children response += "

Contents of \""; response += request; response += "\"

"; response += getTerminator(); for (int i = 0; i < node->nChildren(); i++) { SGPropertyNode *child = node->getChild(i); string name = child->getName(); string line = ""; if ( child->nChildren() > 0 ) { line += ""; line += name; line += ""; line += "/
"; } else { string value = node->getStringValue ( name, "" ); line += ""; line += name; line += " ("; line += value; line += ")
"; } response += line; response += getTerminator(); } } else { // request for an individual data member string value = node->getStringValue(); response += "
"; response += ""; response += request; response += " = "; response += ""; response += ""; response += ""; response += "
"; } response += ""; response += getTerminator(); response += ""; response += getTerminator(); push( "HTTP/1.1 200 OK" ); push( getTerminator() ); printf("size = %d\n", response.length()); char ctmp[256]; sprintf(ctmp, "Content-Length: %d", response.length()); push( ctmp ); push( getTerminator() ); push( "Connection: close" ); push( getTerminator() ); push( "Content-Type: text/html" ); push( getTerminator() ); push( getTerminator() ); push( response.c_str() ); } buffer.remove(); }