Panda3D
 All Classes Functions Variables Enumerations
fake_http_server.cxx
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 
 All Classes Functions Variables Enumerations