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

📄 httpsrvr.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 4 页
字号:
/* * httpsrvr.cxx * * HTTP server classes. * * Portable Windows Library * * Copyright (c) 1993-2002 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. * * Contributor(s): ______________________________________. * * $Log: httpsrvr.cxx,v $ * Revision 1.48  2005/01/15 07:53:55  csoutheren * Fixed problem when disabling http * * Revision 1.47  2004/02/03 09:37:20  rjongbloed * Added check to text files via the type extension, thanks David Parr * * Revision 1.46  2003/03/19 01:55:26  robertj * Fixed bugs in deleteing HTTP resources from server, thanks Diego T醨tara * * Revision 1.45  2002/11/06 22:47:25  robertj * Fixed header comment (copyright etc) * * Revision 1.44  2002/10/10 04:43:44  robertj * VxWorks port, thanks Martijn Roest * * Revision 1.43  2002/10/02 08:54:01  craigs * Added support for XMLRPC server * * Revision 1.42  2002/08/27 23:49:08  robertj * Fixed security hole where possible to get any file on disk when using *   PHTTPDirectory HTTP resource. * * Revision 1.41  2002/07/17 08:43:52  robertj * Fixed closing of html msg on generated post output. * * Revision 1.40  2002/05/08 05:38:54  robertj * Added PHTTPTailFile resource to do a unix 'tail -f' of a file. * * Revision 1.39  2002/04/12 08:15:23  robertj * Fixed warning on older GNU compilers, also guarantees numeric output. * * Revision 1.38  2001/10/31 01:37:13  robertj * Fixed deleting of object added to http name space if add fails. * Changes to support HTTP v1.1 chunked transfer encoding. * * Revision 1.37  2001/09/28 00:45:27  robertj * Removed HasKey() as is confusing due to ancestor Contains(). * * Revision 1.36  2001/06/01 07:28:23  craigs * Added handling for binary data in multi-part MIME fields * * Revision 1.35  2001/03/14 01:49:54  craigs * Added ability to handle multi-part form POST commands * * Revision 1.34  2001/01/15 06:17:56  robertj * Set HTTP resource members to private to assure are not modified by *   dscendents in non-threadsafe manner. * * Revision 1.33  2000/09/04 03:57:58  robertj * Added ability to change the persistent connection parameters (timeout etc). * * 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>#ifdef P_HTTP#include <ptlib/sockets.h>#include <ptclib/http.h>#include <ctype.h>#define new PNEW// define to enable work-around for Netscape persistant connection bug// set to lifetime of suspect sockets (in seconds)#define STRANGE_NETSCAPE_BUG	3// maximum delay between characters whilst reading a line of text#define	READLINE_TIMEOUT	30#define DEFAULT_PERSIST_TIMEOUT 30#define DEFAULT_PERSIST_TRANSATIONS 10//  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) {      delete res;      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()) {    delete res;    return FALSE;   // Already a resource in tree further down path.  }  if (overwrite == ErrorOnExist && node->resource != NULL) {    delete res;    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 have resource and not last node, then trying to remove something    // further down the tree than a leaf node.    if (node->resource != NULL && i < (path.GetSize()-1))      return FALSE;  }  if (!node->children.IsEmpty())    return FALSE;   // Still a resource in tree further down path.  if (node->parent != NULL) {    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));}void PHTTPConnectionInfo::DecodeMultipartFormInfo(const PString & type, const PString & entityBody){  // remove trailing ","  PINDEX pos = type.Find(",");  if (pos == P_MAX_INDEX) {    pos = type.Find(";");    if (pos == P_MAX_INDEX)       return;  }  PString seperator = type.Mid(pos+1).Trim();  // remove "boundary"  pos = seperator.Find("boundary");  if (pos == P_MAX_INDEX)    return;  seperator = seperator.Mid(8).Trim();  // remove "="  pos = seperator.Find("=");  if (pos == P_MAX_INDEX)    return;  seperator = seperator.Mid(1).Trim();  // seperators have a "--" according to RFC 1521  seperator = PString("--") + seperator;  PINDEX sepLen = seperator.GetLength();  const char * sep = (const char *)seperator;  // split body into parts, assuming binary data  const char * body = (const char *)entityBody;  PINDEX entityOffs = 0;  PINDEX entityLen = entityBody.GetSize()-1;  BOOL ignore = TRUE;  BOOL last = FALSE;  PMultipartFormInfo * info = NULL;  while (!last && (entityOffs < entityLen)) {    // find end of part    PINDEX partStart = entityOffs;    PINDEX partLen;    BOOL foundSep = FALSE;    // collect length of part until seperator    for (partLen = 0; (partStart + partLen) < entityLen; partLen++) {      if ((partLen >= sepLen) && (memcmp(body + partStart + partLen - sepLen, sep, sepLen) == 0)) {        foundSep = TRUE;        break;      }    }    // move entity ptr to the end of the part    entityOffs = partStart + partLen;    // if no seperator found, then this is the last part    // otherwise, look for "--" trailer on seperator and remove CRLF    if (!foundSep)      last = TRUE;    else {      partLen -= sepLen;      // determine if this is the last block      if (((entityOffs + 2) <= entityLen) && (body[entityOffs] == '-') && (body[entityOffs+1] == '-')) {        last = TRUE;        entityOffs += 2;      }      // remove crlf      if (((entityOffs + 2) <= entityLen) && (body[entityOffs] == '\r') && (body[entityOffs+1] == '\n'))         entityOffs += 2;    }    // ignore everything up to the first seperator,     // then adjust seperator to include leading CRLF    if (ignore) {      ignore = FALSE;      seperator = PString("\r\n") + seperator;      sepLen = seperator.GetLength();      sep = (const char *)seperator;      continue;    }    // extract the MIME header, by looking for a double CRLF    PINDEX ptr;    PINDEX nlCount = 0;    for (ptr = partStart;(ptr < (partStart + partLen)) && (nlCount < 2); ptr++) {      if (body[ptr] == '\r') {        nlCount++;        if ((ptr < entityLen-1) && (body[ptr+1] == '\n'))          ptr++;      } else        nlCount = 0;    }    // create the new part info    info = new PMultipartFormInfo;    // read MIME information    PStringStream strm(PString(body + partStart, ptr - partStart));    info->mime.ReadFrom(strm);    // save the entity body, being careful of binary files    int savedLen = partStart + partLen - ptr;    char * saved = info->body.GetPointer(savedLen + 1);    memcpy(saved, body + ptr, savedLen);    saved[savedLen] = '\0';    // add the data to the array    multipartFormInfoArray.Append(info);    info = NULL;  }  #if 0  // ignore until first separator  do {    data >> line;    if (line.IsEmpty())      return;  } while (line.Find(sep) != 0);  PMultipartFormInfo * info = NULL;  // read form parts  while (data.good() && (line.Right(2) != "--")) {

⌨️ 快捷键说明

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