]> git.mxchange.org Git - flightgear.git/blob - src/Network/httpd.cxx
30354ada17e873ff1a0cdd54ba86f42ab236fae8
[flightgear.git] / src / Network / httpd.cxx
1 // httpd.hxx -- FGFS http property manager interface / external script
2 //              and control class
3 //
4 // Written by Curtis Olson, started June 2001.
5 //
6 // Copyright (C) 2001  Curtis L. Olson - curt@flightgear.org
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 //
22 // $Id$
23
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #include <simgear/compiler.h>
30
31 #include <simgear/debug/logstream.hxx>
32 #include <simgear/io/iochannel.hxx>
33 #include <simgear/math/sg_types.hxx>
34 #include <simgear/misc/props.hxx>
35
36 #include <stdlib.h>             // atoi() atof()
37
38 #include STL_STRING
39 #include STL_STRSTREAM
40
41 #include <Main/fg_props.hxx>
42 #include <Main/globals.hxx>
43
44 #include "httpd.hxx"
45
46 SG_USING_STD(string);
47 #if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
48 SG_USING_STD(cout);
49 SG_USING_STD(istrstream);
50 #endif
51
52
53 bool FGHttpd::open() {
54     if ( is_enabled() ) {
55         SG_LOG( SG_IO, SG_ALERT, "This shouldn't happen, but the channel " 
56                 << "is already in use, ignoring" );
57         return false;
58     }
59
60     server = new HttpdServer( port );
61
62     set_hz( 5 );                // default to processing requests @ 5Hz
63     set_enabled( true );
64
65     return true;
66 }
67
68
69 bool FGHttpd::process() {
70     netChannel::poll();
71
72     return true;
73 }
74
75
76 bool FGHttpd::close() {
77     delete server;
78
79     return true;
80 }
81
82
83 // Handle http GET requests
84 void HttpdChannel::foundTerminator (void) {
85     const string s = buffer.getData();
86
87     if ( s.find( "GET " ) == 0 ) {
88         printf("echo: %s\n", s.c_str());
89
90         string rest = s.substr(4);
91         string request;
92         string tmp;
93
94         unsigned int pos = rest.find( " " );
95         if ( pos != string::npos ) {
96             request = rest.substr( 0, pos );
97         } else {
98             request = "/";
99         }
100
101         SGPropertyNode *node = NULL;
102         pos = request.find( "?" );
103         if ( pos != string::npos ) {
104             // request to update property value
105             string args = request.substr( pos + 1 );
106             request = request.substr( 0, pos );
107             printf("'%s' '%s'\n", request.c_str(), args.c_str());
108
109             // parse args looking for "value="
110             bool done = false;
111             while ( ! done ) {
112                 string arg;
113                 pos = args.find("&");
114                 if ( pos != string::npos ) {
115                     arg = args.substr( 0, pos );
116                     args = args.substr( pos + 1 );
117                 } else {
118                     arg = args;
119                     done = true;
120                 }
121
122                 printf("  arg = %s\n", arg.c_str() );
123                 unsigned int apos = arg.find("=");
124                 if ( apos != string::npos ) {
125                     string a = arg.substr( 0, apos );
126                     string b = arg.substr( apos + 1 );
127                     printf("    a = %s  b = %s\n", a.c_str(), b.c_str() );
128                     if ( a == "value" ) {
129                         fgSetString( request, b );
130                     } 
131                 }
132             }
133         }
134
135         node = globals->get_props()->getNode(request);
136
137         string response = "";
138         response += "<HTML LANG=\"en\">";
139         response += getTerminator();
140
141         response += "<HEAD>";
142         response += getTerminator();
143
144         response += "<TITLE>HUD - ";
145         response += request;
146         response += "</TITLE>";
147         response += getTerminator();
148
149         response += "</HEAD>";
150         response += getTerminator();
151
152         response += "<BODY>";
153         response += getTerminator();
154
155         if ( node->nChildren() > 0 ) {
156             // request is a path with children
157             response += "<H3>Contents of \"";
158             response += request;
159             response += "\"</H3>";
160             response += getTerminator();
161
162             for (int i = 0; i < node->nChildren(); i++) {
163                 SGPropertyNode *child = node->getChild(i);
164                 string name = child->getName();
165                 string line = "";
166                 if ( child->nChildren() > 0 ) {
167                     line += "<B><A HREF=\"";
168                     line += request;
169                     if ( request.substr(request.length() - 1, 1) != (string)"/" ) {
170                         line += "/";
171                     }
172                     line += name;
173                     line += "\">";
174                     line += name;
175                     line += "</A></B>";
176                     line += "/<BR>";
177                 } else {
178                     string value = node->getStringValue ( name, "" );
179                     line += "<B>";
180                     line += name;
181                     line += "</B> <A HREF=\"";
182                     line += request;
183                     if ( request.substr(request.length() - 1, 1) != (string)"/" ) {
184                         line += "/";
185                     }
186                     line += name;
187                     line += "\">(";
188                     line += value;
189                     line += ")</A><BR>";
190                 }
191                 response += line;
192                 response += getTerminator();
193             }
194         } else {
195             // request for an individual data member
196             string value = node->getStringValue();
197             
198             response += "<form method=\"GET\" action=\"";
199             response += request;
200             response += "\">";
201             response += "<B>";
202             response += request;
203             response += "</B> = ";
204             response += "<input type=text name=value size=\"5\" value=\"";
205             response += value;
206             response += "\" maxlength=2047>";
207             response += "<input type=submit value=\"update\" name=\"submit\">";
208             response += "<FORM>";
209             response += "<BR>";
210         }
211         response += "</BODY>";
212         response += getTerminator();
213
214         response += "</HTML>";
215         response += getTerminator();
216
217         push( "HTTP/1.1 200 OK" );
218         push( getTerminator() );
219         
220         printf("size = %d\n", response.length());
221         char ctmp[256];
222         sprintf(ctmp, "Content-Length: %d", response.length());
223         push( ctmp );
224         push( getTerminator() );
225
226         push( "Connection: close" );
227         push( getTerminator() );
228
229         push( "Content-Type: text/html" );
230         push( getTerminator() );
231         push( getTerminator() );
232                 
233         push( response.c_str() );
234     }
235
236     buffer.remove();
237 }