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

📄 http.cxx

📁 基于VXWORKS H323通信技术源代码
💻 CXX
📖 第 1 页 / 共 2 页
字号:
  Parse(s);
}


PString PURL::TranslateString(const PString & str, TranslationType type)
{
  PString xlat = str;

  if (type == QueryTranslation) {
    PINDEX space = (PINDEX)-1;
    while ((space = xlat.Find(' ', space+1)) != P_MAX_INDEX)
      xlat[space] = '+';
  }

  PString safeChars = "abcdefghijklmnopqrstuvwxyz"
                      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                      "0123456789$-_.+!*'(),";
  switch (type) {
    case LoginTranslation :
      safeChars += ";?&=";
      break;

    case PathTranslation :
      safeChars += ":@&=";
      break;

    case QueryTranslation :
      safeChars += ":@";
  }
  PINDEX pos = (PINDEX)-1;
  while ((pos += 1+strspn(&xlat[pos+1], safeChars)) < xlat.GetLength())
    xlat.Splice(psprintf("%%%02X", (BYTE)xlat[pos]), pos, 1);

  return xlat;
}


static void UnmangleString(PString & str, PURL::TranslationType type)
{
  PINDEX pos;
  if (type == PURL::QueryTranslation) {
    pos = (PINDEX)-1;
    while ((pos = str.Find('+', pos+1)) != P_MAX_INDEX)
      str[pos] = ' ';
  }

  pos = (PINDEX)-1;
  while ((pos = str.Find('%', pos+1)) != P_MAX_INDEX) {
    int digit1 = str[pos+1];
    int digit2 = str[pos+2];
    if (isxdigit(digit1) && isxdigit(digit2)) {
      str[pos] = (char)(
            (isdigit(digit2) ? (digit2-'0') : (toupper(digit2)-'A'+10)) +
           ((isdigit(digit1) ? (digit1-'0') : (toupper(digit1)-'A'+10)) << 4));
      str.Delete(pos+1, 2);
    }
  }
}


void PURL::SplitQueryVars(const PString & queryStr, PStringToString & queryVars)
{
  PStringArray tokens = queryStr.Tokenise("&=", TRUE);
  for (PINDEX i = 0; i < tokens.GetSize(); i += 2) {
    PCaselessString key = tokens[i];
    UnmangleString(key, QueryTranslation);
    PString data = tokens[i+1];
    UnmangleString(data, QueryTranslation);
    if (queryVars.Contains(key))
      queryVars.SetAt(key, queryVars[key] + ',' + data);
    else
      queryVars.SetAt(key, data);
  }
}


