cgictx.cpp
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:12k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: cgictx.cpp,v $
  4.  * PRODUCTION Revision 1000.1  2004/06/01 18:39:10  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.37
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /*  $Id: cgictx.cpp,v 1000.1 2004/06/01 18:39:10 gouriano Exp $
  10. * ===========================================================================
  11. *
  12. *                            PUBLIC DOMAIN NOTICE
  13. *               National Center for Biotechnology Information
  14. *
  15. *  This software/database is a "United States Government Work" under the
  16. *  terms of the United States Copyright Act.  It was written as part of
  17. *  the author's official duties as a United States Government employee and
  18. *  thus cannot be copyrighted.  This software/database is freely available
  19. *  to the public for use. The National Library of Medicine and the U.S.
  20. *  Government have not placed any restriction on its use or reproduction.
  21. *
  22. *  Although all reasonable efforts have been taken to ensure the accuracy
  23. *  and reliability of the software and data, the NLM and the U.S.
  24. *  Government do not and cannot warrant the performance or results that
  25. *  may be obtained by using this software or data. The NLM and the U.S.
  26. *  Government disclaim all warranties, express or implied, including
  27. *  warranties of performance, merchantability or fitness for any particular
  28. *  purpose.
  29. *
  30. *  Please cite the author in any work or product based on this material.
  31. *
  32. * ===========================================================================
  33. *
  34. * Author: Eugene Vasilchenko
  35. *
  36. * File Description:
  37. *   Definition CGI application class and its context class.
  38. *
  39. */
  40. #include <ncbi_pch.hpp>
  41. #include <corelib/ncbistd.hpp>
  42. #include <corelib/ncbireg.hpp>
  43. #include <cgi/ncbires.hpp>
  44. #include <cgi/cgictx.hpp>
  45. #include <cgi/cgiapp.hpp>
  46. #ifdef NCBI_OS_UNIX
  47. #  ifdef _AIX32 // version 3.2 *or higher*
  48. #    include <strings.h> // needed for bzero()
  49. #  endif
  50. #  include <sys/time.h>
  51. #  include <unistd.h> // needed for select() on some platforms
  52. #endif
  53. BEGIN_NCBI_SCOPE
  54. /////////////////////////////////////////////////////////////////////////////
  55. //  CCgiServerContext::
  56. //
  57. CCgiServerContext::~CCgiServerContext(void)
  58. {
  59.     return;
  60. }
  61. /////////////////////////////////////////////////////////////////////////////
  62. //  CCtxMsg::
  63. //
  64. CCtxMsg::~CCtxMsg(void)
  65. {
  66.     return;
  67. }
  68. /////////////////////////////////////////////////////////////////////////////
  69. //  CCtxMsgString::
  70. //
  71. string CCtxMsgString::sm_nl = "n";
  72. CCtxMsgString::~CCtxMsgString(void)
  73. {
  74.     return;
  75. }
  76. CNcbiOstream& CCtxMsgString::Write(CNcbiOstream& os) const
  77. {
  78.     return os << m_Message << sm_nl;
  79. }
  80. /////////////////////////////////////////////////////////////////////////////
  81. //  CCgiContext::
  82. //
  83. CCgiContext::CCgiContext(CCgiApplication&        app,
  84.                          const CNcbiArguments*   args,
  85.                          const CNcbiEnvironment* env,
  86.                          CNcbiIstream*           inp,
  87.                          CNcbiOstream*           out,
  88.                          int                     ifd,
  89.                          int                     ofd,
  90.                          size_t                  errbuf_size,
  91.                          CCgiRequest::TFlags     flags)
  92.     : m_App(app),
  93.       m_Request(0),
  94.       m_Response(out, ofd)
  95. {
  96.     try {
  97.         m_Request.reset(new CCgiRequest(args ? args : &app.GetArguments(),
  98.                                         env  ? env  : &app.GetEnvironment(),
  99.                                         inp, flags, ifd, errbuf_size));
  100.     }
  101.     catch (exception& _DEBUG_ARG(e)) {
  102.         _TRACE("CCgiContext::CCgiContext: " << e.what());
  103.         PutMsg("Bad request");
  104.         char buf[1];
  105.         CNcbiIstrstream dummy(buf, 0);
  106.         m_Request.reset(new CCgiRequest
  107.                         (args, env, &dummy, CCgiRequest::fIgnoreQueryString,
  108.                          ifd, errbuf_size));
  109.     }
  110. }
  111. CCgiContext::~CCgiContext(void)
  112. {
  113.     return;
  114. }
  115. const CNcbiRegistry& CCgiContext::GetConfig(void) const
  116. {
  117.     return m_App.GetConfig();
  118. }
  119. CNcbiRegistry& CCgiContext::GetConfig(void)
  120. {
  121.     return m_App.GetConfig();
  122. }
  123. const CNcbiResource& CCgiContext::GetResource(void) const
  124. {
  125.     return m_App.GetResource();
  126. }
  127. CNcbiResource& CCgiContext::GetResource(void)
  128. {
  129.     return m_App.GetResource();
  130. }
  131. CCgiServerContext& CCgiContext::x_GetServerContext(void) const
  132. {
  133.     CCgiServerContext* context = m_ServerContext.get();
  134.     if ( !context ) {
  135.         context = m_App.LoadServerContext(const_cast<CCgiContext&>(*this));
  136.         if ( !context ) {
  137.             ERR_POST("CCgiContext::GetServerContext: no server context set");
  138.             throw runtime_error("no server context set");
  139.         }
  140.         const_cast<CCgiContext&>(*this).m_ServerContext.reset(context);
  141.     }
  142.     return *context;
  143. }
  144. const CCgiEntry& CCgiContext::GetRequestValue(const string& name,
  145.                                               bool*         is_found)
  146.     const
  147. {
  148.     pair<TCgiEntriesCI, TCgiEntriesCI> range =
  149.         GetRequest().GetEntries().equal_range(name);
  150.     if (range.second == range.first) {
  151.         if ( is_found ) {
  152.             *is_found = false;
  153.         }
  154.         static const CCgiEntry kEmptyCgiEntry(kEmptyStr);
  155.         return kEmptyCgiEntry;
  156.     }
  157.     if ( is_found ) {
  158.         *is_found = true;
  159.     }
  160.     const CCgiEntry& value = range.first->second;
  161.     while (++range.first != range.second) {
  162.         if (range.first->second != value) {
  163.             THROW1_TRACE(runtime_error,
  164.                          "duplicated entries in request with name: " +
  165.                          name + ": " + value.GetValue() + "!=" +
  166.                          range.first->second.GetValue());
  167.         }
  168.     }
  169.     return value;
  170. }
  171. void CCgiContext::RemoveRequestValues(const string& name)
  172. {
  173.     GetRequest().GetEntries().erase(name);
  174. }
  175. void CCgiContext::AddRequestValue(const string& name, const CCgiEntry& value)
  176. {
  177.     GetRequest().GetEntries().insert(TCgiEntries::value_type(name, value));
  178. }
  179. void CCgiContext::ReplaceRequestValue(const string&    name,
  180.                                       const CCgiEntry& value)
  181. {
  182.     RemoveRequestValues(name);
  183.     AddRequestValue(name, value);
  184. }
  185. const string& CCgiContext::GetSelfURL(void) const
  186. {
  187.     if ( !m_SelfURL.empty() )
  188.         return m_SelfURL;
  189.     // Compose self URL
  190.     m_SelfURL = "http://";
  191.     m_SelfURL += GetRequest().GetProperty(eCgi_ServerName);
  192.     m_SelfURL += ':';
  193.     m_SelfURL += GetRequest().GetProperty(eCgi_ServerPort);
  194.     // (workaround a bug in the "www.ncbi" proxy -- replace adjacent '//')
  195.     m_SelfURL += NStr::Replace
  196.         (GetRequest().GetProperty(eCgi_ScriptName), "//", "/");
  197.     return m_SelfURL;
  198. }
  199. CCgiContext::TStreamStatus
  200. CCgiContext::GetStreamStatus(STimeout* timeout) const
  201. {
  202. #if defined(NCBI_OS_UNIX)  &&  !defined(NCBI_COMPILER_MW_MSL)
  203.     int ifd  = m_Request->GetInputFD();
  204.     int ofd  = m_Response.GetOutputFD();
  205.     int nfds = max(ifd, ofd) + 1;
  206.     if (nfds == 0) {
  207.         return 0;
  208.     }
  209.     fd_set readfds, writefds;
  210.     FD_ZERO(&readfds);
  211.     if (ifd >= 0) {
  212.         FD_SET(ifd, &readfds);
  213.     }
  214.     FD_ZERO(&writefds);
  215.     if (ofd >= 0) {
  216.         FD_SET(ofd, &writefds);
  217.     }
  218.     struct timeval tv;
  219.     tv.tv_sec  = timeout->sec;
  220.     tv.tv_usec = timeout->usec;
  221.     ::select(nfds, &readfds, &writefds, NULL, &tv);
  222.     TStreamStatus result = 0;
  223.     if (ifd >= 0  &&  FD_ISSET(ifd, &readfds)) {
  224.         result |= fInputReady;
  225.     }
  226.     if (ofd >= 0  &&  FD_ISSET(ofd, &writefds)) {
  227.         result |= fOutputReady;
  228.     }
  229.     return result;
  230. #else
  231.     return 0;
  232. #endif
  233. }
  234. END_NCBI_SCOPE
  235. /*
  236. * ===========================================================================
  237. * $Log: cgictx.cpp,v $
  238. * Revision 1000.1  2004/06/01 18:39:10  gouriano
  239. * PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.37
  240. *
  241. * Revision 1.37  2004/05/17 20:56:50  gorelenk
  242. * Added include of PCH ncbi_pch.hpp
  243. *
  244. * Revision 1.36  2004/05/11 12:43:55  kuznets
  245. * Changes to control HTTP parsing (CCgiRequest flags)
  246. *
  247. * Revision 1.35  2003/05/19 21:25:31  vakatov
  248. * In CCgiContext::ctor -- fixed invalid arg passage to CCgiRequest::ctor
  249. *
  250. * Revision 1.34  2003/04/16 21:48:19  vakatov
  251. * Slightly improved logging format, and some minor coding style fixes.
  252. *
  253. * Revision 1.33  2003/04/04 15:23:57  lavr
  254. * Slightly brushed; lines wrapped at 79th col
  255. *
  256. * Revision 1.32  2003/04/03 14:14:59  rsmith
  257. * combine pp symbols NCBI_COMPILER_METROWERKS & _MSL_USING_MW_C_HEADERS
  258. * into NCBI_COMPILER_MW_MSL
  259. *
  260. * Revision 1.31  2003/04/02 13:27:53  rsmith
  261. * GetStreamStatus not implemented on MacOSX w/Codewarrior using MSL headers.
  262. *
  263. * Revision 1.30  2003/03/11 19:17:31  kuznets
  264. * Improved error diagnostics in CCgiRequest
  265. *
  266. * Revision 1.29  2003/02/21 19:19:07  vakatov
  267. * CCgiContext::GetRequestValue() -- added optional arg "is_found"
  268. *
  269. * Revision 1.28  2003/02/16 05:30:27  vakatov
  270. * GetRequestValue() to return "const CCgiEntry&" rather than just "CCgiEntry"
  271. * to avoid some nasty surprises for earlier user code looking as:
  272. *    const string& s = GetRequestValue(...);
  273. * caused by 'premature' destruction of temporary CCgiEntry object (GCC 3.0.4).
  274. *
  275. * Revision 1.27  2002/07/10 18:40:44  ucko
  276. * Made CCgiEntry-based functions the only version; kept "Ex" names as
  277. * temporary synonyms, to go away in a few days.
  278. *
  279. * Revision 1.26  2002/07/03 20:24:31  ucko
  280. * Extend to support learning uploaded files' names; move CVS logs to end.
  281. *
  282. * Revision 1.25  2002/03/25 18:10:27  ucko
  283. * Include <unistd.h> on Unix; necessary for select on FreeBSD at least.
  284. *
  285. * Revision 1.24  2002/02/21 17:04:56  ucko
  286. * [AIX] Include <strings.h> before <sys/time.h> for bzero.
  287. *
  288. * Revision 1.23  2001/10/07 05:05:04  vakatov
  289. * [UNIX]  include <sys/time.h>
  290. *
  291. * Revision 1.22  2001/10/04 18:17:53  ucko
  292. * Accept additional query parameters for more flexible diagnostics.
  293. * Support checking the readiness of CGI input and output streams.
  294. *
  295. * Revision 1.21  2001/06/13 21:04:37  vakatov
  296. * Formal improvements and general beautifications of the CGI lib sources.
  297. *
  298. * Revision 1.20  2000/12/23 23:54:01  vakatov
  299. * TLMsg container to use AutoPtr instead of regular pointer
  300. *
  301. * Revision 1.19  2000/05/24 20:57:13  vasilche
  302. * Use new macro _DEBUG_ARG to avoid warning about unused argument.
  303. *
  304. * Revision 1.18  2000/01/20 17:54:15  vakatov
  305. * CCgiContext:: constructor to get "CNcbiArguments*" instead of raw argc/argv.
  306. * All virtual member function implementations moved away from the header.
  307. *
  308. * Revision 1.17  1999/12/23 17:16:18  golikov
  309. * CtxMsgs made not HTML lib depended
  310. *
  311. * Revision 1.16  1999/12/15 19:19:10  golikov
  312. * fixes
  313. *
  314. * Revision 1.15  1999/11/15 15:54:53  sandomir
  315. * Registry support moved from CCgiApplication to CNcbiApplication
  316. *
  317. * Revision 1.14  1999/10/21 16:10:53  vasilche
  318. * Fixed memory leak in CNcbiOstrstream::str()
  319. *
  320. * Revision 1.13  1999/10/01 14:21:40  golikov
  321. * Now messages in context are html nodes
  322. *
  323. * Revision 1.12  1999/09/03 21:32:28  vakatov
  324. * Move #include <algorithm> after the NCBI #include's for more
  325. * consistency and to suppress some bulky MSVC++ warnings.
  326. *
  327. * Revision 1.11  1999/07/15 19:05:17  sandomir
  328. * GetSelfURL(() added in Context
  329. *
  330. * Revision 1.10  1999/07/07 14:23:37  pubmed
  331. * minor changes for VC++
  332. *
  333. * Revision 1.9  1999/06/29 20:02:29  pubmed
  334. * many changes due to query interface changes
  335. *
  336. * Revision 1.8  1999/05/14 19:21:54  pubmed
  337. * myncbi - initial version; minor changes in CgiContext, history, query
  338. *
  339. * Revision 1.6  1999/05/06 20:33:43  pubmed
  340. * CNcbiResource -> CNcbiDbResource; utils from query; few more context methods
  341. *
  342. * Revision 1.5  1999/05/04 16:14:44  vasilche
  343. * Fixed problems with program environment.
  344. * Added class CNcbiEnvironment for cached access to C environment.
  345. *
  346. * Revision 1.4  1999/05/04 00:03:11  vakatov
  347. * Removed the redundant severity arg from macro ERR_POST()
  348. *
  349. * Revision 1.3  1999/04/30 19:21:02  vakatov
  350. * Added more details and more control on the diagnostics
  351. * See #ERR_POST, EDiagPostFlag, and ***DiagPostFlag()
  352. *
  353. * Revision 1.2  1999/04/28 16:54:41  vasilche
  354. * Implemented stream input processing for FastCGI applications.
  355. * Fixed POST request parsing
  356. *
  357. * Revision 1.1  1999/04/27 14:50:04  vasilche
  358. * Added FastCGI interface.
  359. * CNcbiContext renamed to CCgiContext.
  360. * ===========================================================================
  361. */