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