void PURL::Parse(const char * cstr)
{
  hostname = PCaselessString();
  pathStr = username = password = parameters = fragment = queryStr = PString();
  path.SetSize(0);
  queryVars.RemoveAll();
  port = 0;

  // copy the string so we can take bits off it
  while (isspace(*cstr))
    cstr++;
  PString url = cstr;

  PINDEX pos;

  static const PString reservedChars = "=;/#?";

  // determine if the URL has a scheme
  scheme = "";
  if (isalpha(url[0])) {
    for (pos = 0; url[pos] != '\0' &&
                          reservedChars.Find(url[pos]) == P_MAX_INDEX; pos++) {
      if (url[pos] == ':') {
        scheme = url.Left(pos);
        url.Delete(0, pos+1);
        break;
      }
    }
  }

  // if there is no scheme, then default to http for the local
  // on the default port
  if (scheme.IsEmpty()) {
    scheme   = "http";
    if (url.GetLength() > 2 && url[0] == '/' && url[1] == '/') 
      url.Delete(0, 2);
  } else {

    // get information which tells us how to parse URL for this
    // particular scheme
    const schemeStruct & schemeInfo = GetSchemeInfo(scheme);
    
    // if the URL should have leading slash, then remove it if it has one
    if (schemeInfo.hasDoubleSlash &&
      url.GetLength() > 2 && url[0] == '/' && url[1] == '/') 
    url.Delete(0, 2);

    // if the rest of the URL isn't a path, then we are finished!
    if (schemeInfo.type == Other) {
      pathStr = url;
      return;
    }

    // parse user/password/host/port
    if (schemeInfo.type == HostPort ||
        schemeInfo.type == UserPasswordHostPort ||
        schemeInfo.type == HostOnly) {
      pos = url.Find('/');
      PString uphp = url.Left(pos);
      if (pos != P_MAX_INDEX)
        url.Delete(0, pos);
      else
        url = PString();

      // if the URL is of type HostOnly, then this is the hostname
      if (schemeInfo.type == HostOnly) {
        hostname = uphp;
        UnmangleString(hostname, LoginTranslation);
      } 

      // if the URL is of type UserPasswordHostPort, then parse it
      if (schemeInfo.type == UserPasswordHostPort) {

        // extract username and password
        PINDEX pos2 = uphp.Find('@');
        if (pos2 != P_MAX_INDEX && pos2 > 0) {
          PINDEX pos3 = uphp.Find(":");
          // if no password...
          if (pos3 > pos2)
            username = uphp(0, pos2-1);
          else {
            username = uphp(0, pos3-1);
            password = uphp(pos3+1, pos2-1);
            UnmangleString(password, LoginTranslation);
          }
          UnmangleString(username, LoginTranslation);
          uphp.Delete(0, pos2+1);
        }
      }

      // determine if the URL has a port number
      if (schemeInfo.type == HostPort ||
          schemeInfo.type == UserPasswordHostPort) {
        pos = uphp.Find(":");
        if (pos == P_MAX_INDEX) {
          hostname = uphp;
          port = schemeInfo.defaultPort;
        } else {
          hostname = uphp.Left(pos);
          port = (WORD)uphp(pos+1, P_MAX_INDEX).AsInteger();
        }
        UnmangleString(hostname, LoginTranslation);
        if (hostname.IsEmpty())
          hostname = PIPSocket::GetHostName();
      }
    }
  }

  // chop off any trailing fragment
  pos = url.Find('#');
  if (pos != P_MAX_INDEX && pos > 0) {
    fragment = url(pos+1, P_MAX_INDEX);
    UnmangleString(fragment, PathTranslation);
    url.Delete(pos, P_MAX_INDEX);
  }

  // chop off any trailing query
  pos = url.Find('?');
  if (pos != P_MAX_INDEX && pos > 0) {
    queryStr = url(pos+1, P_MAX_INDEX);
    url.Delete(pos, P_MAX_INDEX);
    SplitQueryVars(queryStr, queryVars);
  }

  // chop off any trailing parameters
  pos = url.Find(';');
  if (pos != P_MAX_INDEX && pos > 0) {
    parameters = url(pos+1, P_MAX_INDEX);
    UnmangleString(parameters, PathTranslation);
    url.Delete(pos, P_MAX_INDEX);
  }

  // the hierarchy is what is left
  pathStr = url;
  path = url.Tokenise("/", TRUE);
  if (path.GetSize() > 0 && path[0].IsEmpty()) 
    path.RemoveAt(0);
  for (pos = 0; pos < path.GetSize(); pos++) {
    UnmangleString(path[pos], PathTranslation);
    if (pos > 0 && path[pos] == ".." && path[pos-1] != "..") {
      path.RemoveAt(pos--);
      path.RemoveAt(pos--);
    }
  }
}


PString PURL::AsString(UrlFormat fmt) const
{
  PStringStream str;

  if (fmt == FullURL || fmt == HostPortOnly) {

    // if the scheme is empty, assume http
    if (!scheme) {
      str << scheme << ':';
      const schemeStruct & schemeInfo = GetSchemeInfo(scheme);

      if (schemeInfo.hasDoubleSlash)
        str << "//";

      if (schemeInfo.type == Other) 
        str << pathStr;
      else {
        if (schemeInfo.type == HostOnly)
          str << hostname;

        if (schemeInfo.type == UserPasswordHostPort) {
          if (!username || !password)
            str << TranslateString(username, LoginTranslation)
                << ':'
                << TranslateString(password, LoginTranslation)
                << '@';
        }

        if (schemeInfo.type == HostPort || schemeInfo.type == UserPasswordHostPort) {
          if (hostname.IsEmpty())
            str = PString();
          else {
            str << hostname;
            if (port != schemeInfo.defaultPort)
              str << ':' << port;
          }
        }
      }
    }
    if (fmt == HostPortOnly)
      return str;
  }

  PINDEX count = path.GetSize();
  if (count > 0) {
    str << '/';
    for (PINDEX i = 0; i < count; i++) {
      str << TranslateString(path[i], PathTranslation);
      if (i < count-1)
        str << '/';
    }
  }

  if (fmt == FullURL || fmt == URIOnly) {
    if (!parameters)
      str << ";" << TranslateString(parameters, PathTranslation);

    if (!queryStr)
      str << "?" << queryStr;

    if (!fragment)
      str << "#" << TranslateString(fragment, PathTranslation);
  }

  return str;
}


