📄 ncbicgi.cpp
字号:
/* * =========================================================================== * PRODUCTION $Log: ncbicgi.cpp,v $ * PRODUCTION Revision 1000.2 2004/06/01 18:39:19 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.76 * PRODUCTION * =========================================================================== *//* $Id: ncbicgi.cpp,v 1000.2 2004/06/01 18:39:19 gouriano Exp $* ===========================================================================** PUBLIC DOMAIN NOTICE* National Center for Biotechnology Information** This software/database is a "United States Government Work" under the* terms of the United States Copyright Act. It was written as part of* the author's official duties as a United States Government employee and* thus cannot be copyrighted. This software/database is freely available* to the public for use. The National Library of Medicine and the U.S.* Government have not placed any restriction on its use or reproduction.** Although all reasonable efforts have been taken to ensure the accuracy* and reliability of the software and data, the NLM and the U.S.* Government do not and cannot warrant the performance or results that* may be obtained by using this software or data. The NLM and the U.S.* Government disclaim all warranties, express or implied, including* warranties of performance, merchantability or fitness for any particular* purpose.** Please cite the author in any work or product based on this material.** ===========================================================================** Author: Denis Vakatov** File Description:* NCBI C++ CGI API:* CCgiCookie -- one CGI cookie* CCgiCookies -- set of CGI cookies* CCgiRequest -- full CGI request*/#include <ncbi_pch.hpp>#include <corelib/ncbienv.hpp>#include <corelib/ncbitime.hpp>#include <cgi/cgi_exception.hpp>#include <cgi/ncbicgi.hpp>#include <stdio.h>#include <time.h>#ifdef HAVE_UNISTD_H# include <unistd.h>#else# define STDIN_FILENO 0#endif// Mac OS has unistd.h, but STDIN_FILENO is not defined#ifdef NCBI_OS_MAC# define STDIN_FILENO 0#endifBEGIN_NCBI_SCOPE///////////////////////////////////////////////////////// CCgiCookie:://// auxiliary zero "tm" structconst tm kZeroTime = { 0,0,0,0,0,0,0,0,0 };inline bool s_ZeroTime(const tm& date) { return (::memcmp(&date, &kZeroTime, sizeof(tm)) == 0);}CCgiCookie::CCgiCookie(const CCgiCookie& cookie) : m_Name(cookie.m_Name), m_Value(cookie.m_Value), m_Domain(cookie.m_Domain), m_Path(cookie.m_Path){ m_Expires = cookie.m_Expires; m_Secure = cookie.m_Secure;}CCgiCookie::CCgiCookie(const string& name, const string& value, const string& domain, const string& path){ if ( name.empty() ) throw invalid_argument("Empty cookie name"); x_CheckField(name, " ;,="); m_Name = name; SetDomain(domain); SetPath(path); SetValue(value); m_Expires = kZeroTime; m_Secure = false;}void CCgiCookie::Reset(void){ m_Value.erase(); m_Domain.erase(); m_Path.erase(); m_Expires = kZeroTime; m_Secure = false;}void CCgiCookie::CopyAttributes(const CCgiCookie& cookie){ if (&cookie == this) return; m_Value = cookie.m_Value; m_Domain = cookie.m_Domain; m_Path = cookie.m_Path; m_Expires = cookie.m_Expires; m_Secure = cookie.m_Secure;}string CCgiCookie::GetExpDate(void) const{ if ( s_ZeroTime(m_Expires) ) return kEmptyStr; char str[30]; if ( !::strftime(str, sizeof(str), "%a, %d %b %Y %H:%M:%S GMT", &m_Expires) ) { NCBI_THROW(CCgiErrnoException, eErrno, "CCgiCookie::GetExpDate() -- strftime() failed"); } return string(str);}bool CCgiCookie::GetExpDate(tm* exp_date) const{ if ( !exp_date ) throw invalid_argument("Null cookie exp.date"); if ( s_ZeroTime(m_Expires) ) return false; *exp_date = m_Expires; return true;}CNcbiOstream& CCgiCookie::Write(CNcbiOstream& os) const{ os << "Set-Cookie: "; os << m_Name.c_str() << '='; if ( !m_Value.empty() ) os << m_Value.c_str(); if ( !m_Domain.empty() ) os << "; domain=" << m_Domain.c_str(); if ( !m_Path.empty() ) os << "; path=" << m_Path.c_str(); string x_ExpDate = GetExpDate(); if ( !x_ExpDate.empty() ) os << "; expires=" << x_ExpDate.c_str(); if ( m_Secure ) os << "; secure"; os << HTTP_EOL; return os;}// Check if the cookie field is validvoid CCgiCookie::x_CheckField(const string& str, const char* banned_symbols){ if (banned_symbols && str.find_first_of(banned_symbols) != NPOS) { throw invalid_argument("CCgiCookie::CheckValidCookieField() [1]"); } for (const char* s = str.c_str(); *s; s++) { if ( !isprint(*s) ) throw invalid_argument("CCgiCookie::CheckValidCookieField() [2]"); }}static bool s_CookieLess(const string& name1, const string& domain1, const string& path1, const string& name2, const string& domain2, const string& path2){ PNocase nocase_less; bool x_less; x_less = nocase_less(name1, name2); if (x_less || nocase_less(name2, name1)) return x_less; x_less = nocase_less(domain1, domain2); if (x_less || nocase_less(domain2, domain1)) return x_less; if ( path1.empty() ) return !path2.empty(); if ( path2.empty() ) return false; return (path1.compare(path2) > 0);}bool CCgiCookie::operator< (const CCgiCookie& cookie) const{ return s_CookieLess(m_Name, m_Domain, m_Path, cookie.m_Name, cookie.m_Domain, cookie.m_Path);}void CCgiCookie::SetExpTime(const CTime& exp_time){ _ASSERT(exp_time.IsGmtTime()); m_Expires.tm_sec = exp_time.Second(); m_Expires.tm_min = exp_time.Minute(); m_Expires.tm_hour = exp_time.Hour(); m_Expires.tm_mday = exp_time.Day(); m_Expires.tm_mon = exp_time.Month()-1; m_Expires.tm_wday = exp_time.DayOfWeek(); m_Expires.tm_year = exp_time.Year()-1900; m_Expires.tm_isdst = -1;}///////////////////////////////////////////////////////// CCgiCookies:://CCgiCookie* CCgiCookies::Add(const string& name, const string& value, const string& domain , const string& path){ CCgiCookie* ck = Find(name, domain, path); if ( ck ) { // override existing CCgiCookie ck->SetValue(value); } else { // create new CCgiCookie and add it ck = new CCgiCookie(name, value); ck->SetDomain(domain); ck->SetPath(path); _VERIFY( m_Cookies.insert(ck).second ); } return ck;}CCgiCookie* CCgiCookies::Add(const CCgiCookie& cookie){ CCgiCookie* ck = Find (cookie.GetName(), cookie.GetDomain(), cookie.GetPath()); if ( ck ) { // override existing CCgiCookie ck->CopyAttributes(cookie); } else { // create new CCgiCookie and add it ck = new CCgiCookie(cookie); _VERIFY( m_Cookies.insert(ck).second ); } return ck;}void CCgiCookies::Add(const CCgiCookies& cookies){ ITERATE (TSet, cookie, cookies.m_Cookies) { Add(**cookie); }}void CCgiCookies::Add(const string& str){ SIZE_TYPE pos; for (pos = str.find_first_not_of(" \t\n"); ; ){ SIZE_TYPE pos_beg = str.find_first_not_of(' ', pos); if (pos_beg == NPOS) return; // done SIZE_TYPE pos_mid = str.find_first_of("=;\r\n", pos_beg); if (pos_mid == NPOS) { Add(str.substr(pos_beg), kEmptyStr); return; // done } if (str[pos_mid] != '=') { Add(str.substr(pos_beg, pos_mid-pos_beg), kEmptyStr); if (str[pos_mid] != ';' || ++pos_mid == str.length()) return; // done pos = pos_mid; continue; } SIZE_TYPE pos_end = str.find_first_of(';', pos_mid); if (pos_end != NPOS) { pos = pos_end + 1; pos_end--; } else { pos_end = str.find_last_not_of(" \t\n", str.length()); if (pos_end == NPOS) break; // error pos = NPOS; // about to finish } Add(str.substr(pos_beg, pos_mid-pos_beg), str.substr(pos_mid+1, pos_end-pos_mid)); } NCBI_THROW2(CCgiParseException, eCookie, "Invalid cookie string: `" + str + "'", pos);}CNcbiOstream& CCgiCookies::Write(CNcbiOstream& os) const{ ITERATE (TSet, cookie, m_Cookies) { os << **cookie; } return os;}CCgiCookie* CCgiCookies::Find(const string& name, const string& domain, const string& path){ TCIter iter = m_Cookies.begin(); while (iter != m_Cookies.end() && s_CookieLess((*iter)->GetName(), (*iter)->GetDomain(), (*iter)->GetPath(), name, domain, path)) { iter++; } // find exact match if (iter != m_Cookies.end() && !s_CookieLess(name, domain, path, (*iter)->GetName(), (*iter)->GetDomain(), (*iter)->GetPath())) { _ASSERT( AStrEquiv(name, (*iter)->GetName(), PNocase()) ); _ASSERT( AStrEquiv(domain, (*iter)->GetDomain(), PNocase()) ); _ASSERT( path.compare((*iter)->GetPath()) == 0 ); return *iter; } return 0;}const CCgiCookie* CCgiCookies::Find(const string& name, const string& domain, const string& path) const{ return const_cast<CCgiCookies*>(this)->Find(name, domain, path);}CCgiCookie* CCgiCookies::Find(const string& name, TRange* range){ PNocase nocase_less; // find the first match TIter beg = m_Cookies.begin(); while (beg != m_Cookies.end() && nocase_less((*beg)->GetName(), name)) beg++; // get this first match only if ( !range ) { return (beg != m_Cookies.end() && !nocase_less(name, (*beg)->GetName())) ? *beg : 0; } // get the range of equal names TIter end = beg; while (end != m_Cookies.end() && !nocase_less(name, (*end)->GetName()))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -