Panda3D
|
00001 // Filename: fake_http_server.cxx 00002 // Created by: drose (10Dec02) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) Carnegie Mellon University. All rights reserved. 00008 // 00009 // All use of this software is subject to the terms of the revised BSD 00010 // license. You should have received a copy of this license along 00011 // with this source code in a file named "LICENSE." 00012 // 00013 //////////////////////////////////////////////////////////////////// 00014 00015 #include "pandabase.h" 00016 00017 #include "queuedConnectionManager.h" 00018 #include "queuedConnectionListener.h" 00019 #include "queuedConnectionReader.h" 00020 #include "connectionWriter.h" 00021 #include "netAddress.h" 00022 #include "connection.h" 00023 #include "netDatagram.h" 00024 #include "pmap.h" 00025 00026 #include <ctype.h> 00027 00028 QueuedConnectionManager cm; 00029 QueuedConnectionReader reader(&cm, 10); 00030 ConnectionWriter writer(&cm, 10); 00031 00032 class ClientState { 00033 public: 00034 ClientState(Connection *client); 00035 void receive_data(const Datagram &data); 00036 void receive_line(string line); 00037 00038 Connection *_client; 00039 string _received; 00040 }; 00041 00042 ClientState:: 00043 ClientState(Connection *client) { 00044 _client = client; 00045 } 00046 00047 void ClientState:: 00048 receive_data(const Datagram &data) { 00049 _received += data.get_message(); 00050 size_t next = 0; 00051 size_t newline = _received.find('\n', next); 00052 while (newline != string::npos) { 00053 size_t last = next; 00054 next = newline + 1; 00055 if (newline > 0 && _received[newline - 1] == '\r') { 00056 newline--; 00057 } 00058 receive_line(_received.substr(last, newline - last)); 00059 if (next < _received.size() && _received[next] == '\r') { 00060 next++; 00061 } 00062 newline = _received.find('\n', next); 00063 } 00064 _received = _received.substr(next); 00065 } 00066 00067 void ClientState:: 00068 receive_line(string line) { 00069 cerr << "received: " << line << "\n"; 00070 // trim trailing whitespace. 00071 size_t size = line.size(); 00072 while (size > 0 && isspace(line[size - 1])) { 00073 size--; 00074 } 00075 if (size != line.size()) { 00076 line = line.substr(0, size); 00077 } 00078 00079 /* 00080 if (line.empty()) { 00081 // Start to honor the request, as if we cared. 00082 Datagram dg; 00083 dg.append_data("HTTP/1.1 200 OK\r\n"); 00084 writer.send(dg, _client); 00085 // Close the connection! 00086 cm.close_connection(_client); 00087 } 00088 */ 00089 } 00090 00091 00092 int 00093 main(int argc, char *argv[]) { 00094 if (argc != 2) { 00095 nout << "fake_http_server port\n"; 00096 exit(1); 00097 } 00098 00099 int port = atoi(argv[1]); 00100 00101 PT(Connection) rendezvous = cm.open_TCP_server_rendezvous(port, 5); 00102 00103 if (rendezvous.is_null()) { 00104 nout << "Cannot grab port " << port << ".\n"; 00105 exit(1); 00106 } 00107 00108 nout << "Listening for connections on port " << port << "\n"; 00109 00110 QueuedConnectionListener listener(&cm, 1); 00111 listener.add_connection(rendezvous); 00112 00113 typedef pmap< PT(Connection), ClientState > Clients; 00114 Clients clients; 00115 00116 reader.set_raw_mode(1); 00117 writer.set_raw_mode(1); 00118 00119 bool shutdown = false; 00120 while (!shutdown) { 00121 // Check for new clients. 00122 while (listener.new_connection_available()) { 00123 PT(Connection) rv; 00124 NetAddress address; 00125 PT(Connection) new_connection; 00126 if (listener.get_new_connection(rv, address, new_connection)) { 00127 nout << "Got connection from " << address << "\n"; 00128 reader.add_connection(new_connection); 00129 clients.insert(Clients::value_type(new_connection, ClientState(new_connection))); 00130 } 00131 } 00132 00133 // Check for reset clients. 00134 while (cm.reset_connection_available()) { 00135 PT(Connection) connection; 00136 if (cm.get_reset_connection(connection)) { 00137 nout << "Lost connection from " 00138 << connection->get_address() << "\n"; 00139 clients.erase(connection); 00140 cm.close_connection(connection); 00141 } 00142 } 00143 00144 // Process all available datagrams. 00145 while (reader.data_available()) { 00146 NetDatagram datagram; 00147 if (reader.get_data(datagram)) { 00148 PT(Connection) client = datagram.get_connection(); 00149 Clients::iterator ci = clients.find(client); 00150 if (ci == clients.end()) { 00151 nout << "Received data from unexpected client " << (void *)client 00152 << "\n"; 00153 } else { 00154 ClientState &state = (*ci).second; 00155 state.receive_data(datagram); 00156 } 00157 } 00158 } 00159 } 00160 00161 return (0); 00162 } 00163 00164 00165 00166 00167