⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 httpsvc.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 5 页
字号:
PHTTPServiceProcess::~PHTTPServiceProcess()
{
  ShutdownListener();
}


PHTTPServiceProcess & PHTTPServiceProcess::Current() 
{
  PHTTPServiceProcess & process = (PHTTPServiceProcess &)PProcess::Current();
  PAssert(PIsDescendant(&process, PHTTPServiceProcess), "Not a HTTP service!");
  return process;
}


BOOL PHTTPServiceProcess::OnStart()
{
  if (!Initialise("Started"))
    return FALSE;

  OnConfigChanged();
  return TRUE;
}


void PHTTPServiceProcess::OnStop()
{
  ShutdownListener();
  PSYSTEMLOG(Warning, GetName() << " stopped.");
  PServiceProcess::OnStop();
}


BOOL PHTTPServiceProcess::OnPause()
{
  OnConfigChanged();
  return TRUE;
}


void PHTTPServiceProcess::OnContinue()
{
  if (Initialise("Restarted"))
    return;

  OnStop();
  Terminate();
}


#ifdef _WIN32
const char * PHTTPServiceProcess::GetServiceDependencies() const
{
  return "EventLog\0Tcpip\0";
}
#endif


BOOL PHTTPServiceProcess::ListenForHTTP(WORD port,
                                        PSocket::Reusability reuse,
                                        PINDEX stackSize)
{
  if (httpListeningSocket != NULL &&
      httpListeningSocket->GetPort() == port &&
      httpListeningSocket->IsOpen())
    return TRUE;

  return ListenForHTTP(new PTCPSocket(port), reuse, stackSize);
}


BOOL PHTTPServiceProcess::ListenForHTTP(PSocket * listener,
                                        PSocket::Reusability reuse,
                                        PINDEX stackSize)
{
  if (httpListeningSocket != NULL)
    ShutdownListener();

  httpListeningSocket = PAssertNULL(listener);
  if (!httpListeningSocket->Listen(5, 0, reuse)) {
    PSYSTEMLOG(Debug, "HTTPSVC\tListen on port " << httpListeningSocket->GetPort()
                   << " failed: " << httpListeningSocket->GetErrorText());
    return FALSE;
  }

  if (stackSize > 1000)
    new PHTTPServiceThread(stackSize, *this);

  return TRUE;
}


void PHTTPServiceProcess::ShutdownListener()
{
  if (httpListeningSocket == NULL)
    return;

  if (!httpListeningSocket->IsOpen())
    return;

  PSYSTEMLOG(Debug, "HTTPSVC\tClosing listener socket on port "
                 << httpListeningSocket->GetPort());

  httpListeningSocket->Close();

  httpThreadsMutex.Wait();
  for (PINDEX i = 0; i < httpThreads.GetSize(); i++)
    httpThreads[i].Close();

  while (httpThreads.GetSize() > 0) {
    httpThreadsMutex.Signal();
    Sleep(1);
    httpThreadsMutex.Wait();
  }

  httpThreadsMutex.Signal();

  delete httpListeningSocket;
  httpListeningSocket = NULL;
}


PString PHTTPServiceProcess::GetCopyrightText()
{
  PHTML html(PHTML::InBody);
  html << "Copyright &copy;"
       << compilationDate.AsString("yyyy") << " by "
       << PHTML::HotLink(copyrightHomePage)
       << copyrightHolder
       << PHTML::HotLink()
       << ", "
       << PHTML::HotLink("mailto:" + copyrightEmail)
       << copyrightEmail
       << PHTML::HotLink();
  return html;
}


PString PHTTPServiceProcess::GetPageGraphic()
{
  PFile header;
  if (header.Open("header.html", PFile::ReadOnly))
    return header.ReadString(header.GetLength());

  PHTML html(PHTML::InBody);
  html << PHTML::TableStart()
       << PHTML::TableRow()
       << PHTML::TableData();

  if (gifHTML.IsEmpty())
    html << PHTML::Heading(1) << productNameHTML << "&nbsp;" << PHTML::Heading(1);
  else
    html << gifHTML;

  html << PHTML::TableData()
       << PHTML::Bold() << GetName() << PHTML::Bold() << PHTML::BreakLine()
       << GetOSClass() << ' ' << GetOSName()
       << " Version " << GetVersion(TRUE) << PHTML::BreakLine()
       << ' ' << GetCompilationDate().AsString("d MMMM yyyy")
       << PHTML::BreakLine()
       << "By "
       << PHTML::HotLink(manufacturersHomePage) << GetManufacturer() << PHTML::HotLink()
       << ", "
       << PHTML::HotLink("mailto:" + manufacturersEmail) << manufacturersEmail << PHTML::HotLink()
       << PHTML::TableEnd()
       << PHTML::HRule();

  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();
}


