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

📄 httpsrvr.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 4 页
字号:
    if (request.server.StartResponse(request.code, request.outMIME, request.contentSize)) {
      // Chunked transfer encoding
      request.outMIME.RemoveAll();
      do {
        WriteChunkedDataToServer(request.server, data);
      } while (LoadData(request, data));
      WriteChunkedDataToServer(request.server, data);
      request.server << "0\r\n" << request.outMIME;
    }
    else {
      do {
        request.server.Write(data, data.GetSize());
        data.SetSize(0);
      } while (LoadData(request, data));
      request.server.Write(data, data.GetSize());
    }
  }
  else {
    request.server.StartResponse(request.code, request.outMIME, data.GetSize());
    request.server.Write(data, data.GetSize());
  }
}


BOOL PHTTPResource::LoadData(PHTTPRequest & request, PCharArray & data)
{
  PString text = LoadText(request);
  OnLoadedText(request, text);
  text.SetSize(text.GetLength());  // Lose the trailing '\0'
  data = text;
  return FALSE;
}


PString PHTTPResource::LoadText(PHTTPRequest &)
{
  PAssertAlways(PUnimplementedFunction);
  return PString();
}


void PHTTPResource::OnLoadedText(PHTTPRequest &, PString &)
{
  // Do nothing
}


BOOL PHTTPResource::Post(PHTTPRequest & request,
                         const PStringToString &,
                         PHTML & msg)
{
  request.code = PHTTP::MethodNotAllowed;
  msg = "Error in POST";
  msg << "Post to this resource is not allowed" << PHTML::Body();
  return TRUE;
}


//////////////////////////////////////////////////////////////////////////////
// PHTTPString

PHTTPString::PHTTPString(const PURL & url)
  : PHTTPResource(url, "text/html")
{
}


PHTTPString::PHTTPString(const PURL & url,
                         const PHTTPAuthority & auth)
  : PHTTPResource(url, "text/html", auth)
{
}


PHTTPString::PHTTPString(const PURL & url, const PString & str)
  : PHTTPResource(url, "text/html"), string(str)
{
}


PHTTPString::PHTTPString(const PURL & url,
                         const PString & str,
                         const PString & type)
  : PHTTPResource(url, type), string(str)
{
}


PHTTPString::PHTTPString(const PURL & url,
                         const PString & str,
                         const PHTTPAuthority & auth)
  : PHTTPResource(url, "text/html", auth), string(str)
{
}


PHTTPString::PHTTPString(const PURL & url,
                         const PString & str,
                         const PString & type,
                         const PHTTPAuthority & auth)
  : PHTTPResource(url, type, auth), string(str)
{
}


BOOL PHTTPString::LoadHeaders(PHTTPRequest & request)
{
  request.contentSize = string.GetLength();
  return TRUE;
}


PString PHTTPString::LoadText(PHTTPRequest &)
{
  return string;
}


//////////////////////////////////////////////////////////////////////////////
// PHTTPFile

PHTTPFile::PHTTPFile(const PURL & url, int)
  : PHTTPResource(url)
{
}


PHTTPFile::PHTTPFile(const PString & filename)
  : PHTTPResource(filename, PMIMEInfo::GetContentType(PFilePath(filename).GetType())),
    filePath(filename)
{
}


PHTTPFile::PHTTPFile(const PString & filename, const PHTTPAuthority & auth)
  : PHTTPResource(filename, auth), filePath(filename)
{
}


PHTTPFile::PHTTPFile(const PURL & url, const PFilePath & path)
  : PHTTPResource(url, PMIMEInfo::GetContentType(path.GetType())),
    filePath(path)
{
}


PHTTPFile::PHTTPFile(const PURL & url,
                     const PFilePath & path,
                     const PString & type)
  : PHTTPResource(url, type), filePath(path)
{
}


PHTTPFile::PHTTPFile(const PURL & url,
                     const PFilePath & path,
                     const PHTTPAuthority & auth)
  : PHTTPResource(url, PMIMEInfo::GetContentType(path.GetType()), auth),
    filePath(path)
{
}


PHTTPFile::PHTTPFile(const PURL & url,
                     const PFilePath & path,
                     const PString & type,
                     const PHTTPAuthority & auth)
  : PHTTPResource(url, type, auth), filePath(path)
{
}


PHTTPFileRequest::PHTTPFileRequest(const PURL & url,
                                   const PMIMEInfo & inMIME,
                                   const PMultipartFormInfoArray & multipartFormInfo,
                                   PHTTPServer & server)
  : PHTTPRequest(url, inMIME, multipartFormInfo, server)
{
}


PHTTPRequest * PHTTPFile::CreateRequest(const PURL & url,
                                        const PMIMEInfo & inMIME,
                          const PMultipartFormInfoArray & multipartFormInfo,
                PHTTPServer & server)
{
  return new PHTTPFileRequest(url, inMIME, multipartFormInfo, server);
}