BOOL PURL::OpenBrowser(const PString & url)
{
#ifdef WIN32
  if ((int)ShellExecute(NULL, "open", url, NULL, NULL, 0) > 32)
    return TRUE;

  MessageBox(NULL, "Unable to open page"&url, PProcess::Current().GetName(), MB_TASKMODAL);
#endif
  return FALSE;
}


//////////////////////////////////////////////////////////////////////////////
// PHTTP

static char const * const HTTPCommands[PHTTP::NumCommands] = {
  // HTTP 1.0 commands
  "GET", "HEAD", "POST",

  // HTTP 1.1 commands
  "PUT",  "DELETE", "TRACE", "OPTIONS",

  // HTTPS command
  "CONNECT"
};


const PCaselessString PHTTP::AllowTag           = "Allow";
const PCaselessString PHTTP::AuthorizationTag   = "Authorization";
const PCaselessString PHTTP::ContentEncodingTag = "Content-Encoding";
const PCaselessString PHTTP::ContentLengthTag   = "Content-Length";
const PCaselessString PHTTP::ContentTypeTag     = "Content-Type";
const PCaselessString PHTTP::DateTag            = "Date";
const PCaselessString PHTTP::ExpiresTag         = "Expires";
const PCaselessString PHTTP::FromTag            = "From";
const PCaselessString PHTTP::IfModifiedSinceTag = "If-Modified-Since";
const PCaselessString PHTTP::LastModifiedTag    = "Last-Modified";
const PCaselessString PHTTP::LocationTag        = "Location";
const PCaselessString PHTTP::PragmaTag          = "Pragma";
const PCaselessString PHTTP::PragmaNoCacheTag   = "no-cache";
const PCaselessString PHTTP::RefererTag         = "Referer";
const PCaselessString PHTTP::ServerTag          = "Server";
const PCaselessString PHTTP::UserAgentTag       = "User-Agent";
const PCaselessString PHTTP::WWWAuthenticateTag = "WWW-Authenticate";
const PCaselessString PHTTP::MIMEVersionTag     = "MIME-Version";
const PCaselessString PHTTP::ConnectionTag      = "Connection";
const PCaselessString PHTTP::KeepAliveTag       = "Keep-Alive";
const PCaselessString PHTTP::ProxyConnectionTag = "Proxy-Connection";
const PCaselessString PHTTP::ProxyAuthorizationTag = "Proxy-Authorization";
const PCaselessString PHTTP::ProxyAuthenticateTag = "Proxy-Authenticate";
const PCaselessString PHTTP::ForwardedTag       = "Forwarded";
const PCaselessString PHTTP::SetCookieTag       = "Set-Cookie";
const PCaselessString PHTTP::CookieTag          = "Cookie";



PHTTP::PHTTP()
  : PInternetProtocol("www 80", NumCommands, HTTPCommands)
{
}


PINDEX PHTTP::ParseResponse(const PString & line)
{
  PINDEX endVer = line.Find(' ');
  if (endVer == P_MAX_INDEX) {
    lastResponseInfo = "Bad response";
    lastResponseCode = PHTTP::InternalServerError;
    return 0;
  }

  lastResponseInfo = line.Left(endVer);
  PINDEX endCode = line.Find(' ', endVer+1);
  lastResponseCode = line(endVer+1,endCode-1).AsInteger();
  if (lastResponseCode == 0)
    lastResponseCode = PHTTP::InternalServerError;
  lastResponseInfo &= line.Mid(endCode);
  return 0;
}


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

⌨️ 快捷键说明

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