Panda3D
fake_http_server.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file fake_http_server.cxx
10  * @author drose
11  * @date 2002-12-10
12  */
13 
14 #include "pandabase.h"
15 
18 #include "queuedConnectionReader.h"
19 #include "connectionWriter.h"
20 #include "netAddress.h"
21 #include "connection.h"
22 #include "netDatagram.h"
23 #include "pmap.h"
24 
25 #include <ctype.h>
26 
27 using std::string;
28 
30 QueuedConnectionReader reader(&cm, 10);
31 ConnectionWriter writer(&cm, 10);
32 
33 class ClientState {
34 public:
35  ClientState(Connection *client);
36  void receive_data(const Datagram &data);
37  void receive_line(string line);
38 
39  Connection *_client;
40  string _received;
41 };
42 
43 ClientState::
44 ClientState(Connection *client) {
45  _client = client;
46 }
47 
48 void ClientState::
49 receive_data(const Datagram &data) {
50  _received += data.get_message();
51  size_t next = 0;
52  size_t newline = _received.find('\n', next);
53  while (newline != string::npos) {
54  size_t last = next;
55  next = newline + 1;
56  if (newline > 0 && _received[newline - 1] == '\r') {
57  newline--;
58  }
59  receive_line(_received.substr(last, newline - last));
60  if (next < _received.size() && _received[next] == '\r') {
61  next++;
62  }
63  newline = _received.find('\n', next);
64  }
65  _received = _received.substr(next);
66 }
67 
68 void ClientState::
69 receive_line(string line) {
70  std::cerr << "received: " << line << "\n";
71  // trim trailing whitespace.
72  size_t size = line.size();
73  while (size > 0 && isspace(line[size - 1])) {
74  size--;
75  }
76  if (size != line.size()) {
77  line = line.substr(0, size);
78  }
79 
80  /*
81  if (line.empty()) {
82  // Start to honor the request, as if we cared.
83  Datagram dg;
84  dg.append_data("HTTP/1.1 200 OK\r\n");
85  writer.send(dg, _client);
86  // Close the connection!
87  cm.close_connection(_client);
88  }
89  */
90 }
91 
92 
93 int
94 main(int argc, char *argv[]) {
95  if (argc != 2) {
96  nout << "fake_http_server port\n";
97  exit(1);
98  }
99 
100  int port = atoi(argv[1]);
101 
102  PT(Connection) rendezvous = cm.open_TCP_server_rendezvous(port, 5);
103 
104  if (rendezvous.is_null()) {
105  nout << "Cannot grab port " << port << ".\n";
106  exit(1);
107  }
108 
109  nout << "Listening for connections on port " << port << "\n";
110 
111  QueuedConnectionListener listener(&cm, 1);
112  listener.add_connection(rendezvous);
113 
114  typedef pmap< PT(Connection), ClientState > Clients;
115  Clients clients;
116 
117  reader.set_raw_mode(1);
118  writer.set_raw_mode(1);
119 
120  bool shutdown = false;
121  while (!shutdown) {
122  // Check for new clients.
123  while (listener.new_connection_available()) {
124  PT(Connection) rv;
125  NetAddress address;
126  PT(Connection) new_connection;
127  if (listener.get_new_connection(rv, address, new_connection)) {
128  nout << "Got connection from " << address << "\n";
129  reader.add_connection(new_connection);
130  clients.insert(Clients::value_type(new_connection, ClientState(new_connection)));
131  }
132  }
133 
134  // Check for reset clients.
135  while (cm.reset_connection_available()) {
136  PT(Connection) connection;
137  if (cm.get_reset_connection(connection)) {
138  nout << "Lost connection from "
139  << connection->get_address() << "\n";
140  clients.erase(connection);
141  cm.close_connection(connection);
142  }
143  }
144 
145  // Process all available datagrams.
146  while (reader.data_available()) {
147  NetDatagram datagram;
148  if (reader.get_data(datagram)) {
149  PT(Connection) client = datagram.get_connection();
150  Clients::iterator ci = clients.find(client);
151  if (ci == clients.end()) {
152  nout << "Received data from unexpected client " << (void *)client
153  << "\n";
154  } else {
155  ClientState &state = (*ci).second;
156  state.receive_data(datagram);
157  }
158  }
159  }
160  }
161 
162  return (0);
163 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is our own Panda specialization on the default STL map.
Definition: pmap.h:49
A specific kind of Datagram, especially for sending across or receiving from a network.
Definition: netDatagram.h:40
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This flavor of ConnectionManager will queue up all of the reset-connection messages from the Connecti...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool get_reset_connection(PT(Connection) &connection)
If a previous call to reset_connection_available() returned true, this function will return informati...
bool reset_connection_available() const
Returns true if one of the readers/writers/listeners reported a connection reset recently.
This class handles threaded delivery of datagrams to various TCP or UDP sockets.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This flavor of ConnectionReader will read from its sockets and queue up all of the datagrams read for...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Represents a single TCP or UDP socket for input or output.
Definition: connection.h:29
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
An ordered list of data elements, formatted in memory for transmission over a socket or writing to a ...
Definition: datagram.h:38
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Represents a network address to which UDP packets may be sent or to which a TCP socket may be bound.
Definition: netAddress.h:25
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This flavor of ConnectionListener will queue up all of the TCP connections it established for later d...