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
00039 typedef void (*UserDataDestructor)(void* userData);
00040 typedef bool (*handler)(WWWconnection& con);
00041
00042 void* userData;
00043 UserDataDestructor userDataDestructor;
00044
00045 void setUserData(void* data, UserDataDestructor destructor = NULL) {
00046 userData = data;
00047 userDataDestructor = destructor;
00048 }
00049
00050
00051
00052
00053 WWWconnection& append(char const* str);
00054
00055
00056
00057 WWWconnection& append(const void *buf, int len);
00058
00059 WWWconnection& operator << (char const* str) {
00060 return append(str);
00061 }
00062
00063 void setEncoding(WWWencodingType type) { encoding = type; }
00064
00065 WWWconnection& operator << (WWWencodingType type) {
00066 setEncoding(type);
00067 return *this;
00068 }
00069 WWWconnection& operator << (int value) {
00070 char buf[32];
00071 sprintf(buf, "%d", value);
00072 return append(buf);
00073 }
00074 WWWconnection& operator << (double value) {
00075 char buf[32];
00076 sprintf(buf, "%f", value);
00077 return append(buf);
00078 }
00079
00080 WWWconnection& operator << (db_int8 value) {
00081 char buf[32];
00082 sprintf(buf, INT8_FORMAT, value);
00083 return append(buf);
00084 }
00085
00086 WWWconnection& operator << (oid_t value) {
00087 char buf[32];
00088 sprintf(buf, "%ld", (long)value);
00089 return append(buf);
00090 }
00091
00092 char* getStub() { return stub; }
00093
00094 char* getAddress() { return address; }
00095
00096 char* getPeer() { return peer; }
00097
00098
00099
00100
00101 bool terminatedBy(char const* str) const;
00102
00103
00104
00105
00106
00107
00108
00109
00110 char* get(char const* name, int n = 0);
00111
00112
00113
00114
00115 void addPair(char const* name, char const* value);
00116
00117 WWWconnection();
00118 ~WWWconnection();
00119
00120 protected:
00121 enum { hash_table_size = 1013 };
00122 socket_t* sock;
00123 char* reply_buf;
00124 size_t reply_buf_size;
00125 size_t reply_buf_used;
00126 char* stub;
00127 char* address;
00128 char* peer;
00129 WWWconnection* next;
00130 WWWencodingType encoding;
00131
00132
00133 struct name_value_pair {
00134 name_value_pair* next;
00135 char const* name;
00136 char const* value;
00137 unsigned hash_code;
00138 };
00139
00140 name_value_pair* hash_table[hash_table_size];
00141 name_value_pair* free_pairs;
00142
00143 char* extendBuffer(size_t inc);
00144
00145
00146
00147
00148
00149
00150
00151 void reset();
00152
00153
00154
00155
00156 char* unpack(char* body, size_t body_length);
00157 };
00158
00159
00160 class FASTDB_DLL_ENTRY WWWapi {
00161 public:
00162 struct dispatcher {
00163 char const* page;
00164 WWWconnection::handler func;
00165
00166 unsigned hash_code;
00167 dispatcher* collision_chain;
00168 };
00169
00170 protected:
00171 socket_t* sock;
00172 bool canceled;
00173 char* address;
00174 dbDatabase& db;
00175 enum { hash_table_size = 113 };
00176 dispatcher* hash_table[hash_table_size];
00177
00178 bool dispatch(WWWconnection& con, char* page);
00179
00180 public:
00181 WWWapi(dbDatabase& db, int n_handlers, dispatcher* dispatch_table);
00182
00183
00184
00185
00186 bool open(char const* socket_address = "localhost:80",
00187 socket_t::socket_domain domain = socket_t::sock_global_domain,
00188 int listen_queue = DEFAULT_LISTEN_QUEUE_SIZE);
00189
00190
00191
00192
00193
00194 virtual bool serve(WWWconnection& con) = 0;
00195
00196
00197
00198
00199 bool connect(WWWconnection& con);
00200
00201
00202
00203
00204 void cancel();
00205
00206
00207
00208
00209 void close();
00210 };
00211
00212
00213
00214
00215
00216 class FASTDB_DLL_ENTRY CGIapi : public WWWapi {
00217 public:
00218 virtual bool serve(WWWconnection& con);
00219
00220 CGIapi(dbDatabase& db, int n_handlers, dispatcher* dispatch_table)
00221 : WWWapi(db, n_handlers, dispatch_table) {}
00222 };
00223
00224
00225
00226
00227
00228 class FASTDB_DLL_ENTRY HTTPapi : public WWWapi {
00229 protected:
00230 time_t connectionHoldTimeout;
00231 bool keepConnectionAlive;
00232
00233 bool handleRequest(WWWconnection& con, char* begin, char* end,
00234 char* host, bool& result);
00235
00236 public:
00237 virtual bool serve(WWWconnection& con);
00238
00239 HTTPapi(dbDatabase& db, int n_handlers, dispatcher* dispatch_table,
00240 bool persistentConnections = false,
00241 time_t connectionHoldTimeoutSec = WAIT_FOREVER)
00242 : WWWapi(db, n_handlers, dispatch_table)
00243 {
00244 keepConnectionAlive = persistentConnections;
00245 connectionHoldTimeout = connectionHoldTimeoutSec;
00246 }
00247 };
00248
00249 class FASTDB_DLL_ENTRY QueueManager {
00250 WWWconnection* connectionPool;
00251 WWWconnection* freeList;
00252 WWWconnection* waitList;
00253 dbMutex mutex;
00254 dbLocalSemaphore go;
00255 dbLocalEvent done;
00256 dbThread* threads;
00257 int nThreads;
00258 WWWapi* server;
00259 dbDatabase& db;
00260
00261 static void thread_proc handleThread(void* arg);
00262 void handle();
00263
00264 public:
00265 void stop();
00266 void start();
00267
00268 QueueManager(WWWapi& api,
00269 dbDatabase& db,
00270 int nThreads = 8,
00271 int connectionQueueLen = 64);
00272 ~QueueManager();
00273 };
00274
00275
00276 #endif
00277
00278
00279