Main Page | Class Hierarchy | Class List | File List | Class Members

wwwapi.h

00001 //-< WWWAPI.H >------------------------------------------------------*--------*
00002 // FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Main Memory Database Management System)                          *   /\|  *
00004 //                                                                   *  /  \  *
00005 //                          Created:     27-Mar-99    K.A. Knizhnik  * / [] \ *
00006 //                          Last update:  1-Jul-99    K.A. Knizhnik  * GARRET *
00007 //-------------------------------------------------------------------*--------*
00008 // API for creating Internet applications 
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, // HTML tags (no conversion)
00021     HTML = 1, // replace ('<','>','"','&') with (&lt; &gt; &amp; &qout;)
00022     URL  = 2  // replace spaces with '+', and other special characters with %XX
00023 };
00024 //
00025 // Automatic state shifts after each append operation:
00026 //   TAG->HTML
00027 //   HTML->TAG
00028 //   URL->TAG
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     // Append string to reply buffer
00052     //
00053     WWWconnection& append(char const* str);
00054     //
00055     // Append binary data
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     // Compare content of the string with the end of the reply buffer
00100     //
00101     bool terminatedBy(char const* str) const;
00102 
00103     //
00104     // Get value of variable from request string. If name is not present in 
00105     // string NULL is returned. Parameter 'n' can be used to get n-th
00106     // value of variable for multiple selection slot. Zero value of n 
00107     // corresponds to the first variable's value, 1 - to the second,...
00108     // When no more values are available NULL is returned.
00109     //
00110     char* get(char const* name, int n = 0);
00111     
00112     //
00113     // Associatte value with name
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     // Deallocate all resources hold by connection. It is not possible to 
00148     // call get_value() or reply() method after this. Method reset()
00149     // is implicitly called by WWWapi::get() method.
00150     //
00151     void reset();
00152 
00153     //
00154     // Unpack requests paramters
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         // filled by contracutor of WWWapi
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     // Bind and listen socket
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     // Read and execute requests
00193     //
00194     virtual bool serve(WWWconnection& con) = 0;
00195 
00196     //
00197     // Accept new connection by the socket
00198     //
00199     bool connect(WWWconnection& con);
00200 
00201     //
00202     // Cancel acception of connections
00203     // 
00204     void cancel();
00205 
00206     //
00207     // Close socket
00208     // 
00209     void close();
00210 };
00211 
00212 
00213 //
00214 // Interaction with WWW server by means of CGI protocol and CGIatub program
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 // Built-in implementation of sunset of subset of HTTP protocol
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, // WWWapi should be opened
00269                  dbDatabase& db,
00270                  int     nThreads = 8, 
00271                  int     connectionQueueLen = 64);
00272     ~QueueManager();
00273 };
00274 
00275 
00276 #endif
00277 
00278 
00279 

Generated on Thu Feb 12 13:04:48 2004 for FastDB by doxygen 1.3.5