📄 http.cxx
字号:
PString s; stream >> s; 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;}//////////////////////////////////////////////////////////////////////////////// PHTTPstatic 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 char * PHTTP::AllowTag = "Allow";const char * PHTTP::AuthorizationTag = "Authorization";const char * PHTTP::ContentEncodingTag = "Content-Encoding";const char * PHTTP::ContentLengthTag = "Content-Length";const char * PHTTP::ContentTypeTag = "Content-Type";const char * PHTTP::DateTag = "Date";const char * PHTTP::ExpiresTag = "Expires";const char * PHTTP::FromTag = "From";const char * PHTTP::IfModifiedSinceTag = "If-Modified-Since";const char * PHTTP::LastModifiedTag = "Last-Modified";const char * PHTTP::LocationTag = "Location";const char * PHTTP::PragmaTag = "Pragma";const char * PHTTP::PragmaNoCacheTag = "no-cache";const char * PHTTP::RefererTag = "Referer";const char * PHTTP::ServerTag = "Server";const char * PHTTP::UserAgentTag = "User-Agent";const char * PHTTP::WWWAuthenticateTag = "WWW-Authenticate";const char * PHTTP::MIMEVersionTag = "MIME-Version";const char * PHTTP::ConnectionTag = "Connection";const char * PHTTP::KeepAliveTag = "Keep-Alive";const char * PHTTP::ProxyConnectionTag = "Proxy-Connection";const char * PHTTP::ProxyAuthorizationTag = "Proxy-Authorization";const char * PHTTP::ProxyAuthenticateTag = "Proxy-Authenticate";const char * PHTTP::ForwardedTag = "Forwarded";const char * PHTTP::SetCookieTag = "Set-Cookie";const char * 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 + -