web/webserver.hh

00001 /* -*- mode: c++; c-basic-offset: 4; -*- */
00002 /*----------------------------------------------------------------------*/
00003 /*                                                                      */
00004 /* Module Name: webserver                                               */
00005 /*                                                                      */
00006 /* Module Description: a basic web server                               */
00007 /*                                                                      */
00008 /* Revision History:                                                    */
00009 /* Rel   Date     Programmer    Comments                                */
00010 /* 0.1   4Jan02   D. Sigg       First release                           */
00011 /*                                                                      */
00012 /* Documentation References:                                            */
00013 /*      Man Pages: webserver.html                                       */
00014 /*      References: none                                                */
00015 /*                                                                      */
00016 /* Author Information:                                                  */
00017 /* Name          Telephone       Fax             e-mail                 */
00018 /* Daniel Sigg   (509) 372-8132  (509) 372-8137  sigg_d@ligo.mit.edu    */
00019 /*                                                                      */
00020 /*                                                                      */
00021 /*                      -------------------                             */
00022 /*                                                                      */
00023 /*                             LIGO                                     */
00024 /*                                                                      */
00025 /*        THE LASER INTERFEROMETER GRAVITATIONAL WAVE OBSERVATORY.      */
00026 /*                                                                      */
00027 /*                     (C) The LIGO Project, 1999.                      */
00028 /*                                                                      */
00029 /*                                                                      */
00030 /* Caltech                              MIT                             */
00031 /* LIGO Project MS 51-33                LIGO Project NW-17 161          */
00032 /* Pasadena CA 91125                    Cambridge MA 01239              */
00033 /*                                                                      */
00034 /* LIGO Hanford Observatory             LIGO Livingston Observatory     */
00035 /* P.O. Box 1970 S9-02                  19100 LIGO Lane Rd.             */
00036 /* Richland WA 99352                    Livingston, LA 70754            */
00037 /*                                                                      */
00038 /*----------------------------------------------------------------------*/
00039 
00040 #ifndef _LIGO_WEBSERVER_H
00041 #define _LIGO_WEBSERVER_H
00042 
00043 
00044 #include <semaphore.h>
00045 #include <sys/types.h>
00046 #include <sys/socket.h>
00047 #include <vector>
00048 #include <map>
00049 #include <string>
00050 #include <iosfwd>
00051 #include "gmutex.hh"
00052 #include "web/webcache.hh"
00053 
00054 //  The hostname printing caused the web server to fail when a dns was.
00055 //  for this reason, I have slightly reformatted the transaction log
00056 //  printout and mad the host-name translation optional. To turn on the
00057 //  hostname printing you must uncomment the following line:
00058 //
00059 //  #define WEBSRV_HOSTNAME 1
00060 //
00061 //--> JGZ  31.X.2006
00062 
00063 namespace web {
00064 
00065    const int kDefaultPort = 80;
00066 
00087    class request_t {
00088    public:
00090       enum req_type {
00092       rInvalid, 
00094       rGet, 
00096       rPost, 
00098       rHead,
00100       rOptions,
00102       rPut,
00104       rDelete,
00106       rTrace,
00108       rConnect
00109       };
00111       class header_sort {
00112       public:
00114          bool operator () (const std::string& s1, const std::string& s2) const;
00115       };
00117       typedef std::map <std::string, std::string, header_sort> header_type;
00122       struct browser_t {
00124          browser_t (const char* p = 0);
00126          int    fMajor;
00128          float  fMinor;
00130          bool   fIsNav;
00132          bool   fIsNav2;
00134          bool   fIsNav3;
00136          bool   fIsNav4;
00138          bool   fIsNav4up;
00140          bool   fIsNavOnly;
00142          bool   fIsNav6;
00144          bool   fIsNav6up;
00146          bool   fIsGecko;
00148          bool   fIsIe;
00150          bool   fIsIe3;
00152          bool   fIsIe4;
00154          bool   fIsIe4up;
00156          bool   fIsIe5;
00158          bool   fIsIe5_5;
00160          bool   fIsIe5up;
00162          bool   fIsIe5_5up;
00164          bool   fIsIe6;
00166          bool   fIsIe6up;
00168          bool   fIsAol;
00170          bool   fIsAol3;
00172          bool   fIsAol4;
00174          bool   fIsAol5;
00176          bool   fIsAol6;
00178          bool   fIsOpera;
00180          bool   fIsOpera2;
00182          bool   fIsOpera3;
00184          bool   fIsOpera4;
00186          bool   fIsOpera5;
00188          bool   fIsOpera5up;
00190          bool   fIsWebtv; 
00192          bool   fIsTVNavigator; 
00194          bool   fIsAOLTV;
00196          bool   fIsHotjava;
00198          bool   fIsHotjava3;
00200          bool   fIsHotjava3up;
00202          float  fJsVersion;
00204          bool   fIsWin;
00206          bool   fIsWin95;
00208          bool   fIsWin16;  
00210          bool   fIsWin31;
00212          bool   fIsWinme;
00214          bool   fIsWin2k;
00216          bool   fIsWin98;
00218          bool   fIsWinnt;
00220          bool   fIsWin32;
00222          bool   fIsOs2;
00224          bool   fIsMac;
00226          bool   fIsMac68k;
00228          bool   fIsMacppc;
00230          bool   fIsSun;
00232          bool   fIsSun4;
00234          bool   fIsSun5;
00236          bool   fIsSuni86;
00238          bool   fIsIrix;
00240          bool   fIsIrix5;
00242          bool   fIsIrix6;
00244          bool   fIsHpux;
00246          bool   fIsHpux9;
00248          bool   fIsHpux10;
00250          bool   fIsAix;
00252          bool   fIsAix1;    
00254          bool   fIsAix2;    
00256          bool   fIsAix3;    
00258          bool   fIsAix4;    
00260          bool   fIsLinux;
00262          bool   fIsSco;
00264          bool   fIsUnixware; 
00266          bool   fIsMpras; 
00268          bool   fIsReliant;
00270          bool   fIsDec;
00272          bool   fIsSinix;
00274          bool   fIsFreebsd;
00276          bool   fIsBsd;
00278          bool   fIsUnix;
00280          bool   fIsVms;
00281       };
00282    
00284       request_t() 
00285       : fHttpVersion (10), fType (rInvalid), fKeepAlive (false), 
00286       fData (0), fLen (0) {
00287       }
00289       request_t (int fd)     
00290       : fHttpVersion (10), fType (rInvalid), fKeepAlive (false), 
00291       fData (0), fLen (0) {
00292          read (fd); }
00294       ~request_t() {
00295          if (fData) delete[] fData; }
00297       bool read (int fd);
00299       void SetType (req_type p) {
00300          fType = p; }
00302       req_type GetType() const {
00303          return fType; }
00305       void SetUrl (const char* p) {
00306          fUrl = p; }
00308       const char* GetUrl() const {
00309          return fUrl.c_str(); }
00311       std::string GetDemangledUrl() const;
00313       header_type& Header() {
00314          return fHeader; }
00316       const header_type& Header() const {
00317          return fHeader; }
00319       bool KeepAlive() const {
00320          return fKeepAlive; }
00321    
00323       const char* GetData() const {
00324          return fData; }
00326       char* GetData() {
00327          return fData; }
00329       void SetData (const char* p, int len) {
00330          Reserve (len); 
00331          if (len) memcpy (fData, p, len); };
00333       void Reserve (int len) {
00334          if (fData) delete [] fData; 
00335          fData = (len > 0) ? new char [len] : 0; 
00336          fLen = (len > 0) ? len : 0; }
00338       int GetLength() const {
00339          return fLen; }
00341       int GetHttpVersion() const {
00342          return fHttpVersion; }
00344       const browser_t& GetBrowser() const {
00345          return fBrowser; }
00346    private:
00347       int               fHttpVersion;
00348       browser_t         fBrowser;
00349       req_type          fType;
00350       std::string       fUrl;
00351       header_type       fHeader;
00352       bool              fKeepAlive;
00353       char*             fData;
00354       int               fLen;
00355    
00356       request_t (const request_t&);
00357       request_t& operator= (const request_t&);
00358    };
00359 
00366    class response_t {
00367    public:
00369       typedef std::pair <std::string, std::string> header_entry;
00371       typedef std::vector <header_entry> header_type;
00372    
00374       response_t() : fData (0), fLen (0), fCanCompress (false) {
00375       }
00377       ~response_t() {
00378          if (fData) delete[] fData; }
00379    
00381       bool write (int fd);
00383       void SetStatusLine (const char* p) {
00384          fStatusLine = p; }
00386       const char* GetStatusLine() const {
00387          return fStatusLine.c_str(); }
00389       void AddHeader (const std::string& name, const std::string& token);
00391       void RemoveHeader (const std::string& name);
00393       header_type& GetHeader() {
00394          return fHeader; }
00396       const header_type& GetHeader() const {
00397          return fHeader; }
00398    
00400       const char* GetData() const {
00401          return fData; }
00403       char* GetData() {
00404          return fData; }
00406       void SetData (const char* p, int len) {
00407          Reserve (len); 
00408          if (len) memcpy (fData, p, len); };
00410       void SetData (const std::string& s) {
00411          SetData(s.c_str(), s.size());}
00413       void Reserve (int len) {
00414          if (fData) delete [] fData; 
00415          fData = (len > 0) ? new char [len] : 0; 
00416          fLen = (len > 0) ? len : 0; }
00418       int GetLength() const {
00419          return fLen; }
00421       void SetCanCompress (bool set = true) {
00422          fCanCompress = set; }
00424       bool GetCanCompress() const {
00425          return fCanCompress; }
00427       bool TryCompress();
00428    private:
00429       std::string       fStatusLine;
00430       header_type       fHeader;
00431       char*             fData;
00432       int               fLen;
00433       bool              fCanCompress;
00434    
00435       response_t (const response_t&);
00436       response_t& operator= (const response_t&);
00437    };
00438 
00439    inline void 
00440    response_t::AddHeader(const std::string& name, const std::string& token) {
00441      header_entry ent(name, token);
00442      fHeader.push_back(ent); 
00443    }
00444 
00445 
00461    class basic_server {
00462    public:
00476       basic_server (int argn, char** argv, int max = 20, 
00477                    bool ctrlC = true, int maxretry = 0);
00481       virtual ~basic_server();
00486       virtual void Listen();
00494       virtual bool Parse (int csock, struct sockaddr* caddr, int clen);
00495    
00500       int getPort() const {
00501          return fPort; }
00502    
00507       void SetLog (std::ostream* os) {
00508          fLog = os; }
00509    
00515       virtual void Interrupt (int sig);
00516    
00517    protected:
00519       mutable thread::recursivemutex    fMux;
00521       webcache                          fCache;
00522    
00530       virtual void Spawn (int csock, struct sockaddr* caddr, int clen);
00538       virtual bool Request (const request_t& request,
00539                         response_t& response);                                                  
00548       virtual bool RequestConnect (const request_t& request,
00549                         response_t& response);
00558       virtual bool RequestGet (const request_t& request,
00559                         response_t& response);
00568       virtual bool RequestHead (const request_t& request,
00569                         response_t& response);
00578       virtual bool RequestPost (const request_t& request,
00579                         response_t& response);
00588       virtual bool RequestPut (const request_t& request,
00589                         response_t& response);
00598       virtual bool RequestDelete (const request_t& request,
00599                         response_t& response);
00608       virtual bool RequestOptions (const request_t& request,
00609                         response_t& response);
00618       virtual bool RequestTrace (const request_t& request,
00619                         response_t& response);
00625       virtual bool CheckCache (const request_t& request, 
00626                         response_t& response);
00630       virtual void Close();
00631    
00633       std::ostream*             fLog;
00634    
00635    private:
00636       typedef std::vector<pthread_t> thread_list;
00638       sem_t                     fThreadCount;
00640       mutable thread::mutex     fThreadMux;
00642       thread_list               fThreads;
00644       int                       fMainSocket;
00646       int                       fPort;
00647    };
00648 
00649 }
00650 
00651 #endif // _LIGO_WEBSERVER_H

Generated on Sun Mar 8 19:20:52 2009 for dmt by  doxygen 1.5.4