Main Page   Class Hierarchy   Compound List   File List   Compound Members  

wwwapi.h

00001 //-< WWWAPI.H >------------------------------------------------------*--------*
00002 // GigaBASE                  Version 1.0         (c) 1999  GARRET    *     ?  *
00003 // (Post Relational 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 BEGIN_GIGABASE_NAMESPACE
00020 
00021 enum WWWencodingType {
00022     TAG  = 0, // HTML tags (no conversion)
00023     HTML = 1, // replace ('<','>','"','&') with (&lt; &gt; &amp; &qout;)
00024     URL  = 2,  // replace spaces with '+', and other special characters with %XX
00025     ENTITY = 3  // same as html and replace non ascii code by &#xxx; (xml entity)
00026 };
00027 //
00028 // Automatic state shifts after each append operation:
00029 //   TAG->HTML
00030 //   HTML->TAG
00031 //   URL->TAG
00032 //
00033 
00034 class GIGABASE_DLL_ENTRY WWWconnection {
00035     friend class WWWapi;
00036     friend class CGIapi;
00037     friend class QueueManager;
00038     friend class HTTPapi;
00039   
00040  public:
00041     
00042     typedef void (*UserDataDestructor)(void* userData);
00043     typedef bool (*handler)(WWWconnection& con);
00044 
00045     void*              userData;
00046     UserDataDestructor userDataDestructor;
00047 
00048     void setUserData(void* data, UserDataDestructor destructor = NULL) { 
00049         userData = data;
00050         userDataDestructor = destructor;
00051     }
00052 
00053     //
00054     // Append string to reply buffer
00055     //
00056     WWWconnection& append(char const* str);
00057     //
00058     // Append binary data
00059     // 
00060     WWWconnection& append(const void *buf, int len);
00061 
00062     WWWconnection& operator << (char const* str) {
00063         return append(str);
00064     }
00065 #ifdef UNICODE
00066     WWWconnection& append(wchar_t const* str);
00067     WWWconnection& operator << (wchar_t const* str) {
00068         return append(str);
00069     }
00070 #endif
00071   
00072     void setEncoding(WWWencodingType type) { encoding = type; }
00073   
00074     WWWconnection& operator << (WWWencodingType type) {
00075         setEncoding(type);
00076         return *this;
00077     }
00078     WWWconnection& operator << (double value) {
00079         char buf[32];
00080         sprintf(buf, "%f", value);
00081         return append(buf);
00082     }
00083   
00084     WWWconnection& operator << (db_int8 value) {
00085         char buf[32];
00086         sprintf(buf, INT8_FORMAT, value);
00087         return append(buf);
00088     }
00089   
00090     WWWconnection& operator << (int value) {
00091         char buf[32];
00092         sprintf(buf, "%d", value);
00093         return append(buf);
00094     }
00095   
00096     WWWconnection& operator << (oid_t value) {        
00097         char buf[32];   
00098         sprintf(buf, "%ld", (long)value);
00099         return append(buf);
00100     }
00101   
00102     char* getStub() { return stub; }
00103   
00104     char* getAddress() { return address; }
00105   
00106     char* getPeer() { return peer; }
00107   
00108     //
00109     // Compare content of the string with the end of the reply buffer
00110     //
00111     bool terminatedBy(char const* str) const;
00112   
00113     //
00114     // Get value of variable from request string. If name is not present in
00115     // string NULL is returned. Parameter 'n' can be used to get n-th
00116     // value of variable for multiple selection slot. Zero value of n
00117     // corresponds to the first variable's value, 1 - to the second,...
00118     // When no more values are available NULL is returned.
00119     //
00120     char* get(char const* name, int n = 0);
00121   
00122     //
00123     // Associatte value with name
00124     //
00125     void addPair(char const* name, char const* value);
00126   
00127 
00128     WWWconnection();
00129     ~WWWconnection();
00130 
00131  protected:
00132     enum { hash_table_size = 1013 };
00133     socket_t*   sock;
00134     char*       reply_buf;
00135     size_t      reply_buf_size;
00136     size_t      reply_buf_used;
00137     char*       stub;
00138     char*       address;
00139     char*       peer;
00140 
00141     WWWconnection*  next;
00142     WWWencodingType encoding;
00143   
00144   
00145     struct name_value_pair {
00146         name_value_pair* next;
00147         char const*      name;
00148         char const*      value;
00149         unsigned         hash_code;
00150     };
00151   
00152     name_value_pair* hash_table[hash_table_size];
00153     name_value_pair* free_pairs;
00154   
00155     char* extendBuffer(size_t inc);
00156   
00157   
00158     //
00159     // Deallocate all resources hold by connection. It is not possible to
00160     // call get_value() or reply() method after this. Method reset()
00161     // is implicitly called by WWWapi::get() method.
00162     //
00163     void reset();
00164   
00165     //
00166     // Unpack requests paramters
00167     //
00168     char* unpack(char* body, size_t body_length);
00169 };
00170 
00171 
00172 class GIGABASE_DLL_ENTRY WWWapi {
00173  public:
00174     struct dispatcher {
00175         char const*         page;
00176         WWWconnection::handler func;
00177         // filled by contracutor of WWWapi
00178         unsigned            hash_code;
00179         dispatcher*         collision_chain;
00180     };
00181   
00182  protected:
00183     socket_t*   sock;
00184     bool        canceled;
00185     char*       address;
00186     dbDatabase& db;
00187     enum { hash_table_size = 113  };
00188     dispatcher* hash_table[hash_table_size];
00189     char* rootPath;
00190     
00191     bool dispatch(WWWconnection& con, char* page);
00192     
00193  public:
00194     WWWapi(dbDatabase& db, int n_handlers, dispatcher* dispatch_table, char const* rootpath=NULL);
00195     
00196     virtual ~WWWapi();
00197     //
00198     // Bind and listen socket
00199     //
00200     bool open(char const* socket_address = "localhost:80",
00201               socket_t::socket_domain domain = socket_t::sock_global_domain,
00202               int listen_queue = DEFAULT_LISTEN_QUEUE_SIZE);
00203     
00204     
00205     //
00206     // Read and execute requests
00207     //
00208     virtual bool serve(WWWconnection& con) = 0;
00209     
00210     //
00211     // Accept new connection by the socket
00212     //
00213     bool connect(WWWconnection& con);
00214     
00215     //
00216     // Cancel acception of connections
00217     //
00218     void cancel();
00219     
00220     //
00221     // Close socket
00222     //
00223     void close();
00224 };
00225 
00226 
00227 //
00228 // Interaction with WWW server by means of CGI protocol and CGIatub program
00229 //
00230 class GIGABASE_DLL_ENTRY CGIapi : public WWWapi {
00231  public:
00232     virtual bool serve(WWWconnection& con);
00233 
00234     CGIapi(dbDatabase& db, int n_handlers, dispatcher* dispatch_table, const char* rootpath=NULL)
00235         : WWWapi(db, n_handlers, dispatch_table, rootpath) {}
00236 };
00237 
00238 
00239 //
00240 // Built-in implementation of sunset of subset of HTTP protocol
00241 //
00242 class GIGABASE_DLL_ENTRY HTTPapi : public WWWapi {
00243  protected:
00244     time_t connectionHoldTimeout;
00245     bool   keepConnectionAlive;
00246 
00247     bool handleRequest(WWWconnection& con, char* begin, char* end,
00248                        char* host, bool& result);
00249 
00250  public:
00251     virtual bool serve(WWWconnection& con);
00252 
00253     HTTPapi(dbDatabase& db, int n_handlers, dispatcher* dispatch_table,
00254             bool persistentConnections = false,
00255             time_t connectionHoldTimeoutSec = WAIT_FOREVER,
00256             const char * rootpath=NULL)
00257         : WWWapi(db, n_handlers, dispatch_table, rootpath)
00258     {
00259         keepConnectionAlive = persistentConnections;
00260         connectionHoldTimeout = connectionHoldTimeoutSec;
00261     }
00262 };
00263 
00264 class GIGABASE_DLL_ENTRY QueueManager {
00265     WWWconnection* connectionPool;
00266     WWWconnection* freeList;
00267     WWWconnection* waitList;
00268     dbMutex        mutex;
00269     dbSemaphore    go;
00270     dbEvent        done;
00271     dbThread*      threads;
00272     int            nThreads;
00273     WWWapi*        server;
00274     dbDatabase&    db;
00275 
00276     static void thread_proc handleThread(void* arg);
00277     void handle();
00278 
00279  public:
00280     void stop();
00281     void start();
00282     void cleanup(WWWconnection::handler cleanupfunc);
00283     
00284     QueueManager(WWWapi& api, // WWWapi should be opened
00285                  dbDatabase& db,
00286                  int     nThreads = 8,
00287                  int     connectionQueueLen = 64
00288                  );
00289     ~QueueManager();
00290 };
00291 
00292 END_GIGABASE_NAMESPACE
00293 
00294 
00295 #endif
00296 
00297 
00298 

Generated on Thu Aug 23 19:35:52 2007 for GigaBASE by doxygen1.2.18