BOOL PHTTPFile::LoadHeaders(PHTTPRequest & request)
{
  PFile & file = ((PHTTPFileRequest&)request).file;

  if (!file.Open(filePath, PFile::ReadOnly)) {
    request.code = PHTTP::NotFound;
    return FALSE;
  }

  request.contentSize = file.GetLength();
  return TRUE;
}


BOOL PHTTPFile::LoadData(PHTTPRequest & request, PCharArray & data)
{
  PFile & file = ((PHTTPFileRequest&)request).file;

  PString contentType = GetContentType();
  if (contentType.IsEmpty())
    contentType = PMIMEInfo::GetContentType(file.GetFilePath().GetType());

  if (contentType(0, 4) *= "text/")
    return PHTTPResource::LoadData(request, data);

  PAssert(file.IsOpen(), PLogicError);

  PINDEX count = file.GetLength() - file.GetPosition();
  if (count > 10000)
    count = 10000;

  if (count > 0)
    PAssert(file.Read(data.GetPointer(count), count), PLogicError);

  if (!file.IsEndOfFile())
    return TRUE;

  file.Close();
  return FALSE;
}


PString PHTTPFile::LoadText(PHTTPRequest & request)
{
  PFile & file = ((PHTTPFileRequest&)request).file;
  PAssert(file.IsOpen(), PLogicError);
  PINDEX count = file.GetLength();
  PString text;
  if (count > 0)
    PAssert(file.Read(text.GetPointer(count+1), count), PLogicError);
  PAssert(file.Close(), PLogicError);
  return text;
}


//////////////////////////////////////////////////////////////////////////////
// PHTTPTailFile

PHTTPTailFile::PHTTPTailFile(const PString & filename)
  : PHTTPFile(filename)
{
}


PHTTPTailFile::PHTTPTailFile(const PString & filename,
                             const PHTTPAuthority & auth)
  : PHTTPFile(filename, auth)
{
}


PHTTPTailFile::PHTTPTailFile(const PURL & url,
                             const PFilePath & file)
  : PHTTPFile(url, file)
{
}


PHTTPTailFile::PHTTPTailFile(const PURL & url,
                             const PFilePath & file,
                             const PString & contentType)
  : PHTTPFile(url, file, contentType)
{
}


PHTTPTailFile::PHTTPTailFile(const PURL & url,
                             const PFilePath & file,
                             const PHTTPAuthority & auth)
  : PHTTPFile(url, file, auth)
{
}


PHTTPTailFile::PHTTPTailFile(const PURL & url,
                             const PFilePath & file,
                             const PString & contentType,
                             const PHTTPAuthority & auth)
  : PHTTPFile(url, file, contentType, auth)
{
}


BOOL PHTTPTailFile::LoadHeaders(PHTTPRequest & request)
{
  if (!PHTTPFile::LoadHeaders(request))
    return FALSE;

  request.contentSize = P_MAX_INDEX;
  return TRUE;
}


BOOL PHTTPTailFile::LoadData(PHTTPRequest & request, PCharArray & data)
{
  PFile & file = ((PHTTPFileRequest&)request).file;

  if (file.GetPosition() == 0)
    file.SetPosition(file.GetLength()-request.url.GetQueryVars()("offset", "10000").AsUnsigned());

  while (file.GetPosition() >= file.GetLength()) {
    if (!request.server.Write(NULL, 0))
      return FALSE;
    PThread::Sleep(200);
  }

  PINDEX count = file.GetLength() - file.GetPosition();
  return file.Read(data.GetPointer(count), count);
}


//////////////////////////////////////////////////////////////////////////////
// PHTTPDirectory

PHTTPDirectory::PHTTPDirectory(const PURL & url, const PDirectory & dir)
  : PHTTPFile(url, 0), basePath(dir), allowDirectoryListing(TRUE)
{
}


PHTTPDirectory::PHTTPDirectory(const PURL & url,
                               const PDirectory & dir,
                               const PHTTPAuthority & auth)
  : PHTTPFile(url, PString(), auth), basePath(dir), allowDirectoryListing(TRUE)
{
}


PHTTPDirRequest::PHTTPDirRequest(const PURL & url,
                                 const PMIMEInfo & inMIME,
                                 const PMultipartFormInfoArray & multipartFormInfo,
                                 PHTTPServer & server)
  : PHTTPFileRequest(url, inMIME, multipartFormInfo, server)
{
}


PHTTPRequest * PHTTPDirectory::CreateRequest(const PURL & url,
                                        const PMIMEInfo & inMIME,
                          const PMultipartFormInfoArray & multipartFormInfo,
                          PHTTPServer & socket)
{
  PHTTPDirRequest * request = new PHTTPDirRequest(url, inMIME, multipartFormInfo, socket);

  const PStringArray & path = url.GetPath();
  request->realPath = basePath;
  PINDEX i;
  for (i = GetURL().GetPath().GetSize(); i < path.GetSize()-1; i++)
    request->realPath += path[i] + PDIR_SEPARATOR;

  // append the last path element
  if (i < path.GetSize())
    request->realPath += path[i];

  if (request->realPath.Find(basePath) != 0)
    request->realPath = basePath;

  return request;
}


