📄 httpsvc.cxx
字号:
/* * httpsvc.cxx * * Classes for service applications using HTTP as the user interface. * * Portable Windows Library * * Copyright (c) 1993-1998 Equivalence Pty. Ltd. * * The contents of this file are subject to the Mozilla Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See * the License for the specific language governing rights and limitations * under the License. * * The Original Code is Portable Windows Library. * * The Initial Developer of the Original Code is Equivalence Pty. Ltd. * * Portions are Copyright (C) 1993 Free Software Foundation, Inc. * All Rights Reserved. * * Contributor(s): ______________________________________. * * $Log: httpsvc.cxx,v $ * Revision 1.54 2000/05/02 02:58:49 robertj * Fixed MSVC warning about unused parameters. * * Revision 1.53 2000/05/02 02:01:18 craigs * Changed stricmp and added implementation of PServiceMacro::Translate * * Revision 1.52 2000/05/02 01:50:37 robertj * Rewrite of PServiceMacro so does not use malloc (indirectly). * * Revision 1.51 2000/01/27 00:35:52 robertj * Fixed benign warning about uninitialised variables in MSVC optimised compile. * * Revision 1.50 1999/08/07 06:50:52 robertj * Removed silly (and incorrect) warning. * * Revision 1.49 1999/04/24 05:16:26 robertj * Fixed incorrect date in copyright notice. * * Revision 1.48 1998/11/30 05:37:46 robertj * New directory structure * * Revision 1.47 1998/11/24 23:05:14 robertj * Fixed extra *** in demo message * * Revision 1.46 1998/11/16 07:23:15 robertj * More PPC GNU compatibility. * * Revision 1.45 1998/11/16 06:50:40 robertj * Fixed PPC GNU compiler compatibility. * * Revision 1.44 1998/10/31 12:49:25 robertj * Added read/write mutex to the HTTP space variable to avoid thread crashes. * * Revision 1.43 1998/10/29 11:58:52 robertj * Added ability to configure the HTTP threads stack size. * * Revision 1.42 1998/10/29 11:31:57 robertj * Fixed default URL to have lower case and spaceless product name. * Increased HTTP stack size. * * Revision 1.41 1998/10/15 01:53:35 robertj * GNU compatibility. * * Revision 1.40 1998/10/13 14:06:24 robertj * Complete rewrite of memory leak detection code. * * Revision 1.39 1998/09/23 06:22:15 robertj * Added open source copyright license. * * Revision 1.38 1998/09/18 01:47:23 robertj * Fixed bug that made files with signature on first line fail on unix systems. * * Revision 1.37 1998/08/20 06:01:02 robertj * Improved internationalisation, registrationpage override. * * Revision 1.36 1998/04/21 02:43:40 robertj * Fixed conditional around wrong way for requiring signature on HTML files. * * Revision 1.35 1998/04/01 01:55:41 robertj * Fixed bug for automatically including GIF file in HTTP name space. * * Revision 1.34 1998/03/23 03:21:40 robertj * Fixed missing invalid case in register page. * * Revision 1.33 1998/03/20 03:18:15 robertj * Added special classes for specific sepahores, PMutex and PSyncPoint. * * Revision 1.32 1998/03/17 10:14:39 robertj * Rewrite of registration page to allow for HTML file override. * * Revision 1.31 1998/03/09 07:17:48 robertj * Added IP peer/local number macros. * Set GetPageGraphic reference to GIF file to be at lop level directory. * * Revision 1.30 1998/02/16 00:14:09 robertj * Added ProductName and BuildDate macros. * Major rewrite of application info passed in PHTTPServiceProcess constructor. * * Revision 1.29 1998/02/03 06:22:45 robertj * Allowed PHTTPServiceString to be overridden by html file after ';'. * * Revision 1.28 1998/01/26 02:49:19 robertj * GNU support. * * Revision 1.27 1998/01/26 02:12:14 robertj * GNU warnings. * * Revision 1.26 1998/01/26 00:45:44 robertj * Added option flags to ProcessMacros to automatically load from file etc. * Assured that all service HTTP resources are overidable with file, using ; URL field. * Added a number of extra #equival macros. * Added "Pty. Ltd." to company name. * * Revision 1.25 1997/11/10 12:40:05 robertj * Changed SustituteEquivalSequence so can override standard macros. * * Revision 1.24 1997/11/04 06:02:46 robertj * Allowed help gif file name to overridable in PServiceHTML, so can be in subdirectory. * * Revision 1.23 1997/10/30 10:21:26 robertj * Added ability to customise regisration text by application. * * Revision 1.22 1997/08/28 14:19:40 robertj * Fixed bug where HTTP directory was not processed for macros. * * Revision 1.20 1997/08/20 08:59:58 craigs * Changed macro handling to commonise #equival sequence * * Revision 1.19 1997/07/26 11:38:22 robertj * Support for overridable pages in HTTP service applications. * * Revision 1.18 1997/07/08 13:11:44 robertj * Added standard header and copyright macros to service HTML. * * Revision 1.17 1997/06/16 13:20:15 robertj * Fixed bug where PHTTPThread crashes on exit. * * Revision 1.16 1997/05/16 12:07:21 robertj * Added operating system and version to hidden fields on registration form. * * Revision 1.15 1997/03/02 03:40:59 robertj * Added error logging to standard HTTP Service HTTP Server. * * Revision 1.14 1997/02/05 11:54:54 robertj * Added support for order form page overridiing. * * Revision 1.13 1997/01/28 11:45:19 robertj * . * * Revision 1.13 1997/01/27 10:22:37 robertj * Numerous changes to support OEM versions of products. * * Revision 1.12 1997/01/03 06:33:23 robertj * Removed slash from operating system version string, so says Windows NT rather than Windows/NT * * Revision 1.11 1996/11/16 10:50:26 robertj * ?? * * Revision 1.10 1996/11/04 03:58:23 robertj * Changed to accept separate copyright and manufacturer strings. * * Revision 1.8 1996/10/08 13:08:29 robertj * Changed standard graphic to use PHTML class. * * Revision 1.7 1996/09/14 13:09:33 robertj * Major upgrade: * rearranged sockets to help support IPX. * added indirect channel class and moved all protocols to descend from it, * separating the protocol from the low level byte transport. * * Revision 1.6 1996/08/25 09:39:00 robertj * Prevented registration if no user etc entered. * * Revision 1.5 1996/08/19 13:39:55 robertj * Fixed race condition in system restart logic. * * Revision 1.4 1996/08/08 13:36:39 robertj * Fixed Registation page so no longer has static link, ie can be DLLed. * * Revision 1.3 1996/07/15 10:36:48 robertj * Added registration info to bottom of order form so can be faxed to us. * * Revision 1.2 1996/06/28 13:21:30 robertj * Fixed nesting problem in tables. * Fixed PConfig page always restarting. * * Revision 1.1 1996/06/13 13:33:34 robertj * Initial revision * */#ifdef __GNUC__#pragma implementation "httpsvc.h"#endif#include <ptlib.h>#include <ptclib/httpsvc.h>#include <ptlib/sockets.h>#define new PNEW#define HOME_PAGE "http://www.equival.com"#define EMAIL "equival@equival.com.au"#define EQUIVALENCE "Equivalence Pty. Ltd."PHTTPServiceProcess::PHTTPServiceProcess(const Info & inf) : PServiceProcess(inf.manufacturerName, inf.productName, inf.majorVersion, inf.minorVersion, inf.buildStatus, inf.buildNumber), productKey(inf.productKey), securedKeys(inf.securedKeyCount, inf.securedKeys), signatureKey(inf.signatureKey), compilationDate(inf.compilationDate), manufacturersHomePage(inf.manufHomePage != NULL ? inf.manufHomePage : HOME_PAGE), manufacturersEmail(inf.email != NULL ? inf.email : EMAIL), productNameHTML(inf.productHTML != NULL ? inf.productHTML : inf.productName){ if (inf.gifHTML != NULL) gifHTML = inf.gifHTML; else { gifHTML = psprintf("<img src=\"/%s\" alt=\"%s!\"", inf.gifFilename, inf.productName); if (inf.gifWidth != 0 && inf.gifHeight != 0) gifHTML += psprintf(" width=%i height=%i", inf.gifWidth, inf.gifHeight); gifHTML += " align=absmiddle>"; } if (inf.gifFilename != NULL) httpNameSpace.AddResource(new PServiceHTTPFile(inf.gifFilename, GetFile().GetDirectory()+inf.gifFilename)); restartThread = NULL; httpListeningSocket = NULL;}PHTTPServiceProcess::~PHTTPServiceProcess(){ ShutdownListener();}PHTTPServiceProcess & PHTTPServiceProcess::Current() { PHTTPServiceProcess & process = (PHTTPServiceProcess &)PProcess::Current(); PAssert(process.IsDescendant(PHTTPServiceProcess::Class()), "Not a HTTP service!"); return process;}BOOL PHTTPServiceProcess::ListenForHTTP(WORD port, PINDEX stackSize){ if (httpListeningSocket != NULL && httpListeningSocket->GetPort() == port && httpListeningSocket->IsOpen()) return TRUE; return ListenForHTTP(new PTCPSocket(port), stackSize);}BOOL PHTTPServiceProcess::ListenForHTTP(PSocket * listener, PINDEX stackSize){ if (httpListeningSocket != NULL) ShutdownListener(); httpListeningSocket = PAssertNULL(listener); if (!httpListeningSocket->Listen()) return FALSE; if (stackSize > 1000) new PHTTPServiceThread(stackSize, *this, *httpListeningSocket, httpNameSpace); return TRUE;}void PHTTPServiceProcess::ShutdownListener(){ if (httpListeningSocket == NULL) return; if (!httpListeningSocket->IsOpen()) return; httpListeningSocket->Close(); httpThreadClosed.Wait(); delete httpListeningSocket; httpListeningSocket = NULL;}PString PHTTPServiceProcess::GetCopyrightText(){ PHTML html(PHTML::InBody); html << "Copyright ©" << compilationDate.AsString("yyyy") << " by " << PHTML::HotLink(HOME_PAGE) << EQUIVALENCE << PHTML::HotLink() << ", " << PHTML::HotLink("mailto:" EMAIL) << EMAIL << PHTML::HotLink(); return html;}PString PHTTPServiceProcess::GetPageGraphic(){ PHTML html(PHTML::InBody); html << PHTML::TableStart() << PHTML::TableRow() << PHTML::TableData() << gifHTML << PHTML::TableData() << GetOSClass() << ' ' << GetOSName() << " Version " << GetVersion(TRUE) << PHTML::BreakLine() << "By " << PHTML::HotLink(manufacturersHomePage) << GetManufacturer() << PHTML::HotLink() << ", " << PHTML::HotLink("mailto:" + manufacturersEmail) << manufacturersEmail << PHTML::HotLink() << PHTML::TableEnd(); return html;}void PHTTPServiceProcess::GetPageHeader(PHTML & html){ GetPageHeader(html, GetName());}void PHTTPServiceProcess::GetPageHeader(PHTML & html, const PString & title){ html << PHTML::Title(title) << PHTML::Body() << GetPageGraphic();}void PHTTPServiceProcess::BeginRestartSystem(){ if (restartThread == NULL) { restartThread = PThread::Current(); OnConfigChanged(); }}void PHTTPServiceProcess::CompleteRestartSystem(){ if (restartThread == NULL) return; if (restartThread != PThread::Current()) return; httpNameSpace.StartWrite(); if (Initialise("Restart\tInitialisation")) restartThread = NULL; httpNameSpace.EndWrite(); if (restartThread != NULL) Terminate();}void PHTTPServiceProcess::AddRegisteredText(PHTML &){}void PHTTPServiceProcess::AddUnregisteredText(PHTML &){}BOOL PHTTPServiceProcess::SubstituteEquivalSequence(PHTTPRequest &, const PString &, PString &){ return FALSE;}//////////////////////////////////////////////////////////////PHTTPServiceThread::PHTTPServiceThread(PINDEX stackSize, PHTTPServiceProcess & app, PSocket & listeningSocket, PHTTPSpace & http) : PThread(stackSize, AutoDeleteThread), process(app), listener(listeningSocket), httpNameSpace(http){ myStackSize = stackSize; Resume();}void PHTTPServiceThread::Main(){ if (!listener.IsOpen()) { process.httpThreadClosed.Signal(); return; } // get a socket when a client connects PHTTPServer server(httpNameSpace); if (!server.Accept(listener)) { if (server.GetErrorCode() != PChannel::Interrupted) PSYSTEMLOG(Error, "Accept failed for HTTP: " << server.GetErrorText()); if (listener.IsOpen()) new PHTTPServiceThread(myStackSize, process, listener, httpNameSpace); else process.httpThreadClosed.Signal(); return; } new PHTTPServiceThread(myStackSize, process, listener, httpNameSpace); // process requests while (server.ProcessCommand()) ; // always close after the response has been sent server.Close(); // if a restart was requested, then do it process.CompleteRestartSystem();}//////////////////////////////////////////////////////////////PConfigPage::PConfigPage(PHTTPServiceProcess & app, const PString & title, const PString & section, const PHTTPAuthority & auth) : PHTTPConfig(title, section, auth), process(app){}PConfigPage::PConfigPage(PHTTPServiceProcess & app, const PString & section, const PHTTPAuthority & auth) : PHTTPConfig(section.ToLower() + ".html", section, auth), process(app){}void PConfigPage::OnLoadedText(PHTTPRequest & request, PString & text){ PServiceHTML::ProcessMacros(request, text, baseURL.AsString(PURL::PathOnly).Mid(1), PServiceHTML::LoadFromFile); PHTTPConfig::OnLoadedText(request, text); PServiceHTML::ProcessMacros(request, text, "", PServiceHTML::NoOptions);}BOOL PConfigPage::OnPOST(PHTTPServer & server, const PURL & url, const PMIMEInfo & info, const PStringToString & data, const PHTTPConnectionInfo & connectInfo){ PHTTPConfig::OnPOST(server, url, info, data, connectInfo); return FALSE; // Make sure we break any persistent connections}BOOL PConfigPage::Post(PHTTPRequest & request, const PStringToString & data, PHTML & reply){ PServiceHTML::ProcessMacros(request, reply, baseURL.AsString(PURL::PathOnly).Mid(1), PServiceHTML::LoadFromFile); PSYSTEMLOG(Debug3, "Post to " << request.url << '\n' << data); BOOL retval = PHTTPConfig::Post(request, data, reply); OnLoadedText(request, reply); if (request.code == PHTTP::OK) process.BeginRestartSystem(); return retval;}BOOL PConfigPage::GetExpirationDate(PTime & when){ // Well and truly before now.... when = PTime(0, 0, 0, 1, 1, 1980); return TRUE;}//////////////////////////////////////////////////////////////PConfigSectionsPage::PConfigSectionsPage(PHTTPServiceProcess & app,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -