00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
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
00055
00056
00057
00058
00059
00060
00061
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