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

📄 httpsrvr.cxx

📁 mgcp协议源代码。支持多种编码:g711
💻 CXX
📖 第 1 页 / 共 3 页
字号:
/* * httpsrvr.cxx * * HTTP server classes. * * 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: httpsrvr.cxx,v $ * Revision 1.32  2000/05/02 07:55:22  craigs * Changed static PString to static const char * to avoid "memory leak" * * Revision 1.31  1999/05/13 04:04:04  robertj * Fixed problem of initialised commandName in ConnectionInfo. * * Revision 1.30  1999/05/12 01:40:47  robertj * Fixed "unknown" response codes being passed on when used with an "unknown" command. * * Revision 1.29  1999/05/11 12:23:22  robertj * Fixed search for persistent connection to accept kee-alive on multile MIME fields. * * Revision 1.28  1999/05/04 15:26:01  robertj * Improved HTTP/1.1 compatibility (pass through user commands). * Fixed problems with quicktime installer. * * Revision 1.27  1999/04/24 11:50:11  robertj * Changed HTTP command parser so will work if some idiot puts spaces in a URL. * * Revision 1.26  1999/04/21 01:58:08  robertj * Fixed problem with reading data for request using second form of PHTTPRequestInfo constructor. * * Revision 1.25  1998/11/30 04:51:59  robertj * New directory structure * * Revision 1.24  1998/11/14 01:11:38  robertj * PPC linux GNU compatibility. * * Revision 1.23  1998/10/31 12:49:23  robertj * Added read/write mutex to the HTTP space variable to avoid thread crashes. * * Revision 1.22  1998/10/25 01:02:41  craigs * Added ability to specify per-directory authorisation for PHTTPDirectory * * Revision 1.21  1998/10/13 14:06:23  robertj * Complete rewrite of memory leak detection code. * * Revision 1.20  1998/09/23 06:22:13  robertj * Added open source copyright license. * * Revision 1.19  1998/08/06 00:54:22  robertj * Fixed bug in sending empty files, caused endless wait in Netscape. * * Revision 1.18  1998/06/16 03:32:14  robertj * Propagated persistence and proxy flags in new connection info instances. * * Revision 1.17  1998/04/01 01:55:16  robertj * Fixed bug when serving HTTPFile that has zero bytes in it. * * Revision 1.16  1998/02/03 06:24:10  robertj * Added local address and port to PHTTPRequest. * Fixed bug in default entity length. should be read to EOF. * Fixed OnError() so can detec HTML bosy tag with parameters. * * Revision 1.14  1998/01/26 00:42:19  robertj * Added more information to PHTTPConnectionInfo. * Made SetDefaultMIMEFields in HTTP Server not set those fields if already set. * * Revision 1.13  1997/10/30 10:22:04  robertj * Added multiple user basic authorisation scheme. * * Revision 1.12  1997/10/03 13:39:25  robertj * Fixed race condition on socket close in Select() function. * * Revision 1.12  1997/10/03 13:31:12  craigs * Added ability to access client socket from within HTTP resources * * Revision 1.11  1997/08/04 10:44:36  robertj * Improved receiving of a POST on a non-persistant connection, do not wait for EOF if have CRLF. * * Revision 1.10  1997/07/14 11:47:13  robertj * Added "const" to numerous variables. * * Revision 1.9  1997/07/08 13:10:26  robertj * Fixed bug in HTTP server where standard error text is not sent to remote client. * * Revision 1.8  1997/04/15 14:32:19  robertj * Fixed case problem for HTTP version string. * * Revision 1.7  1997/03/20 13:01:32  robertj * Fixed bug in proxy POST having unexpexted reset of connection. * * Revision 1.6  1997/02/09 04:09:30  robertj * Fixed GCC warning * * Revision 1.5  1997/01/12 04:15:23  robertj * Globalised MIME tag strings. * * Revision 1.4  1996/12/12 09:24:16  robertj * Persistent proxy connection support (work in progress). * * Revision 1.3  1996/11/10 21:09:33  robertj * Removed redundent GetSocket() call. * Added flush of stream after processing request, important on persistent connections. * * Revision 1.2  1996/10/26 03:31:05  robertj * Changed OnError so can pass in full HTML page as parameter. * * Revision 1.1  1996/09/14 13:02:18  robertj * Initial revision * */#include <ptlib.h>#include <ptlib/sockets.h>#include <ptclib/http.h>#include <ctype.h>#define new PNEW// undefine to remove support for persistant connections#define HAS_PERSISTANCE// define to enable work-around for Netscape persistant connection bug// set to lifetime of suspect sockets (in seconds)#define STRANGE_NETSCAPE_BUG	3// maximum lifetime (in seconds) of persistant connections#define	MAX_LIFETIME		30// maximum lifetime (in transactions) of persistant connections#define MAX_TRANSACTIONS	10// maximum delay between characters whilst reading a line of text#define	READLINE_TIMEOUT	30//  filename to use for directory access directivesstatic const char * accessFilename = "_access";//////////////////////////////////////////////////////////////////////////////// PHTTPSpacePHTTPSpace::PHTTPSpace(){  mutex = new PReadWriteMutex;  root = new Node(PString(), NULL);}void PHTTPSpace::DestroyContents(){  delete mutex;  delete root;}void PHTTPSpace::CloneContents(const PHTTPSpace * c){  mutex = new PReadWriteMutex;  root = new Node(*c->root);}void PHTTPSpace::CopyContents(const PHTTPSpace & c){  mutex = c.mutex;  root = c.root;}PHTTPSpace::Node::Node(const PString & nam, Node * parentNode)  : PString(nam){  parent = parentNode;  resource = NULL;}PHTTPSpace::Node::~Node(){  delete resource;}BOOL PHTTPSpace::AddResource(PHTTPResource * res, AddOptions overwrite){  PAssert(res != NULL, PInvalidParameter);  const PStringArray & path = res->GetURL().GetPath();  Node * node = root;  for (PINDEX i = 0; i < path.GetSize(); i++) {    if (path[i].IsEmpty())      break;    if (node->resource != NULL)      return FALSE;   // Already a resource in tree in partial path    PINDEX pos = node->children.GetValuesIndex(path[i]);    if (pos == P_MAX_INDEX)      pos = node->children.Append(new Node(path[i], node));    node = &node->children[pos];  }  if (!node->children.IsEmpty())    return FALSE;   // Already a resource in tree further down path.  if (overwrite == ErrorOnExist && node->resource != NULL)    return FALSE;   // Already a resource in tree at leaf  delete node->resource;  node->resource = res;  return TRUE;}BOOL PHTTPSpace::DelResource(const PURL & url){  const PStringArray & path = url.GetPath();  Node * node = root;  for (PINDEX i = 0; i < path.GetSize(); i++) {    if (path[i].IsEmpty())      break;    PINDEX pos = node->children.GetValuesIndex(path[i]);    if (pos == P_MAX_INDEX)      return FALSE;    node = &node->children[pos];    if (node->resource != NULL)      return FALSE;  }  if (!node->children.IsEmpty())    return FALSE;   // Still a resource in tree further down path.  do {    Node * par = node->parent;    par->children.Remove(node);    node = par;  } while (node != NULL && node->children.IsEmpty());  return TRUE;}static const char * const HTMLIndexFiles[] = {  "Welcome.html", "welcome.html", "index.html",  "Welcome.htm",  "welcome.htm",  "index.htm"};PHTTPResource * PHTTPSpace::FindResource(const PURL & url){  const PStringArray & path = url.GetPath();  Node * node = root;  PINDEX i;  for (i = 0; i < path.GetSize(); i++) {    if (path[i].IsEmpty())      break;    PINDEX pos = node->children.GetValuesIndex(path[i]);    if (pos == P_MAX_INDEX)      return NULL;    node = &node->children[pos];    if (node->resource != NULL)      return node->resource;  }  for (i = 0; i < PARRAYSIZE(HTMLIndexFiles); i++) {    PINDEX pos = node->children.GetValuesIndex(PString(HTMLIndexFiles[i]));    if (pos != P_MAX_INDEX)      return node->children[pos].resource;  }  return NULL;}//////////////////////////////////////////////////////////////////////////////// PHTTPServerPHTTPServer::PHTTPServer(){  Construct();}PHTTPServer::PHTTPServer(const PHTTPSpace & space)  : urlSpace(space){  Construct();}void PHTTPServer::Construct(){  transactionCount = 0;  SetReadLineTimeout(PTimeInterval(0, READLINE_TIMEOUT));}BOOL PHTTPServer::ProcessCommand(){  PString args;  PINDEX cmd;  // if this is not the first command received by this socket, then set  // the read timeout appropriately.  if (transactionCount > 0)     SetReadTimeout(nextTimeout);  // this will only return false upon timeout or completely invalid command  if (!ReadCommand(cmd, args))    return FALSE;  connectInfo.commandCode = (Commands)cmd;  if (cmd < NumCommands)    connectInfo.commandName = commandNames[cmd];  else {    PINDEX spacePos = args.Find(' ');    connectInfo.commandName = args.Left(spacePos);    args = args.Mid(spacePos);  }  // if no tokens, error  if (args.IsEmpty()) {    OnError(BadRequest, args, connectInfo);    return FALSE;  }  if (!connectInfo.Initialise(*this, args))      return FALSE;  // now that we've decided we did receive a HTTP request, increment the  // count of transactions  transactionCount++;  nextTimeout.SetInterval(MAX_LIFETIME*1000);  PIPSocket * socket = GetSocket();  WORD myPort = (WORD)(socket != NULL ? socket->GetPort() : 80);  // the URL that comes with Connect requests is not quite kosher, so   // mangle it into a proper URL and do NOT close the connection.  // for all other commands, close the read connection if not persistant  if (cmd == CONNECT)     connectInfo.url = "https://" + args;  else {    connectInfo.url = args;    if (connectInfo.url.GetPort() == 0)      connectInfo.url.SetPort(myPort);  }  BOOL persist;  // If the incoming URL is of a proxy type then call OnProxy() which will  // probably just go OnError(). Even if a full URL is provided in the  // command we should check to see if it is a local server request and process  // it anyway even though we are not a proxy. The usage of GetHostName()  // below are to catch every way of specifying the host (name, alias, any of  // several IP numbers etc).  const PURL & url = connectInfo.GetURL();  if (url.GetScheme() != "http" ||      (url.GetPort() != 0 && url.GetPort() != myPort) ||      (!url.GetHostName() && !PIPSocket::IsLocalHost(url.GetHostName())))    persist = OnProxy(connectInfo);  else {    PString entityBody = ReadEntityBody();    // Handle the local request    PStringToString postData;    switch (cmd) {      case GET :        persist = OnGET(url, connectInfo.GetMIME(), connectInfo);        break;      case HEAD :        persist = OnHEAD(url, connectInfo.GetMIME(), connectInfo);        break;      case POST :        PURL::SplitQueryVars(entityBody, postData);        persist = OnPOST(url, connectInfo.GetMIME(), postData, connectInfo);        break;      case P_MAX_INDEX:      default:        persist = OnUnknown(args, connectInfo);    }  }  flush();  // if the function just indicated that the connection is to persist,  // and so did the client, then return TRUE. Note that all of the OnXXXX  // routines above must make sure that their return value is FALSE if  // if there was no ContentLength field in the response. This ensures that  // we always close the socket so the client will get the correct end of file  if (persist &&      connectInfo.IsPersistant() &&      transactionCount < MAX_TRANSACTIONS)    return TRUE;//  if (connectInfo.IsPersistant())//    PError << "Server: connection persistance end" << endl;  // close the output stream now and return FALSE  Shutdown(ShutdownWrite);  return FALSE;}PString PHTTPServer::ReadEntityBody(){  if (connectInfo.GetMajorVersion() < 1)    return PString();  PString entityBody;  long contentLength = connectInfo.GetEntityBodyLength();  // a content length of > 0 means read explicit length  // a content length of < 0 means read until EOF  // a content length of 0 means read nothing  int count = 0;  if (contentLength > 0) {    entityBody = ReadString((PINDEX)contentLength);  } else if (contentLength == -2) {    ReadLine(entityBody, FALSE);  } else if (contentLength < 0) {    while (Read(entityBody.GetPointer(count+1000)+count, 1000))      count += GetLastReadCount();    entityBody.SetSize(count+1);  }  // close the connection, if not persistant  if (!connectInfo.IsPersistant()) {    PIPSocket * socket = GetSocket();    if (socket != NULL)      socket->Shutdown(PIPSocket::ShutdownRead);  }  return entityBody;}PString PHTTPServer::GetServerName() const{  return "PWLib-HTTP-Server/1.0 PWLib/1.0";}void PHTTPServer::SetURLSpace(const PHTTPSpace & space){  urlSpace = space;}BOOL PHTTPServer::OnGET(const PURL & url,                   const PMIMEInfo & info,         const PHTTPConnectionInfo & connectInfo){  urlSpace.StartRead();  PHTTPResource * resource = urlSpace.FindResource(url);  if (resource == NULL) {    urlSpace.EndRead();    return OnError(NotFound, url.AsString(), connectInfo);  }  BOOL retval = resource->OnGET(*this, url, info, connectInfo);  urlSpace.EndRead();  return retval;}BOOL PHTTPServer::OnHEAD(const PURL & url,                    const PMIMEInfo & info,          const PHTTPConnectionInfo & connectInfo){  urlSpace.StartRead();  PHTTPResource * resource = urlSpace.FindResource(url);  if (resource == NULL) {    urlSpace.EndRead();    return OnError(NotFound, url.AsString(), connectInfo);  }  BOOL retval = resource->OnHEAD(*this, url, info, connectInfo);  urlSpace.EndRead();  return retval;}BOOL PHTTPServer::OnPOST(const PURL & url,                    const PMIMEInfo & info,              const PStringToString & data,          const PHTTPConnectionInfo & connectInfo){  urlSpace.StartRead();  PHTTPResource * resource = urlSpace.FindResource(url);  if (resource == NULL) {    urlSpace.EndRead();    return OnError(NotFound, url.AsString(), connectInfo);  }  BOOL retval = resource->OnPOST(*this, url, info, data, connectInfo);  urlSpace.EndRead();  return retval;}BOOL PHTTPServer::OnProxy(const PHTTPConnectionInfo & connectInfo){  return OnError(BadGateway, "Proxy not implemented.", connectInfo) &&         connectInfo.GetCommandCode() != CONNECT;}struct httpStatusCodeStruct {

⌨️ 快捷键说明

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