void PHTTPDirectory::EnableAuthorisation(const PString & realm)
{
  authorisationRealm = realm;
}


BOOL PHTTPDirectory::FindAuthorisations(const PDirectory & dir, PString & realm, PStringToString & authorisations)
{
  PFilePath fn = dir + accessFilename;
  PTextFile file;
  BOOL first = TRUE;
  if (file.Open(fn, PFile::ReadOnly)) {
    PString line;
    while (file.ReadLine(line)) {
      if (first) {
        realm = line.Trim();
        first = FALSE;
      } else {
        PStringArray tokens = line.Tokenise(':');
        if (tokens.GetSize() > 1)
          authorisations.SetAt(tokens[0].Trim(), tokens[1].Trim());
      }
    }
    return TRUE;
  }
    
  if (dir.IsRoot() || (dir == basePath))
    return FALSE;

  return FindAuthorisations(dir.GetParent(), realm, authorisations);
}

BOOL PHTTPDirectory::CheckAuthority(PHTTPServer & server,
                             const PHTTPRequest & request,
                      const PHTTPConnectionInfo & conInfo)
{
  // if access control is enabled, then search parent directories for password files
  PStringToString authorisations;
  PString newRealm;
  if (authorisationRealm.IsEmpty() ||
      !FindAuthorisations(((PHTTPDirRequest&)request).realPath.GetDirectory(), newRealm, authorisations) ||
      authorisations.GetSize() == 0)
    return TRUE;

  PHTTPMultiSimpAuth authority(newRealm, authorisations);
  return PHTTPResource::CheckAuthority(authority, server, request, conInfo);
}

BOOL PHTTPDirectory::LoadHeaders(PHTTPRequest & request)
{
  PFilePath & realPath = ((PHTTPDirRequest&)request).realPath;
    
  // if not able to obtain resource information, then consider the resource "not found"
  PFileInfo info;
  if (!PFile::GetInfo(realPath, info)) {
    request.code = PHTTP::NotFound;
    return FALSE;
  }

  // if the resource is a file, and the file can't be opened, then return "not found"
  PFile & file = ((PHTTPDirRequest&)request).file;
  if (info.type != PFileInfo::SubDirectory) {
    if (!file.Open(realPath, PFile::ReadOnly) ||
        (!authorisationRealm.IsEmpty() && realPath.GetFileName() == accessFilename)) {
      request.code = PHTTP::NotFound;
      return FALSE;
    }
  } 

  // resource is a directory - if index files disabled, then return "not found"
  else if (!allowDirectoryListing) {
    request.code = PHTTP::NotFound;
    return FALSE;
  }

  // else look for index files
  else {
    PINDEX i;
    for (i = 0; i < PARRAYSIZE(HTMLIndexFiles); i++)
      if (file.Open(realPath +
                          PDIR_SEPARATOR + HTMLIndexFiles[i], PFile::ReadOnly))
        break;
  }

  // open the file and return information
  PString & fakeIndex = ((PHTTPDirRequest&)request).fakeIndex;
  if (file.IsOpen()) {
    request.outMIME.SetAt(PHTTP::ContentTypeTag,
                          PMIMEInfo::GetContentType(file.GetFilePath().GetType()));
    request.contentSize = file.GetLength();
    fakeIndex = PString();
    return TRUE;
  }

  // construct a directory listing
  request.outMIME.SetAt(PHTTP::ContentTypeTag, "text/html");
  PHTML reply("Directory of " + request.url.AsString());
  PDirectory dir = realPath;
  if (dir.Open()) {
    do {
      const char * imgName;
      if (dir.IsSubDir())
        imgName = "internal-gopher-menu";
      else if (PMIMEInfo::GetContentType(
                    PFilePath(dir.GetEntryName()).GetType())(0,4) == "text/")
        imgName = "internal-gopher-text";
      else
        imgName = "internal-gopher-unknown";
      reply << PHTML::Image(imgName) << ' '
            << PHTML::HotLink(realPath.GetFileName()+'/'+dir.GetEntryName())
            << dir.GetEntryName()
            << PHTML::HotLink()
            << PHTML::BreakLine();
    } while (dir.Next());
  }
  reply << PHTML::Body();
  fakeIndex = reply;

  return TRUE;
}


PString PHTTPDirectory::LoadText(PHTTPRequest & request)
{
  PString & fakeIndex = ((PHTTPDirRequest&)request).fakeIndex;
  if (fakeIndex.IsEmpty())
    return PHTTPFile::LoadText(request);

  return fakeIndex;
}

#endif // P_HTTP


// End Of File ///////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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