# httpsvc.h

Go to the documentation of this file.

    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  * $Revision: 24177 $
    00027  * $Author: rjongbloed $
    00028  * $Date: 2010-04-05 06:52:04 -0500 (Mon, 05 Apr 2010) $
    00029  */
    00030
    00031 #ifndef PTLIB_HTTPSVC_H
    00032 #define PTLIB_HTTPSVC_H
    00033
    00034 #include <ptlib/svcproc.h>
    00035 #include <ptlib/sockets.h>
    00036 #include <ptclib/httpform.h>
    00037 #include <ptclib/cypher.h>
    00038
    00039
    00040 class PHTTPServiceProcess;
    00041
    00042
    00044
    00045 class PHTTPServiceThread : public PThread
    00046 {
    00047   PCLASSINFO(PHTTPServiceThread, PThread)
    00048   public:
    00049     PHTTPServiceThread(PINDEX stackSize,
    00050                        PHTTPServiceProcess & app);
    00051     ~PHTTPServiceThread();
    00052
    00053     void Main();
    00054     void Close();
    00055
    00056   protected:
    00057     PINDEX                myStackSize;
    00058     PHTTPServiceProcess & process;
    00059     PTCPSocket          * socket;
    00060 };
    00061
    00062
    00064
    00065 class PHTTPServiceProcess : public PServiceProcess
    00066 {
    00067   PCLASSINFO(PHTTPServiceProcess, PServiceProcess)
    00068
    00069   public:
    00070     enum {
    00071       MaxSecuredKeys = 10
    00072     };
    00073     struct Info {
    00074       const char * productName;
    00075       const char * manufacturerName;
    00076
    00077       WORD majorVersion;
    00078       WORD minorVersion;
    00079       CodeStatus buildStatus;
    00080       WORD buildNumber;
    00081       const char * compilationDate;
    00082
    00083       PTEACypher::Key productKey;
    00084       const char * securedKeys[MaxSecuredKeys];
    00085       PINDEX securedKeyCount;
    00086
    00087       PTEACypher::Key signatureKey;
    00088
    00089       const char * manufHomePage;
    00090       const char * email;
    00091       const char * productHTML;
    00092
    00093       const char * gifHTML;
    00094
    00095       const char * gifFilename;
    00096       int gifWidth;
    00097       int gifHeight;
    00098
    00099       const char * copyrightHolder;
    00100       const char * copyrightHomePage;
    00101       const char * copyrightEmail;
    00102     };
    00103
    00104     PHTTPServiceProcess(const Info & inf);
    00105     ~PHTTPServiceProcess();
    00106
    00107     PBoolean OnStart();
    00108     void OnStop();
    00109     PBoolean OnPause();
    00110     void OnContinue();
    00111     const char * GetServiceDependencies() const;
    00112
    00113     virtual void OnConfigChanged() = 0;
    00114     virtual PBoolean Initialise(const char * initMsg) = 0;
    00115
    00116     PBoolean ListenForHTTP(
    00117       WORD port,
    00118       PSocket::Reusability reuse = PSocket::CanReuseAddress,
    00119       PINDEX stackSize = 0x4000
    00120     );
    00121     PBoolean ListenForHTTP(
    00122       PSocket * listener,
    00123       PSocket::Reusability reuse = PSocket::CanReuseAddress,
    00124       PINDEX stackSize = 0x4000
    00125     );
    00126
    00127     virtual PString GetPageGraphic();
    00128     void GetPageHeader(PHTML &);
    00129     void GetPageHeader(PHTML &, const PString & title);
    00130
    00131     virtual PString GetCopyrightText();
    00132
    00133     const PString & GetMacroKeyword() const { return macroKeyword; }
    00134     const PTime & GetCompilationDate() const { return compilationDate; }
    00135     const PString & GetHomePage() const { return manufacturersHomePage; }
    00136     const PString & GetEMailAddress() const { return manufacturersEmail; }
    00137     const PString & GetProductName() const { return productNameHTML; }
    00138     const PTEACypher::Key & GetProductKey() const { return productKey; }
    00139     const PStringArray & GetSecuredKeys() const { return securedKeys; }
    00140     const PTEACypher::Key & GetSignatureKey() const { return signatureKey; }
    00141     PBoolean ShouldIgnoreSignatures() const { return ignoreSignatures; }
    00142     void SetIgnoreSignatures(PBoolean ig) { ignoreSignatures = ig; }
    00143
    00144     static PHTTPServiceProcess & Current();
    00145
    00146     virtual void AddRegisteredText(PHTML & html);
    00147     virtual void AddUnregisteredText(PHTML & html);
    00148     virtual PBoolean SubstituteEquivalSequence(PHTTPRequest & request, const PString &, PString &);
    00149     virtual PHTTPServer * CreateHTTPServer(PTCPSocket & socket);
    00150     virtual PHTTPServer * OnCreateHTTPServer(const PHTTPSpace & urlSpace);
    00151     PTCPSocket * AcceptHTTP();
    00152     PBoolean ProcessHTTP(PTCPSocket & socket);
    00153
    00154   protected:
    00155     PSocket  * httpListeningSocket;
    00156     PHTTPSpace httpNameSpace;
    00157     PString    macroKeyword;
    00158
    00159     PTEACypher::Key productKey;
    00160     PStringArray    securedKeys;
    00161     PTEACypher::Key signatureKey;
    00162     PBoolean            ignoreSignatures;
    00163
    00164     PTime      compilationDate;
    00165     PString    manufacturersHomePage;
    00166     PString    manufacturersEmail;
    00167     PString    productNameHTML;
    00168     PString    gifHTML;
    00169     PString    copyrightHolder;
    00170     PString    copyrightHomePage;
    00171     PString    copyrightEmail;
    00172
    00173     void ShutdownListener();
    00174     void BeginRestartSystem();
    00175     void CompleteRestartSystem();
    00176
    00177     PThread *  restartThread;
    00178
    00179     PLIST(ThreadList, PHTTPServiceThread);
    00180     ThreadList httpThreads;
    00181     PMutex     httpThreadsMutex;
    00182
    00183   friend class PConfigPage;
    00184   friend class PConfigSectionsPage;
    00185   friend class PHTTPServiceThread;
    00186 };
    00187
    00188
    00190
    00191 class PConfigPage : public PHTTPConfig
    00192 {
    00193   PCLASSINFO(PConfigPage, PHTTPConfig)
    00194   public:
    00195     PConfigPage(
    00196       PHTTPServiceProcess & app,
    00197       const PString & section,
    00198       const PHTTPAuthority & auth
    00199     );
    00200     PConfigPage(
    00201       PHTTPServiceProcess & app,
    00202       const PString & title,
    00203       const PString & section,
    00204       const PHTTPAuthority & auth
    00205     );
    00206
    00207     void OnLoadedText(PHTTPRequest &, PString & text);
    00208
    00209     PBoolean OnPOST(
    00210       PHTTPServer & server,
    00211       const PURL & url,
    00212       const PMIMEInfo & info,
    00213       const PStringToString & data,
    00214       const PHTTPConnectionInfo & connectInfo
    00215     );
    00216
    00217     virtual PBoolean Post(
    00218       PHTTPRequest & request,
    00219       const PStringToString & data,
    00220       PHTML & replyMessage
    00221     );
    00222
    00223   protected:
    00224     virtual PBoolean GetExpirationDate(
    00225       PTime & when
    00226     );
    00227
    00228     PHTTPServiceProcess & process;
    00229 };
    00230
    00231
    00233
    00234 class PConfigSectionsPage : public PHTTPConfigSectionList
    00235 {
    00236   PCLASSINFO(PConfigSectionsPage, PHTTPConfigSectionList)
    00237   public:
    00238     PConfigSectionsPage(
    00239       PHTTPServiceProcess & app,
    00240       const PURL & url,
    00241       const PHTTPAuthority & auth,
    00242       const PString & prefix,
    00243       const PString & valueName,
    00244       const PURL & editSection,
    00245       const PURL & newSection,
    00246       const PString & newTitle,
    00247       PHTML & heading
    00248     );
    00249
    00250     void OnLoadedText(PHTTPRequest &, PString & text);
    00251
    00252     PBoolean OnPOST(
    00253       PHTTPServer & server,
    00254       const PURL & url,
    00255       const PMIMEInfo & info,
    00256       const PStringToString & data,
    00257       const PHTTPConnectionInfo & connectInfo
    00258     );
    00259
    00260     virtual PBoolean Post(
    00261       PHTTPRequest & request,
    00262       const PStringToString & data,
    00263       PHTML & replyMessage
    00264     );
    00265
    00266   protected:
    00267     virtual PBoolean GetExpirationDate(
    00268       PTime & when
    00269     );
    00270
    00271     PHTTPServiceProcess & process;
    00272 };
    00273
    00274
    00276
    00277 class PRegisterPage : public PConfigPage
    00278 {
    00279   PCLASSINFO(PRegisterPage, PConfigPage)
    00280   public:
    00281     PRegisterPage(
    00282       PHTTPServiceProcess & app,
    00283       const PHTTPAuthority & auth
    00284     );
    00285
    00286     PString LoadText(
    00287       PHTTPRequest & request
    00288     );
    00289     void OnLoadedText(PHTTPRequest & request, PString & text);
    00290
    00291     virtual PBoolean Post(
    00292       PHTTPRequest & request,
    00293       const PStringToString & data,
    00294       PHTML & replyMessage
    00295     );
    00296
    00297     virtual void AddFields(
    00298       const PString & prefix
    00299     ) = 0;
    00300
    00301   protected:
    00302     PHTTPServiceProcess & process;
    00303 };
    00304
    00305
    00307
    00308 class PServiceHTML : public PHTML
    00309 {
    00310   PCLASSINFO(PServiceHTML, PHTML)
    00311   public:
    00312     PServiceHTML(const char * title,
    00313                  const char * help = NULL,
    00314                  const char * helpGif = "help.gif");
    00315
    00316     PString ExtractSignature(PString & out);
    00317     static PString ExtractSignature(const PString & html,
    00318                                     PString & out,
    00319                                     const char * keyword = "#equival");
    00320
    00321     PString CalculateSignature();
    00322     static PString CalculateSignature(const PString & out);
    00323     static PString CalculateSignature(const PString & out, const PTEACypher::Key & sig);
    00324
    00325     PBoolean CheckSignature();
    00326     static PBoolean CheckSignature(const PString & html);
    00327
    00328     enum MacroOptions {
    00329       NoOptions           = 0,
    00330       NeedSignature       = 1,
    00331       LoadFromFile        = 2,
    00332       NoURLOverride       = 4,
    00333       NoSignatureForFile  = 8
    00334     };
    00335     static bool ProcessMacros(
    00336       PHTTPRequest & request,
    00337       PString & text,
    00338       const PString & filename,
    00339       unsigned options
    00340     );
    00341     static bool SpliceMacro(
    00342       PString & text,
    00343       const PString & tokens,
    00344       const PString & value
    00345     );
    00346 };
    00347
    00348
    00350
    00351 class PServiceMacro : public PObject
    00352 {
    00353   public:
    00354     PServiceMacro(const char * name, PBoolean isBlock);
    00355     PServiceMacro(const PCaselessString & name, PBoolean isBlock);
    00356     Comparison Compare(const PObject & obj) const;
    00357     virtual PString Translate(
    00358       PHTTPRequest & request,
    00359       const PString & args,
    00360       const PString & block
    00361     ) const;
    00362   protected:
    00363     const char * macroName;
    00364     PBoolean isMacroBlock;
    00365     PServiceMacro * link;
    00366     static PServiceMacro * list;
    00367   friend class PServiceMacros_list;
    00368 };
    00369
    00370
    00371 #define P_EMPTY
    00372
    00373 #define PCREATE_SERVICE_MACRO(name, request, args) \
    00374   class PServiceMacro_##name : public PServiceMacro { \
    00375     public: \
    00376       PServiceMacro_##name() : PServiceMacro(#name, false) { } \
    00377       PString Translate(PHTTPRequest &, const PString &, const PString &) const; \
    00378   }; \
    00379   static const PServiceMacro_##name serviceMacro_##name; \
    00380   PString PServiceMacro_##name::Translate(PHTTPRequest & request, const PString & args, const PString &) const
    00381
    00382
    00383
    00384 #define PCREATE_SERVICE_MACRO_BLOCK(name, request, args, block) \
    00385   class PServiceMacro_##name : public PServiceMacro { \
    00386     public: \
    00387       PServiceMacro_##name() : PServiceMacro(#name, true) { } \
    00388       PString Translate(PHTTPRequest &, const PString &, const PString &) const; \
    00389   }; \
    00390   static const PServiceMacro_##name serviceMacro_##name; \
    00391   PString PServiceMacro_##name::Translate(PHTTPRequest & request, const PString & args, const PString & block) const
    00392
    00393
    00394
    00396
    00397 class PServiceHTTPString : public PHTTPString
    00398 {
    00399   PCLASSINFO(PServiceHTTPString, PHTTPString)
    00400   public:
    00401     PServiceHTTPString(const PURL & url, const PString & string)
    00402       : PHTTPString(url, string) { }
    00403
    00404     PServiceHTTPString(const PURL & url, const PHTTPAuthority & auth)
    00405       : PHTTPString(url, auth) { }
    00406
    00407     PServiceHTTPString(const PURL & url, const PString & string, const PHTTPAuthority & auth)
    00408       : PHTTPString(url, string, auth) { }
    00409
    00410     PServiceHTTPString(const PURL & url, const PString & string, const PString & contentType)
    00411       : PHTTPString(url, string, contentType) { }
    00412
    00413     PServiceHTTPString(const PURL & url, const PString & string, const PString & contentType, const PHTTPAuthority & auth)
    00414       : PHTTPString(url, string, contentType, auth) { }
    00415
    00416     PString LoadText(PHTTPRequest &);
    00417
    00418   protected:
    00419     virtual PBoolean GetExpirationDate(
    00420       PTime & when
    00421     );
    00422 };
    00423
    00424
    00425 class PServiceHTTPFile : public PHTTPFile
    00426 {
    00427   PCLASSINFO(PServiceHTTPFile, PHTTPFile)
    00428   public:
    00429     PServiceHTTPFile(const PString & filename, PBoolean needSig = false)
    00430       : PHTTPFile(filename) { needSignature = needSig; }
    00431     PServiceHTTPFile(const PString & filename, const PFilePath & file, PBoolean needSig = false)
    00432       : PHTTPFile(filename, file) { needSignature = needSig; }
    00433     PServiceHTTPFile(const PString & filename, const PString & file, PBoolean needSig = false)
    00434       : PHTTPFile(filename, file) { needSignature = needSig; }
    00435     PServiceHTTPFile(const PString & filename, const PHTTPAuthority & auth, PBoolean needSig = false)
    00436       : PHTTPFile(filename, auth) { needSignature = needSig; }
    00437     PServiceHTTPFile(const PString & filename, const PFilePath & file, const PHTTPAuthority & auth, PBoolean needSig = false)
    00438       : PHTTPFile(filename, file, auth) { needSignature = needSig; }
    00439
    00440     void OnLoadedText(PHTTPRequest &, PString & text);
    00441
    00442   protected:
    00443     virtual PBoolean GetExpirationDate(
    00444       PTime & when
    00445     );
    00446
    00447     PBoolean needSignature;
    00448 };
    00449
    00450 class PServiceHTTPDirectory : public PHTTPDirectory
    00451 {
    00452   PCLASSINFO(PServiceHTTPDirectory, PHTTPDirectory)
    00453   public:
    00454     PServiceHTTPDirectory(const PURL & url, const PDirectory & dirname, PBoolean needSig = false)
    00455       : PHTTPDirectory(url, dirname) { needSignature = needSig; }
    00456
    00457     PServiceHTTPDirectory(const PURL & url, const PDirectory & dirname, const PHTTPAuthority & auth, PBoolean needSig = false)
    00458       : PHTTPDirectory(url, dirname, auth) { needSignature = needSig; }
    00459
    00460     void OnLoadedText(PHTTPRequest &, PString & text);
    00461
    00462   protected:
    00463     virtual PBoolean GetExpirationDate(
    00464       PTime & when
    00465     );
    00466
    00467     PBoolean needSignature;
    00468 };
    00469
    00470
    00471 #endif // PTLIB_HTTPSVC_H
    00472
    00473
    00474 // End Of File ///////////////////////////////////////////////////////////////