PTCPSocket * PHTTPServiceProcess::AcceptHTTP()
{
  if (httpListeningSocket == NULL)
    return NULL;

  if (!httpListeningSocket->IsOpen())
    return NULL;

  // get a socket when a client connects
  PTCPSocket * socket = new PTCPSocket;
  if (socket->Accept(*httpListeningSocket))
    return socket;

  if (socket->GetErrorCode() != PChannel::Interrupted)
    PSYSTEMLOG(Error, "Accept failed for HTTP: " << socket->GetErrorText());

  if (httpListeningSocket != NULL && httpListeningSocket->IsOpen())
    return socket;

  delete socket;
  return NULL;
}


BOOL PHTTPServiceProcess::ProcessHTTP(PTCPSocket & socket)
{
  if (!socket.IsOpen())
    return TRUE;

  PHTTPServer * server = CreateHTTPServer(socket);
  if (server == NULL) {
    PSYSTEMLOG(Error, "HTTP server creation/open failed.");
    return TRUE;
  }

  // process requests
  while (server->ProcessCommand())
    ;

  // always close after the response has been sent
  delete server;

  // if a restart was requested, then do it, but only if we are not shutting down
  if (httpListeningSocket->IsOpen())
    CompleteRestartSystem();

  return TRUE;
}


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;
}


PHTTPServer * PHTTPServiceProcess::CreateHTTPServer(PTCPSocket & socket)
{
#ifdef SO_LINGER
  const linger ling = { 1, 5 };
  socket.SetOption(SO_LINGER, &ling, sizeof(ling));
#endif

  PHTTPServer * server = OnCreateHTTPServer(httpNameSpace);

  if (server->Open(socket))
    return server;

  delete server;
  return NULL;
}


PHTTPServer * PHTTPServiceProcess::OnCreateHTTPServer(const PHTTPSpace & httpNameSpace)
{
  return new PHTTPServer(httpNameSpace);
}


//////////////////////////////////////////////////////////////

PHTTPServiceThread::PHTTPServiceThread(PINDEX stackSize,
                                       PHTTPServiceProcess & app)
  : PThread(stackSize, AutoDeleteThread, NormalPriority, "HTTP Service:%x"),
    process(app)
{
  process.httpThreadsMutex.Wait();
  process.httpThreads.Append(this);
  process.httpThreadsMutex.Signal();

  myStackSize = stackSize;
  socket = NULL;
  Resume();
}


PHTTPServiceThread::~PHTTPServiceThread()
{
  process.httpThreadsMutex.Wait();
  process.httpThreads.Remove(this);
  process.httpThreadsMutex.Signal();
  delete socket;
}


void PHTTPServiceThread::Close()
{
  if (socket != NULL)
    socket->Close();
}


void PHTTPServiceThread::Main()
{
  PTCPSocket * socket = process.AcceptHTTP();
  if (socket != NULL) {
    new PHTTPServiceThread(myStackSize, process);
    process.ProcessHTTP(*socket);
  }
}


//////////////////////////////////////////////////////////////

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,
                              GetURL().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)
{
  PSYSTEMLOG(Debug3, "Post to " << request.url << '\n' << data);
  BOOL retval = PHTTPConfig::Post(request, data, reply);

  if (request.code == PHTTP::RequestOK)
    process.BeginRestartSystem();

  PServiceHTML::ProcessMacros(request, reply,
                              GetURL().AsString(PURL::PathOnly).Mid(1),
                              PServiceHTML::LoadFromFile);
  OnLoadedText(request, reply);

  return retval;
}


BOOL PConfigPage::GetExpirationDate(PTime & when)
{
  // Well and truly before now....
  when = ImmediateExpiryTime;
  return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -