00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef __WWWAPI_H__
00012 #define __WWWAPI_H__
00013
00014 #include "stdtp.h"
00015 #include "sync.h"
00016 #include "sockio.h"
00017 #include "database.h"
00018
00019 enum WWWencodingType {
00020 TAG = 0,
00021 HTML = 1,
00022 URL = 2
00023 };
00024
00025
00026
00027
00028
00029
00030
00031 class FASTDB_DLL_ENTRY WWWconnection {
00032 friend class WWWapi;
00033 friend class CGIapi;
00034 friend class QueueManager;
00035 friend class HTTPapi;
00036
00037 public:
00038 void* userData;
00039 typedef bool (*handler)(WWWconnection& con);
00040
00041
00042
00043
00044 WWWconnection& append(char const* str);
00045
00046 WWWconnection& operator << (char const* str) {
00047 return append(str);
00048 }
00049
00050 void setEncoding(WWWencodingType type) { encoding = type; }
00051
00052 WWWconnection& operator << (WWWencodingType type) {
00053 setEncoding(type);
00054 return *this;
00055 }
00056 WWWconnection& operator << (int value) {
00057 char buf[32];
00058 sprintf(buf, "%d", value);
00059 return append(buf);
00060 }
00061
00062 char* getStub() { return stub; }
00063
00064 char* getAddress() { return address; }
00065
00066 char* getPeer() { return peer; }
00067
00068
00069
00070
00071 bool terminatedBy(char const* str) const;
00072
00073
00074
00075
00076
00077
00078
00079
00080 char* get(char const* name, int n = 0);
00081
00082
00083
00084
00085 void addPair(char const* name, char const* value);
00086
00087 WWWconnection();
00088 ~WWWconnection();
00089 protected:
00090 enum { hash_table_size = 1013 };
00091 socket_t* sock;
00092 char* reply_buf;
00093 size_t reply_buf_size;
00094 size_t reply_buf_used;
00095 char* stub;
00096 char* address;
00097 char* peer;
00098 WWWconnection* next;
00099 WWWencodingType encoding;
00100
00101
00102 struct name_value_pair {
00103 name_value_pair* next;
00104 char const* name;
00105 char const* value;
00106 unsigned hash_code;
00107 };
00108
00109 name_value_pair* hash_table[hash_table_size];
00110 name_value_pair* free_pairs;
00111
00112 char* extendBuffer(size_t inc);
00113
00114
00115
00116
00117
00118
00119
00120 void reset();
00121
00122
00123
00124
00125 char* unpack(char* body, size_t body_length);
00126 };
00127
00128
00129 class FASTDB_DLL_ENTRY WWWapi {
00130 public:
00131 struct dispatcher {
00132 char const* page;
00133 WWWconnection::handler func;
00134
00135 unsigned hash_code;
00136 dispatcher* collision_chain;
00137 };
00138
00139 protected:
00140 socket_t* sock;
00141 bool canceled;
00142 char* address;
00143 dbDatabase& db;
00144 enum { hash_table_size = 113 };
00145 dispatcher* hash_table[hash_table_size];
00146
00147 bool dispatch(WWWconnection& con, char* page);
00148
00149 public:
00150 WWWapi(dbDatabase& db, int n_handlers, dispatcher* dispatch_table);
00151
00152
00153
00154
00155 bool open(char const* socket_address = "localhost:80",
00156 socket_t::socket_domain domain = socket_t::sock_global_domain,
00157 int listen_queue = DEFAULT_LISTEN_QUEUE_SIZE);
00158
00159
00160
00161
00162
00163 virtual bool serve(WWWconnection& con) = 0;
00164
00165
00166
00167
00168 bool connect(WWWconnection& con);
00169
00170
00171
00172
00173 void cancel();
00174
00175
00176
00177
00178 void close();
00179 };
00180
00181
00182
00183
00184
00185 class FASTDB_DLL_ENTRY CGIapi : public WWWapi {
00186 public:
00187 virtual bool serve(WWWconnection& con);
00188
00189 CGIapi(dbDatabase& db, int n_handlers, dispatcher* dispatch_table)
00190 : WWWapi(db, n_handlers, dispatch_table) {}
00191 };
00192
00193
00194
00195
00196
00197 class FASTDB_DLL_ENTRY HTTPapi : public WWWapi {
00198 protected:
00199 time_t connectionHoldTimeout;
00200 bool keepConnectionAlive;
00201
00202 bool handleRequest(WWWconnection& con, char* begin, char* end,
00203 char* host, bool& result);
00204
00205 public:
00206 virtual bool serve(WWWconnection& con);
00207
00208 HTTPapi(dbDatabase& db, int n_handlers, dispatcher* dispatch_table,
00209 bool persistentConnections = false,
00210 time_t connectionHoldTimeoutSec = WAIT_FOREVER)
00211 : WWWapi(db, n_handlers, dispatch_table)
00212 {
00213 keepConnectionAlive = persistentConnections;
00214 connectionHoldTimeout = connectionHoldTimeoutSec;
00215 }
00216 };
00217
00218 class FASTDB_DLL_ENTRY QueueManager {
00219 WWWconnection* connectionPool;
00220 WWWconnection* freeList;
00221 WWWconnection* waitList;
00222 dbMutex mutex;
00223 dbLocalSemaphore go;
00224 dbLocalEvent done;
00225 dbThread* threads;
00226 int nThreads;
00227 WWWapi* server;
00228 dbDatabase& db;
00229
00230 static void thread_proc handleThread(void* arg);
00231 void handle();
00232
00233 public:
00234 void stop();
00235 void start();
00236
00237 QueueManager(WWWapi& api,
00238 dbDatabase& db,
00239 int nThreads = 8,
00240 int connectionQueueLen = 64);
00241 ~QueueManager();
00242 };
00243
00244
00245 #endif
00246
00247
00248