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

📄 httpsrvr.cxx

📁 pwlib源码库
💻 CXX
📖 第 1 页 / 共 4 页
字号:
}PObject * PHTTPSimpleAuth::Clone() const{  return new PHTTPSimpleAuth(realm, username, password);}BOOL PHTTPSimpleAuth::IsActive() const{  return !username || !password;}PString PHTTPSimpleAuth::GetRealm(const PHTTPRequest &) const{  return realm;}BOOL PHTTPSimpleAuth::Validate(const PHTTPRequest &,                               const PString & authInfo) const{  PString user, pass;  DecodeBasicAuthority(authInfo, user, pass);  return username == user && password == pass;}//////////////////////////////////////////////////////////////////////////////// PHTTPMultiSimpAuthPHTTPMultiSimpAuth::PHTTPMultiSimpAuth(const PString & realm_)  : realm(realm_){  PAssert(!realm, "Must have a realm!");}PHTTPMultiSimpAuth::PHTTPMultiSimpAuth(const PString & realm_,                                       const PStringToString & users_)  : realm(realm_), users(users_){  PAssert(!realm, "Must have a realm!");}PObject * PHTTPMultiSimpAuth::Clone() const{  return new PHTTPMultiSimpAuth(realm, users);}BOOL PHTTPMultiSimpAuth::IsActive() const{  return !users.IsEmpty();}PString PHTTPMultiSimpAuth::GetRealm(const PHTTPRequest &) const{  return realm;}BOOL PHTTPMultiSimpAuth::Validate(const PHTTPRequest &,                                  const PString & authInfo) const{  PString user, pass;  DecodeBasicAuthority(authInfo, user, pass);  return users.Contains(user) && users[user] == pass;}void PHTTPMultiSimpAuth::AddUser(const PString & username, const PString & password){  users.SetAt(username, password);}//////////////////////////////////////////////////////////////////////////////// PHTTPRequestPHTTPRequest::PHTTPRequest(const PURL & _url,                      const PMIMEInfo & _mime,        const PMultipartFormInfoArray & _multipartFormInfo,                          PHTTPServer & _server)  : server(_server),    url(_url),    inMIME(_mime),    multipartFormInfo(_multipartFormInfo),    origin(0),    localAddr(0),    localPort(0){  code        = PHTTP::RequestOK;  contentSize = P_MAX_INDEX;  PIPSocket * socket = server.GetSocket();  if (socket != NULL) {    socket->GetPeerAddress(origin);    socket->GetLocalAddress(localAddr, localPort);  }}//////////////////////////////////////////////////////////////////////////////// PHTTPConnectionInfoPHTTPConnectionInfo::PHTTPConnectionInfo()  : persistenceTimeout(0, DEFAULT_PERSIST_TIMEOUT) // maximum lifetime (in seconds) of persistant connections{  // maximum lifetime (in transactions) of persistant connections  persistenceMaximum = DEFAULT_PERSIST_TRANSATIONS;  commandCode       = PHTTP::NumCommands;  majorVersion      = 0;  minorVersion      = 9;  isPersistant      = FALSE;  wasPersistant     = FALSE;  isProxyConnection = FALSE;  entityBodyLength  = -1;  multipartFormInfoArray.AllowDeleteObjects();}BOOL PHTTPConnectionInfo::Initialise(PHTTPServer & server, PString & args){  // if only one argument, then it must be a version 0.9 simple request  PINDEX lastSpacePos = args.FindLast(' ');  static const PCaselessString httpId = "HTTP/";  if (lastSpacePos == P_MAX_INDEX || httpId != args(lastSpacePos+1, lastSpacePos+5)) {    majorVersion = 0;    minorVersion = 9;    return TRUE;  }  // otherwise, attempt to extract a version number  PCaselessString verStr = args.Mid(lastSpacePos + 6);  PINDEX dotPos = verStr.Find('.');  if (dotPos == 0 || dotPos >= verStr.GetLength()) {    server.OnError(PHTTP::BadRequest, "Malformed version number: " + verStr, *this);    return FALSE;  }  // should actually check if the text contains only digits, but the  // chances of matching everything else and it not being a valid number  // are pretty small, so don't bother  majorVersion = (int)verStr.Left(dotPos).AsInteger();  minorVersion = (int)verStr.Mid(dotPos+1).AsInteger();  args.Delete(lastSpacePos, P_MAX_INDEX);  // build our connection info reading MIME info until an empty line is  // received, or EOF  if (!mimeInfo.Read(server))    return FALSE;  wasPersistant = isPersistant;  isPersistant = FALSE;  PString str;  // check for Proxy-Connection and Connection strings  isProxyConnection = mimeInfo.Contains(PHTTP::ProxyConnectionTag);  if (isProxyConnection)    str = mimeInfo[PHTTP::ProxyConnectionTag];  else if (mimeInfo.Contains(PHTTP::ConnectionTag))    str = mimeInfo[PHTTP::ConnectionTag];  // get any connection options  if (!str) {    PStringArray tokens = str.Tokenise(", \r\n", FALSE);    for (PINDEX z = 0; !isPersistant && z < tokens.GetSize(); z++)      isPersistant = isPersistant || (tokens[z] *= PHTTP::KeepAliveTag);  }  // If the protocol is version 1.0 or greater, there is MIME info, and the  // prescence of a an entity body is signalled by the inclusion of  // Content-Length header. If the protocol is less than version 1.0, then   // there is no entity body!  // if the client specified a persistant connection, then use the  // ContentLength field. If there is no content length field, then  // assume a ContentLength of zero and close the connection.  // The spec actually says to read until end of file in this case,  // but Netscape hangs if this is done.  // If the client didn't specify a persistant connection, then use the  // ContentLength if there is one or read until end of file if there isn't  if (!isPersistant)    entityBodyLength = mimeInfo.GetInteger(PHTTP::ContentLengthTag,                                           (commandCode == PHTTP::POST) ? -2 : 0);  else {    entityBodyLength = mimeInfo.GetInteger(PHTTP::ContentLengthTag, -1);    if (entityBodyLength < 0) {      PTRACE(5, "HTTPServer\tPersistant connection has no content length");      entityBodyLength = 0;      mimeInfo.SetAt(PHTTP::ContentLengthTag, "0");    }  }  return TRUE;}void PHTTPConnectionInfo::SetMIME(const PString & tag, const PString & value){  mimeInfo.MakeUnique();  mimeInfo.SetAt(tag, value);}BOOL PHTTPConnectionInfo::IsCompatible(int major, int minor) const{  if (minor == 0 && major == 0)    return TRUE;  else    return (majorVersion > major) ||           ((majorVersion == major) && (minorVersion >= minor));}//////////////////////////////////////////////////////////////////////////////// PHTTPResourcePHTTPResource::PHTTPResource(const PURL & url)  : baseURL(url){  authority = NULL;  hitCount = 0;}PHTTPResource::PHTTPResource(const PURL & url, const PHTTPAuthority & auth)  : baseURL(url){  authority = (PHTTPAuthority *)auth.Clone();  hitCount = 0;}PHTTPResource::PHTTPResource(const PURL & url, const PString & type)  : baseURL(url), contentType(type){  authority = NULL;  hitCount = 0;}PHTTPResource::PHTTPResource(const PURL & url,                             const PString & type,                             const PHTTPAuthority & auth)  : baseURL(url), contentType(type){  authority = (PHTTPAuthority *)auth.Clone();  hitCount = 0;}PHTTPResource::~PHTTPResource(){  delete authority;}BOOL PHTTPResource::OnGET(PHTTPServer & server,                           const PURL & url,                      const PMIMEInfo & info,            const PHTTPConnectionInfo & connectInfo){  return OnGETOrHEAD(server, url, info, connectInfo, TRUE);}BOOL PHTTPResource::OnHEAD(PHTTPServer & server,                           const PURL & url,                      const PMIMEInfo & info,            const PHTTPConnectionInfo & connectInfo){  return OnGETOrHEAD(server, url, info, connectInfo, FALSE);}BOOL PHTTPResource::OnGETOrHEAD(PHTTPServer & server,                           const PURL & url,                      const PMIMEInfo & info,            const PHTTPConnectionInfo & connectInfo,                                   BOOL isGET){  // Nede to split songle if into 2 so the Tornado compiler won't end with  // 'internal compiler error'  if (isGET && info.Contains(PHTTP::IfModifiedSinceTag))    if (!IsModifiedSince(PTime(info[PHTTP::IfModifiedSinceTag])))      return server.OnError(PHTTP::NotModified, url.AsString(), connectInfo);  PHTTPRequest * request = CreateRequest(url,                                         info,                                         connectInfo.GetMultipartFormInfo(),                                         server);  BOOL retVal = TRUE;  if (CheckAuthority(server, *request, connectInfo)) {    retVal = FALSE;    server.SetDefaultMIMEInfo(request->outMIME, connectInfo);    PTime expiryDate;    if (GetExpirationDate(expiryDate))      request->outMIME.SetAt(PHTTP::ExpiresTag,                              expiryDate.AsString(PTime::RFC1123, PTime::GMT));    if (!LoadHeaders(*request))       retVal = server.OnError(request->code, url.AsString(), connectInfo);    else if (!isGET)      retVal = request->outMIME.Contains(PHTTP::ContentLengthTag);    else {      hitCount++;      retVal = OnGETData(server, url, connectInfo, *request);    }  }  delete request;  return retVal;}BOOL PHTTPResource::OnGETData(PHTTPServer & /*server*/,                               const PURL & /*url*/,                const PHTTPConnectionInfo & /*connectInfo*/,                             PHTTPRequest & request){  SendData(request);  return request.outMIME.Contains(PHTTP::ContentLengthTag) ||         request.outMIME.Contains(PHTTP::TransferEncodingTag);}BOOL PHTTPResource::OnPOST(PHTTPServer & server,                            const PURL & url,                       const PMIMEInfo & info,                 const PStringToString & data,             const PHTTPConnectionInfo & connectInfo){  PHTTPRequest * request = CreateRequest(url,                                         info,                                         connectInfo.GetMultipartFormInfo(),                                         server);  request->entityBody = connectInfo.GetEntityBody();  BOOL persist = TRUE;  if (CheckAuthority(server, *request, connectInfo)) {    server.SetDefaultMIMEInfo(request->outMIME, connectInfo);    persist = OnPOSTData(*request, data);    if (request->code != PHTTP::RequestOK)      persist = server.OnError(request->code, "", connectInfo) && persist;  }  delete request;  return persist;}BOOL PHTTPResource::OnPOSTData(PHTTPRequest & request,                               const PStringToString & data){  PHTML msg;  BOOL persist = Post(request, data, msg);  if (msg.Is(PHTML::InBody))    msg << PHTML::Body();  if (request.code != PHTTP::RequestOK)    return persist;  if (msg.IsEmpty())    msg << PHTML::Title()    << (unsigned)PHTTP::RequestOK << " OK" << PHTML::Body()        << PHTML::Heading(1) << (unsigned)PHTTP::RequestOK << " OK" << PHTML::Heading(1)        << PHTML::Body();  request.outMIME.SetAt(PHTTP::ContentTypeTag, "text/html");  PINDEX len = msg.GetLength();  request.server.StartResponse(request.code, request.outMIME, len);  return request.server.Write((const char *)msg, len) && persist;}BOOL PHTTPResource::CheckAuthority(PHTTPServer & server,                            const PHTTPRequest & request,                     const PHTTPConnectionInfo & connectInfo){  if (authority == NULL)    return TRUE;  return CheckAuthority(*authority, server, request, connectInfo);}        BOOL PHTTPResource::CheckAuthority(PHTTPAuthority & authority,                                      PHTTPServer & server,                               const PHTTPRequest & request,                        const PHTTPConnectionInfo & connectInfo){  if (!authority.IsActive())    return TRUE;  // if this is an authorisation request...  if (request.inMIME.Contains(PHTTP::AuthorizationTag) &&      authority.Validate(request, request.inMIME[PHTTP::AuthorizationTag]))    return TRUE;  // it must be a request for authorisation  PMIMEInfo headers;  server.SetDefaultMIMEInfo(headers, connectInfo);  headers.SetAt(PHTTP::WWWAuthenticateTag,                       "Basic realm=\"" + authority.GetRealm(request) + "\"");  headers.SetAt(PHTTP::ContentTypeTag, "text/html");  const httpStatusCodeStruct * statusInfo =                               GetStatusCodeStruct(PHTTP::UnAuthorised);  PHTML reply;  reply << PHTML::Title()        << statusInfo->code        << ' '        << statusInfo->text        << PHTML::Body()        << PHTML::Heading(1)        << statusInfo->code        << ' '        << statusInfo->text        << PHTML::Heading(1)        << "Your request cannot be authorised because it requires authentication."        << PHTML::Paragraph()        << "This may be because you entered an incorrect username or password, "        << "or because your browser is not performing Basic authentication."        << PHTML::Body();  server.StartResponse(PHTTP::UnAuthorised, headers, reply.GetLength());  server.WriteString(reply);  return FALSE;}void PHTTPResource::SetAuthority(const PHTTPAuthority & auth){  delete authority;  authority = (PHTTPAuthority *)auth.Clone();}void PHTTPResource::ClearAuthority(){  delete authority;  authority = NULL;}BOOL PHTTPResource::IsModifiedSince(const PTime &){  return TRUE;}BOOL PHTTPResource::GetExpirationDate(PTime &){  return FALSE;}PHTTPRequest * PHTTPResource::CreateRequest(const PURL & url,                                            const PMIMEInfo & inMIME,                                            const PMultipartFormInfoArray & multipartFormInfo,				            PHTTPServer & socket){  return new PHTTPRequest(url, inMIME, multipartFormInfo, socket);}static void WriteChunkedDataToServer(PHTTPServer & server, PCharArray & data){  if (data.GetSize() == 0)    return;  server << data.GetSize() << "\r\n";  server.Write(data, data.GetSize());  server << "\r\n";  data.SetSize(0);}void PHTTPResource::SendData(PHTTPRequest & request){  if (!request.outMIME.Contains(PHTTP::ContentTypeTag) && !contentType)    request.outMIME.SetAt(PHTTP::ContentTypeTag, contentType);  PCharArray data;  if (LoadData(request, data)) {    if (request.server.StartResponse(request.code, request.outMIME, request.contentSize)) {      // Chunked transfer encoding      request.outMIME.RemoveAll();

⌨️ 快捷键说明

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