PWLib
1.10.10
|
00001 /* 00002 * httpsvc.h 00003 * 00004 * Common classes for service applications using HTTP as the user interface. 00005 * 00006 * Portable Windows Library 00007 * 00008 * Copyright (c) 1993-2002 Equivalence Pty. Ltd. 00009 * 00010 * The contents of this file are subject to the Mozilla Public License 00011 * Version 1.0 (the "License"); you may not use this file except in 00012 * compliance with the License. You may obtain a copy of the License at 00013 * http://www.mozilla.org/MPL/ 00014 * 00015 * Software distributed under the License is distributed on an "AS IS" 00016 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 00017 * the License for the specific language governing rights and limitations 00018 * under the License. 00019 * 00020 * The Original Code is Portable Windows Library. 00021 * 00022 * The Initial Developer of the Original Code is Equivalence Pty. Ltd. 00023 * 00024 * Contributor(s): ______________________________________. 00025 * 00026 * $Log: httpsvc.h,v $ 00027 * Revision 1.45 2005/11/30 12:47:37 csoutheren 00028 * Removed tabs, reformatted some code, and changed tags for Doxygen 00029 * 00030 * Revision 1.44 2003/07/15 11:17:45 csoutheren 00031 * Added additional constructor for PServiceHTTPString, 00032 * Thanks to Federico Pinna 00033 * 00034 * Revision 1.43 2003/02/19 07:23:17 robertj 00035 * Changes to allow for single threaded HTTP service processes. 00036 * 00037 * Revision 1.42 2002/11/06 22:47:24 robertj 00038 * Fixed header comment (copyright etc) 00039 * 00040 * Revision 1.41 2002/07/30 03:47:13 craigs 00041 * Added PHTTPServiceString with content type 00042 * 00043 * Revision 1.40 2002/07/17 08:02:53 robertj 00044 * Allowed for adjustable copyright holder 00045 * 00046 * Revision 1.39 2002/02/05 22:53:14 robertj 00047 * Changed default for HTTP listener to reuse addresses. 00048 * 00049 * Revision 1.38 2001/10/10 08:06:34 robertj 00050 * Fixed problem with not shutting down threads when closing listener. 00051 * 00052 * Revision 1.37 2001/08/28 06:44:30 craigs 00053 * Added ability to override PHTTPServer creation 00054 * 00055 * Revision 1.36 2001/06/23 00:32:15 robertj 00056 * Added parameter to be able to set REUSEADDR on listener socket. 00057 * 00058 * Revision 1.35 2001/03/04 02:24:44 robertj 00059 * Removed default OnControl() from http service as cannot get port number. 00060 * 00061 * Revision 1.34 2001/02/20 02:32:41 robertj 00062 * Added PServiceMacro version that can do substitutions on blocks of HTML. 00063 * 00064 * Revision 1.33 2001/02/15 01:12:15 robertj 00065 * Moved some often repeated HTTP service code into PHTTPServiceProcess. 00066 * 00067 * Revision 1.32 2001/02/14 02:30:59 robertj 00068 * Moved HTTP Service Macro facility to public API so can be used by apps. 00069 * Added ability to specify the service macro keyword, defaults to "macro". 00070 * Added machine macro to get the OS version and hardware. 00071 * 00072 * Revision 1.31 2000/12/14 08:09:41 robertj 00073 * Fixed missing immediate expiry date on string and file service HTTP resourcer. 00074 * 00075 * Revision 1.30 2000/12/11 13:15:17 robertj 00076 * Added macro to include signed or unsigned chunks of HTML. 00077 * Added flag to globally ignore HTML signatures (useful for develeopment). 00078 * 00079 * Revision 1.29 2000/11/02 21:57:00 craigs 00080 * Added extra constructor 00081 * 00082 * Revision 1.28 2000/08/04 12:48:13 robertj 00083 * Added mechanism by which a service can get at new HTTP connections, eg to add SSL. 00084 * 00085 * Revision 1.27 1999/02/16 08:07:10 robertj 00086 * MSVC 6.0 compatibility changes. 00087 * 00088 * Revision 1.26 1998/11/30 02:50:50 robertj 00089 * New directory structure 00090 * 00091 * Revision 1.25 1998/10/29 11:58:51 robertj 00092 * Added ability to configure the HTTP threads stack size. 00093 * 00094 * Revision 1.24 1998/09/23 06:19:34 robertj 00095 * Added open source copyright license. 00096 * 00097 * Revision 1.23 1998/04/01 01:56:47 robertj 00098 * Added PServiceHTTPFile constructor so file path and URL can be different. 00099 * 00100 * Revision 1.22 1998/03/20 03:16:09 robertj 00101 * Added special classes for specific sepahores, PMutex and PSyncPoint. 00102 * 00103 * Revision 1.21 1998/03/17 10:16:00 robertj 00104 * Allowed registration page to have HTML override. 00105 * 00106 * Revision 1.20 1998/02/16 00:15:13 robertj 00107 * Major rewrite of application info passed in PHTTPServiceProcess constructor. 00108 * 00109 * Revision 1.19 1998/01/26 00:28:32 robertj 00110 * Removed POrderPage completely from httpsvc. 00111 * Added PHTTPAuthority to PHTTPServiceString constructor. 00112 * Added option flags to ProcessMacros to automatically load from file etc. 00113 * 00114 * Revision 1.18 1997/11/10 12:40:05 robertj 00115 * Changed SustituteEquivalSequence so can override standard macros. 00116 * 00117 * Revision 1.17 1997/11/04 06:02:56 robertj 00118 * Allowed help gif file name to overridable in PServiceHTML, so can be in subdirectory. 00119 * 00120 * Revision 1.16 1997/10/30 10:22:35 robertj 00121 * Added ability to customise regisration text by application. 00122 * 00123 * Revision 1.15 1997/08/28 13:56:34 robertj 00124 * Fixed bug where HTTP directory was not processed for macros. 00125 * 00126 * Revision 1.13 1997/08/20 08:48:18 craigs 00127 * Added PHTTPServiceDirectory & PHTTPServiceString 00128 * 00129 * Revision 1.12 1997/07/26 11:38:18 robertj 00130 * Support for overridable pages in HTTP service applications. 00131 * 00132 * Revision 1.11 1997/06/16 14:12:55 robertj 00133 * Changed private to protected. 00134 * 00135 * Revision 1.10 1997/06/16 13:20:14 robertj 00136 * Fixed bug where PHTTPThread crashes on exit. 00137 * 00138 * Revision 1.9 1997/03/02 03:42:19 robertj 00139 * Added error logging to standard HTTP Service HTTP Server. 00140 * Removed extraneous variables that set GIF file size to zero. 00141 * 00142 * Revision 1.8 1997/02/05 11:54:52 robertj 00143 * Added support for order form page overridiing. 00144 * 00145 * Revision 1.7 1997/01/27 10:22:33 robertj 00146 * Numerous changes to support OEM versions of products. 00147 * 00148 * Revision 1.6 1996/11/04 03:55:20 robertj 00149 * Changed to accept separate copyright and manufacturer strings. 00150 * 00151 * Revision 1.5 1996/09/14 13:09:12 robertj 00152 * Major upgrade: 00153 * rearranged sockets to help support IPX. 00154 * added indirect channel class and moved all protocols to descend from it, 00155 * separating the protocol from the low level byte transport. 00156 * 00157 * Revision 1.4 1996/08/19 13:43:46 robertj 00158 * Fixed race condition in system restart logic. 00159 * 00160 * Revision 1.3 1996/08/08 13:36:38 robertj 00161 * Fixed Registation page so no longer has static link, ie can be DLLed. 00162 * 00163 * Revision 1.2 1996/06/28 13:15:39 robertj 00164 * Moved HTTP form resource to another compilation module. 00165 * 00166 * Revision 1.1 1996/06/13 13:33:14 robertj 00167 * Initial revision 00168 * 00169 */ 00170 00171 #ifndef APPCOMM_H 00172 #define APPCOMM_H 00173 00174 #include <ptlib/svcproc.h> 00175 #include <ptlib/sockets.h> 00176 #include <ptclib/httpform.h> 00177 #include <ptclib/cypher.h> 00178 00179 00180 class PHTTPServiceProcess; 00181 00182 00184 00185 class PHTTPServiceThread : public PThread 00186 { 00187 PCLASSINFO(PHTTPServiceThread, PThread) 00188 public: 00189 PHTTPServiceThread(PINDEX stackSize, 00190 PHTTPServiceProcess & app); 00191 ~PHTTPServiceThread(); 00192 00193 void Main(); 00194 void Close(); 00195 00196 protected: 00197 PINDEX myStackSize; 00198 PHTTPServiceProcess & process; 00199 PTCPSocket * socket; 00200 }; 00201 00202 00204 00205 class PHTTPServiceProcess : public PServiceProcess 00206 { 00207 PCLASSINFO(PHTTPServiceProcess, PServiceProcess) 00208 00209 public: 00210 enum { 00211 MaxSecuredKeys = 10 00212 }; 00213 struct Info { 00214 const char * productName; 00215 const char * manufacturerName; 00216 00217 WORD majorVersion; 00218 WORD minorVersion; 00219 CodeStatus buildStatus; 00220 WORD buildNumber; 00221 const char * compilationDate; 00222 00223 PTEACypher::Key productKey; 00224 const char * securedKeys[MaxSecuredKeys]; 00225 PINDEX securedKeyCount; 00226 00227 PTEACypher::Key signatureKey; 00228 00229 const char * manufHomePage; 00230 const char * email; 00231 const char * productHTML; 00232 00233 const char * gifHTML; 00234 00235 const char * gifFilename; 00236 int gifWidth; 00237 int gifHeight; 00238 00239 const char * copyrightHolder; 00240 const char * copyrightHomePage; 00241 const char * copyrightEmail; 00242 }; 00243 00244 PHTTPServiceProcess(const Info & inf); 00245 ~PHTTPServiceProcess(); 00246 00247 BOOL OnStart(); 00248 void OnStop(); 00249 BOOL OnPause(); 00250 void OnContinue(); 00251 const char * GetServiceDependencies() const; 00252 00253 virtual void OnConfigChanged() = 0; 00254 virtual BOOL Initialise(const char * initMsg) = 0; 00255 00256 BOOL ListenForHTTP( 00257 WORD port, 00258 PSocket::Reusability reuse = PSocket::CanReuseAddress, 00259 PINDEX stackSize = 0x4000 00260 ); 00261 BOOL ListenForHTTP( 00262 PSocket * listener, 00263 PSocket::Reusability reuse = PSocket::CanReuseAddress, 00264 PINDEX stackSize = 0x4000 00265 ); 00266 00267 virtual PString GetPageGraphic(); 00268 void GetPageHeader(PHTML &); 00269 void GetPageHeader(PHTML &, const PString & title); 00270 00271 virtual PString GetCopyrightText(); 00272 00273 const PString & GetMacroKeyword() const { return macroKeyword; } 00274 const PTime & GetCompilationDate() const { return compilationDate; } 00275 const PString & GetHomePage() const { return manufacturersHomePage; } 00276 const PString & GetEMailAddress() const { return manufacturersEmail; } 00277 const PString & GetProductName() const { return productNameHTML; } 00278 const PTEACypher::Key & GetProductKey() const { return productKey; } 00279 const PStringArray & GetSecuredKeys() const { return securedKeys; } 00280 const PTEACypher::Key & GetSignatureKey() const { return signatureKey; } 00281 BOOL ShouldIgnoreSignatures() const { return ignoreSignatures; } 00282 void SetIgnoreSignatures(BOOL ig) { ignoreSignatures = ig; } 00283 00284 static PHTTPServiceProcess & Current(); 00285 00286 virtual void AddRegisteredText(PHTML & html); 00287 virtual void AddUnregisteredText(PHTML & html); 00288 virtual BOOL SubstituteEquivalSequence(PHTTPRequest & request, const PString &, PString &); 00289 virtual PHTTPServer * CreateHTTPServer(PTCPSocket & socket); 00290 virtual PHTTPServer * OnCreateHTTPServer(const PHTTPSpace & urlSpace); 00291 PTCPSocket * AcceptHTTP(); 00292 BOOL ProcessHTTP(PTCPSocket & socket); 00293 00294 protected: 00295 PSocket * httpListeningSocket; 00296 PHTTPSpace httpNameSpace; 00297 PString macroKeyword; 00298 00299 PTEACypher::Key productKey; 00300 PStringArray securedKeys; 00301 PTEACypher::Key signatureKey; 00302 BOOL ignoreSignatures; 00303 00304 PTime compilationDate; 00305 PString manufacturersHomePage; 00306 PString manufacturersEmail; 00307 PString productNameHTML; 00308 PString gifHTML; 00309 PString copyrightHolder; 00310 PString copyrightHomePage; 00311 PString copyrightEmail; 00312 00313 void ShutdownListener(); 00314 void BeginRestartSystem(); 00315 void CompleteRestartSystem(); 00316 00317 PThread * restartThread; 00318 00319 PLIST(ThreadList, PHTTPServiceThread); 00320 ThreadList httpThreads; 00321 PMutex httpThreadsMutex; 00322 00323 friend class PConfigPage; 00324 friend class PConfigSectionsPage; 00325 friend class PHTTPServiceThread; 00326 }; 00327 00328 00330 00331 class PConfigPage : public PHTTPConfig 00332 { 00333 PCLASSINFO(PConfigPage, PHTTPConfig) 00334 public: 00335 PConfigPage( 00336 PHTTPServiceProcess & app, 00337 const PString & section, 00338 const PHTTPAuthority & auth 00339 ); 00340 PConfigPage( 00341 PHTTPServiceProcess & app, 00342 const PString & title, 00343 const PString & section, 00344 const PHTTPAuthority & auth 00345 ); 00346 00347 void OnLoadedText(PHTTPRequest &, PString & text); 00348 00349 BOOL OnPOST( 00350 PHTTPServer & server, 00351 const PURL & url, 00352 const PMIMEInfo & info, 00353 const PStringToString & data, 00354 const PHTTPConnectionInfo & connectInfo 00355 ); 00356 00357 virtual BOOL Post( 00358 PHTTPRequest & request, 00359 const PStringToString & data, 00360 PHTML & replyMessage 00361 ); 00362 00363 protected: 00364 virtual BOOL GetExpirationDate( 00365 PTime & when 00366 ); 00367 00368 PHTTPServiceProcess & process; 00369 }; 00370 00371 00373 00374 class PConfigSectionsPage : public PHTTPConfigSectionList 00375 { 00376 PCLASSINFO(PConfigSectionsPage, PHTTPConfigSectionList) 00377 public: 00378 PConfigSectionsPage( 00379 PHTTPServiceProcess & app, 00380 const PURL & url, 00381 const PHTTPAuthority & auth, 00382 const PString & prefix, 00383 const PString & valueName, 00384 const PURL & editSection, 00385 const PURL & newSection, 00386 const PString & newTitle, 00387 PHTML & heading 00388 ); 00389 00390 void OnLoadedText(PHTTPRequest &, PString & text); 00391 00392 BOOL OnPOST( 00393 PHTTPServer & server, 00394 const PURL & url, 00395 const PMIMEInfo & info, 00396 const PStringToString & data, 00397 const PHTTPConnectionInfo & connectInfo 00398 ); 00399 00400 virtual BOOL Post( 00401 PHTTPRequest & request, 00402 const PStringToString & data, 00403 PHTML & replyMessage 00404 ); 00405 00406 protected: 00407 virtual BOOL GetExpirationDate( 00408 PTime & when 00409 ); 00410 00411 PHTTPServiceProcess & process; 00412 }; 00413 00414 00416 00417 class PRegisterPage : public PConfigPage 00418 { 00419 PCLASSINFO(PRegisterPage, PConfigPage) 00420 public: 00421 PRegisterPage( 00422 PHTTPServiceProcess & app, 00423 const PHTTPAuthority & auth 00424 ); 00425 00426 PString LoadText( 00427 PHTTPRequest & request 00428 ); 00429 void OnLoadedText(PHTTPRequest & request, PString & text); 00430 00431 virtual BOOL Post( 00432 PHTTPRequest & request, 00433 const PStringToString & data, 00434 PHTML & replyMessage 00435 ); 00436 00437 virtual void AddFields( 00438 const PString & prefix 00439 ) = 0; 00440 00441 protected: 00442 PHTTPServiceProcess & process; 00443 }; 00444 00445 00447 00448 class PServiceHTML : public PHTML 00449 { 00450 PCLASSINFO(PServiceHTML, PHTML) 00451 public: 00452 PServiceHTML(const char * title, 00453 const char * help = NULL, 00454 const char * helpGif = "help.gif"); 00455 00456 PString ExtractSignature(PString & out); 00457 static PString ExtractSignature(const PString & html, 00458 PString & out, 00459 const char * keyword = "#equival"); 00460 00461 PString CalculateSignature(); 00462 static PString CalculateSignature(const PString & out); 00463 static PString CalculateSignature(const PString & out, const PTEACypher::Key & sig); 00464 00465 BOOL CheckSignature(); 00466 static BOOL CheckSignature(const PString & html); 00467 00468 enum MacroOptions { 00469 NoOptions = 0, 00470 NeedSignature = 1, 00471 LoadFromFile = 2, 00472 NoURLOverride = 4, 00473 NoSignatureForFile = 8 00474 }; 00475 static BOOL ProcessMacros(PHTTPRequest & request, 00476 PString & text, 00477 const PString & filename, 00478 unsigned options); 00479 }; 00480 00481 00483 00484 class PServiceMacro : public PObject 00485 { 00486 public: 00487 PServiceMacro(const char * name, BOOL isBlock); 00488 PServiceMacro(const PCaselessString & name, BOOL isBlock); 00489 Comparison Compare(const PObject & obj) const; 00490 virtual PString Translate( 00491 PHTTPRequest & request, 00492 const PString & args, 00493 const PString & block 00494 ) const; 00495 protected: 00496 const char * macroName; 00497 BOOL isMacroBlock; 00498 PServiceMacro * link; 00499 static PServiceMacro * list; 00500 friend class PServiceMacros_list; 00501 }; 00502 00503 00504 #define P_EMPTY 00505 00506 #define PCREATE_SERVICE_MACRO(name, request, args) \ 00507 class PServiceMacro_##name : public PServiceMacro { \ 00508 public: \ 00509 PServiceMacro_##name() : PServiceMacro(#name, FALSE) { } \ 00510 PString Translate(PHTTPRequest &, const PString &, const PString &) const; \ 00511 }; \ 00512 static const PServiceMacro_##name serviceMacro_##name; \ 00513 PString PServiceMacro_##name::Translate(PHTTPRequest & request, const PString & args, const PString &) const 00514 00515 00516 00517 #define PCREATE_SERVICE_MACRO_BLOCK(name, request, args, block) \ 00518 class PServiceMacro_##name : public PServiceMacro { \ 00519 public: \ 00520 PServiceMacro_##name() : PServiceMacro(#name, TRUE) { } \ 00521 PString Translate(PHTTPRequest &, const PString &, const PString &) const; \ 00522 }; \ 00523 static const PServiceMacro_##name serviceMacro_##name; \ 00524 PString PServiceMacro_##name::Translate(PHTTPRequest & request, const PString & args, const PString & block) const 00525 00526 00527 00529 00530 class PServiceHTTPString : public PHTTPString 00531 { 00532 PCLASSINFO(PServiceHTTPString, PHTTPString) 00533 public: 00534 PServiceHTTPString(const PURL & url, const PString & string) 00535 : PHTTPString(url, string) { } 00536 00537 PServiceHTTPString(const PURL & url, const PHTTPAuthority & auth) 00538 : PHTTPString(url, auth) { } 00539 00540 PServiceHTTPString(const PURL & url, const PString & string, const PHTTPAuthority & auth) 00541 : PHTTPString(url, string, auth) { } 00542 00543 PServiceHTTPString(const PURL & url, const PString & string, const PString & contentType) 00544 : PHTTPString(url, string, contentType) { } 00545 00546 PServiceHTTPString(const PURL & url, const PString & string, const PString & contentType, const PHTTPAuthority & auth) 00547 : PHTTPString(url, string, contentType, auth) { } 00548 00549 PString LoadText(PHTTPRequest &); 00550 00551 protected: 00552 virtual BOOL GetExpirationDate( 00553 PTime & when 00554 ); 00555 }; 00556 00557 00558 class PServiceHTTPFile : public PHTTPFile 00559 { 00560 PCLASSINFO(PServiceHTTPFile, PHTTPFile) 00561 public: 00562 PServiceHTTPFile(const PString & filename, BOOL needSig = FALSE) 00563 : PHTTPFile(filename) { needSignature = needSig; } 00564 PServiceHTTPFile(const PString & filename, const PFilePath & file, BOOL needSig = FALSE) 00565 : PHTTPFile(filename, file) { needSignature = needSig; } 00566 PServiceHTTPFile(const PString & filename, const PHTTPAuthority & auth, BOOL needSig = FALSE) 00567 : PHTTPFile(filename, auth) { needSignature = needSig; } 00568 PServiceHTTPFile(const PString & filename, const PFilePath & file, const PHTTPAuthority & auth, BOOL needSig = FALSE) 00569 : PHTTPFile(filename, file, auth) { needSignature = needSig; } 00570 00571 void OnLoadedText(PHTTPRequest &, PString & text); 00572 00573 protected: 00574 virtual BOOL GetExpirationDate( 00575 PTime & when 00576 ); 00577 00578 BOOL needSignature; 00579 }; 00580 00581 class PServiceHTTPDirectory : public PHTTPDirectory 00582 { 00583 PCLASSINFO(PServiceHTTPDirectory, PHTTPDirectory) 00584 public: 00585 PServiceHTTPDirectory(const PURL & url, const PDirectory & dirname, BOOL needSig = FALSE) 00586 : PHTTPDirectory(url, dirname) { needSignature = needSig; } 00587 00588 PServiceHTTPDirectory(const PURL & url, const PDirectory & dirname, const PHTTPAuthority & auth, BOOL needSig = FALSE) 00589 : PHTTPDirectory(url, dirname, auth) { needSignature = needSig; } 00590 00591 void OnLoadedText(PHTTPRequest &, PString & text); 00592 00593 protected: 00594 virtual BOOL GetExpirationDate( 00595 PTime & when 00596 ); 00597 00598 BOOL needSignature; 00599 }; 00600 00601 00602 #endif