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

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ncbicgi.hpp,v $
  4.  * PRODUCTION Revision 1000.1  2003/11/18 15:42:41  gouriano
  5.  * PRODUCTION PRODUCTION: UPGRADED [ORIGINAL] Dev-tree R1.63
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. #ifndef NCBICGI__HPP
  10. #define NCBICGI__HPP
  11. /*  $Id: ncbicgi.hpp,v 1000.1 2003/11/18 15:42:41 gouriano Exp $
  12. * ===========================================================================
  13. *
  14. *                            PUBLIC DOMAIN NOTICE
  15. *               National Center for Biotechnology Information
  16. *
  17. *  This software/database is a "United States Government Work" under the
  18. *  terms of the United States Copyright Act.  It was written as part of
  19. *  the author's official duties as a United States Government employee and
  20. *  thus cannot be copyrighted.  This software/database is freely available
  21. *  to the public for use. The National Library of Medicine and the U.S.
  22. *  Government have not placed any restriction on its use or reproduction.
  23. *
  24. *  Although all reasonable efforts have been taken to ensure the accuracy
  25. *  and reliability of the software and data, the NLM and the U.S.
  26. *  Government do not and cannot warrant the performance or results that
  27. *  may be obtained by using this software or data. The NLM and the U.S.
  28. *  Government disclaim all warranties, express or implied, including
  29. *  warranties of performance, merchantability or fitness for any particular
  30. *  purpose.
  31. *
  32. *  Please cite the author in any work or product based on this material.
  33. *
  34. * ===========================================================================
  35. *
  36. * Author:  Denis Vakatov
  37. *
  38. * File Description:
  39. *   NCBI C++ CGI API:
  40. *      CCgiCookie    -- one CGI cookie
  41. *      CCgiCookies   -- set of CGI cookies
  42. *      CCgiRequest   -- full CGI request
  43. */
  44. #include <corelib/ncbistd.hpp>
  45. #include <corelib/ncbiobj.hpp>
  46. #include <list>
  47. #include <map>
  48. #include <set>
  49. #include <memory>
  50. #include <time.h>
  51. /** @addtogroup CGIReqRes
  52.  *
  53.  * @{
  54.  */
  55. #define HTTP_EOL "rn"
  56. BEGIN_NCBI_SCOPE
  57. class CTime;
  58. ///////////////////////////////////////////////////////
  59. //
  60. //  CCgiCookie::
  61. //
  62. // The CGI send-cookie class
  63. //
  64. class NCBI_XCGI_EXPORT CCgiCookie
  65. {
  66. public:
  67.     // Copy constructor
  68.     CCgiCookie(const CCgiCookie& cookie);
  69.     // Throw the "invalid_argument" if "name" or "value" have invalid format
  70.     //  - the "name" must not be empty; it must not contain '='
  71.     //  - "name", "value", "domain" -- must consist of printable ASCII
  72.     //    characters, and not: semicolons(;), commas(,), or space characters.
  73.     //  - "path" -- can have space characters.
  74.     CCgiCookie(const string& name, const string& value,
  75.                const string& domain = NcbiEmptyString,
  76.                const string& path   = NcbiEmptyString);
  77.     // The cookie name cannot be changed during its whole timelife
  78.     const string& GetName(void) const;
  79.     // Compose and write to output stream "os":
  80.     //   "Set-Cookie: name=value; expires=date; path=val_path; domain=dom_name;
  81.     //    securen"
  82.     // Here, only "name=value" is mandatory, and other parts are optional
  83.     CNcbiOstream& Write(CNcbiOstream& os) const;
  84.     // Reset everything(but name!) to default state like CCgiCookie(m_Name, "")
  85.     void Reset(void);
  86.     // Set all attribute values(but name!) to those from "cookie"
  87.     void CopyAttributes(const CCgiCookie& cookie);
  88.     // All SetXXX(const string&) methods beneath:
  89.     //  - set the property to "str" if "str" has valid format
  90.     //  - throw the "invalid_argument" if "str" has invalid format
  91.     void SetValue  (const string& str);
  92.     void SetDomain (const string& str);    // not spec'd by default
  93.     void SetPath   (const string& str);    // not spec'd by default
  94.     void SetExpDate(const tm& exp_date);   // GMT time (infinite if all zeros)
  95.     void SetExpTime(const CTime& exp_time);// GMT time (infinite if all zeros)
  96.     void SetSecure (bool secure);          // "false" by default
  97.     // All "const string& GetXXX(...)" methods beneath return reference
  98.     // to "NcbiEmptyString" if the requested attributre is not set
  99.     const string& GetValue  (void) const;
  100.     const string& GetDomain (void) const;
  101.     const string& GetPath   (void) const;
  102.     // Day, dd-Mon-yyyy hh:mm:ss GMT  (return empty string if not set)
  103.     string        GetExpDate(void) const;
  104.     // If exp.date is not set then return "false" and dont assign "*exp_date"
  105.     bool GetExpDate(tm* exp_date) const;
  106.     bool GetSecure(void)          const;
  107.     // Compare two cookies
  108.     bool operator< (const CCgiCookie& cookie) const;
  109.     // Predicate for the cookie comparison
  110.     typedef const CCgiCookie* TCPtr;
  111.     struct PLessCPtr {
  112.         bool operator() (const TCPtr& c1, const TCPtr& c2) const {
  113.             return (*c1 < *c2);
  114.         }
  115.     };
  116. private:
  117.     string m_Name;
  118.     string m_Value;
  119.     string m_Domain;
  120.     string m_Path;
  121.     tm     m_Expires;  // GMT time zone
  122.     bool   m_Secure;
  123.     static void x_CheckField(const string& str, const char* banned_symbols);
  124.     static bool x_GetString(string* str, const string& val);
  125.     // prohibit default assignment
  126.     CCgiCookie& operator= (const CCgiCookie&);
  127. };  // CCgiCookie
  128. /* @} */
  129. inline CNcbiOstream& operator<< (CNcbiOstream& os, const CCgiCookie& cookie)
  130. {
  131.     return cookie.Write(os);
  132. }
  133. /** @addtogroup CGIReqRes
  134.  *
  135.  * @{
  136.  */
  137. ///////////////////////////////////////////////////////
  138. //
  139. //  CCgiCookies::
  140. //
  141. // Set of CGI send-cookies
  142. //
  143. //  The cookie is uniquely identified by {name, domain, path}.
  144. //  "name" is mandatory and non-empty;  "domain" and "path" are optional.
  145. //  "name" and "domain" are not case-sensitive;  "path" is case-sensitive.
  146. //
  147. class NCBI_XCGI_EXPORT CCgiCookies
  148. {
  149. public:
  150.     typedef set<CCgiCookie*, CCgiCookie::PLessCPtr>  TSet;
  151.     typedef TSet::iterator         TIter;
  152.     typedef TSet::const_iterator   TCIter;
  153.     typedef pair<TIter,  TIter>    TRange;
  154.     typedef pair<TCIter, TCIter>   TCRange;
  155.     // Empty set of cookies
  156.     CCgiCookies(void);
  157.     // Format of the string:  "name1=value1; name2=value2; ..."
  158.     CCgiCookies(const string& str);
  159.     // Destructor
  160.     ~CCgiCookies(void);
  161.     // Return "true" if this set contains no cookies
  162.     bool Empty(void) const;
  163.     // All Add() functions:
  164.     // if the added cookie has the same {name, domain, path} as an already
  165.     // existing one then the new cookie will override the old one
  166.     CCgiCookie* Add(const string& name, const string& value,
  167.                     const string& domain = NcbiEmptyString,
  168.                     const string& path   = NcbiEmptyString);
  169.     CCgiCookie* Add(const CCgiCookie& cookie);  // add a copy of "cookie"
  170.     void Add(const CCgiCookies& cookies);  // update by a set of cookies
  171.     void Add(const string& str); // "name1=value1; name2=value2; ..."
  172.     // Return NULL if cannot find this exact cookie
  173.     CCgiCookie*       Find(const string& name,
  174.                            const string& domain, const string& path);
  175.     const CCgiCookie* Find(const string& name,
  176.                            const string& domain, const string& path) const;
  177.     // Return the first matched cookie with name "name", or NULL if
  178.     // there is no such cookie(s).
  179.     // Also, if "range" is non-NULL then assign its "first" and
  180.     // "second" fields to the beginning and the end of the range
  181.     // of cookies matching the name "name".
  182.     // NOTE:  if there is a cookie with empty domain and path then
  183.     //        this cookie is guaranteed to be returned.
  184.     CCgiCookie*       Find(const string& name, TRange*  range=0);
  185.     const CCgiCookie* Find(const string& name, TCRange* range=0) const;
  186.     // Remove "cookie" from this set;  deallocate it if "destroy" is true
  187.     // Return "false" if can not find "cookie" in this set
  188.     bool Remove(CCgiCookie* cookie, bool destroy=true);
  189.     // Remove (and destroy if "destroy" is true) all cookies belonging
  190.     // to range "range".  Return # of found and removed cookies.
  191.     size_t Remove(TRange& range, bool destroy=true);
  192.     // Remove (and destroy if "destroy" is true) all cookies with the
  193.     // given "name".  Return # of found and removed cookies.
  194.     size_t Remove(const string& name, bool destroy=true);
  195.     // Remove all stored cookies
  196.     void Clear(void);
  197.     // Printout all cookies into the stream "os" (see also CCgiCookie::Write())
  198.     CNcbiOstream& Write(CNcbiOstream& os) const;
  199. private:
  200.     TSet m_Cookies;
  201.     // prohibit default initialization and assignment
  202.     CCgiCookies(const CCgiCookies&);
  203.     CCgiCookies& operator= (const CCgiCookies&);
  204. };  // CCgiCookies
  205. /* @} */
  206. inline CNcbiOstream& operator<< (CNcbiOstream& os, const CCgiCookies& cookies)
  207. {
  208.     return cookies.Write(os);
  209. }
  210. /** @addtogroup CGIReqRes
  211.  *
  212.  * @{
  213.  */
  214. ///////////////////////////////////////////////////////
  215. //
  216. //  CCgiRequest::
  217. //
  218. // The CGI request class
  219. //
  220. // Set of "standard" HTTP request properties
  221. enum ECgiProp {
  222.     // server properties
  223.     eCgi_ServerSoftware = 0,
  224.     eCgi_ServerName,
  225.     eCgi_GatewayInterface,
  226.     eCgi_ServerProtocol,
  227.     eCgi_ServerPort,        // see also "GetServerPort()"
  228.     // client properties
  229.     eCgi_RemoteHost,
  230.     eCgi_RemoteAddr,        // see also "GetRemoteAddr()"
  231.     // client data properties
  232.     eCgi_ContentType,
  233.     eCgi_ContentLength,     // see also "GetContentLength()"
  234.     // request properties
  235.     eCgi_RequestMethod,
  236.     eCgi_PathInfo,
  237.     eCgi_PathTranslated,
  238.     eCgi_ScriptName,
  239.     eCgi_QueryString,
  240.     // authentication info
  241.     eCgi_AuthType,
  242.     eCgi_RemoteUser,
  243.     eCgi_RemoteIdent,
  244.     // semi-standard properties(from HTTP header)
  245.     eCgi_HttpAccept,
  246.     eCgi_HttpCookie,
  247.     eCgi_HttpIfModifiedSince,
  248.     eCgi_HttpReferer,
  249.     eCgi_HttpUserAgent,
  250.     // # of CCgiRequest-supported standard properties
  251.     // for internal use only!
  252.     eCgi_NProperties
  253. };  // ECgiProp
  254. class NCBI_XCGI_EXPORT CCgiEntry // copy-on-write semantics
  255. {
  256. private:
  257.     struct SData : public CObject
  258.     {
  259.         SData(const string& value, const string& filename,
  260.               unsigned int position)
  261.             : m_Value(value), m_Filename(filename), m_Position(position) { }
  262.         SData(const SData& data)
  263.             : m_Value(data.m_Value), m_Filename(data.m_Filename),
  264.             m_Position(data.m_Position){ }
  265.         string       m_Value, m_Filename;
  266.         unsigned int m_Position;
  267.     };
  268. public:
  269.     CCgiEntry(const string& value, const string& filename = kEmptyStr,
  270.               unsigned int position = 0)
  271.         : m_Data(new SData(value, filename, position)) { }
  272.     CCgiEntry(const char* value, const string& filename = kEmptyStr,
  273.               unsigned int position = 0)
  274.         : m_Data(new SData(value, filename, position)) { }
  275.     CCgiEntry(const CCgiEntry& e) : m_Data(e.m_Data) { }
  276.     const string& GetValue() const
  277.         { return m_Data->m_Value; }
  278.     string&       SetValue()
  279.         { x_ForceUnique(); return m_Data->m_Value; }
  280.     void          SetValue(const string& v)
  281.         { x_ForceUnique(); m_Data->m_Value = v; }
  282.     const string& GetFilename() const
  283.         { return m_Data->m_Filename; }
  284.     string&       SetFilename()
  285.         { x_ForceUnique(); return m_Data->m_Filename; }
  286.     void          SetFilename(const string& f)
  287.         { x_ForceUnique(); m_Data->m_Filename = f; }
  288.     // CGI parameter number -- automatic image name parameter is #0,
  289.     // explicit parameters start at #1
  290.     unsigned int  GetPosition() const
  291.         { return m_Data->m_Position; }
  292.     unsigned int& SetPosition()
  293.         { x_ForceUnique(); return m_Data->m_Position; }
  294.     void          SetPosition(int p)
  295.         { x_ForceUnique(); m_Data->m_Position = p; }
  296.     operator const string&() const     { return GetValue(); }
  297.     operator       string&()           { return SetValue(); }
  298.     // commonly-requested string:: operations...
  299.     SIZE_TYPE size() const             { return GetValue().size(); }
  300.     bool empty() const                 { return GetValue().empty(); }
  301.     const char* c_str() const          { return GetValue().c_str(); }
  302.     int compare(const string& s) const { return GetValue().compare(s); }
  303.     int compare(const char* s) const   { return GetValue().compare(s); }
  304.     string substr(SIZE_TYPE i = 0, SIZE_TYPE n = NPOS) const
  305.         { return GetValue().substr(i, n); }
  306.     SIZE_TYPE find(const char* s, SIZE_TYPE pos = 0) const
  307.         { return GetValue().find(s, pos); }
  308.     SIZE_TYPE find(const string& s, SIZE_TYPE pos = 0) const
  309.         { return GetValue().find(s, pos); }
  310.     SIZE_TYPE find(char c, SIZE_TYPE pos = 0) const
  311.         { return GetValue().find(c, pos); }
  312.     SIZE_TYPE find_first_of(const string& s, SIZE_TYPE pos = 0) const
  313.         { return GetValue().find_first_of(s, pos); }
  314.     SIZE_TYPE find_first_of(const char* s, SIZE_TYPE pos = 0) const
  315.         { return GetValue().find_first_of(s, pos); }
  316. private:
  317.     void x_ForceUnique()
  318.         { if (!m_Data->ReferencedOnlyOnce()) { m_Data = new SData(*m_Data); } }
  319.     CRef<SData> m_Data;
  320. };
  321. /* @} */
  322. inline
  323. bool operator ==(const CCgiEntry& e1, const CCgiEntry& e2)
  324. {
  325.     return (e1.GetValue() == e2.GetValue() 
  326.             &&  e1.GetFilename() == e2.GetFilename());
  327. }
  328. inline
  329. bool operator !=(const CCgiEntry& e1, const CCgiEntry& e2)
  330. {
  331.     return !(e1 == e2);
  332. }
  333. inline
  334. bool operator ==(const CCgiEntry& e, const string& s)
  335. {
  336.     return e.GetValue() == s;
  337. }
  338. inline
  339. bool operator ==(const CCgiEntry& e, const char* s)
  340. {
  341.     return e.GetValue() == s;
  342. }
  343. inline
  344. string operator +(const CCgiEntry& e, const string& s)
  345. {
  346.     return e.GetValue() + s;
  347. }
  348. inline
  349. string operator +(const string& s, const CCgiEntry& e)
  350. {
  351.     return s + e.GetValue();
  352. }
  353. inline
  354. CNcbiOstream& operator <<(CNcbiOstream& o, const CCgiEntry& e)
  355. {
  356.     return o << e.GetValue();
  357.     // filename omitted in case anything depends on just getting the value
  358. }
  359. /** @addtogroup CGIReqRes
  360.  *
  361.  * @{
  362.  */
  363. // Typedefs
  364. typedef map<string, string>         TCgiProperties;
  365. typedef multimap<string, CCgiEntry> TCgiEntries;
  366. typedef TCgiEntries::iterator       TCgiEntriesI;
  367. typedef TCgiEntries::const_iterator TCgiEntriesCI;
  368. typedef list<string>                TCgiIndexes;
  369. // Forward class declarations
  370. class CNcbiArguments;
  371. class CNcbiEnvironment;
  372. //
  373. class NCBI_XCGI_EXPORT CCgiRequest
  374. {
  375. public:
  376.     // Startup initialization:
  377.     //   retrieve request's properties and cookies from environment;
  378.     //   retrieve request's entries from "$QUERY_STRING".
  379.     // If "$REQUEST_METHOD" == "POST" and "$CONTENT_TYPE" is empty or either
  380.     // "application/x-www-form-urlencoded" or "multipart/form-data",
  381.     // and "fDoNotParseContent" flag is not set,
  382.     // then retrieve and parse entries from the input stream "istr".
  383.     // If "$REQUEST_METHOD" is undefined then try to retrieve the request's
  384.     // entries from the 1st cmd.-line argument, and do not use "$QUERY_STRING"
  385.     // and "istr" at all.
  386.     typedef int TFlags;
  387.     enum Flags {
  388.         // do not handle indexes as regular FORM entries with empty value
  389.         fIndexesNotEntries  = 0x1,
  390.         // do not parse $QUERY_STRING
  391.         fIgnoreQueryString  = 0x2,
  392.         // own the passed "env" (and destroy it in the destructor)
  393.         fOwnEnvironment     = 0x4,
  394.         // do not automatically parse the request's content body (from "istr")
  395.         fDoNotParseContent  = 0x8
  396.     };
  397.     CCgiRequest(const         CNcbiArguments*   args = 0,
  398.                 const         CNcbiEnvironment* env  = 0,
  399.                 CNcbiIstream* istr  = 0 /*NcbiCin*/,
  400.                 TFlags        flags = 0,
  401.                 int           ifd   = -1,
  402.                 size_t        errbuf_size = 256);
  403.     // args := CNcbiArguments(argc,argv), env := CNcbiEnvironment(envp)
  404.     CCgiRequest(int                argc,
  405.                 const char* const* argv,
  406.                 const char* const* envp  = 0,
  407.                 CNcbiIstream*      istr  = 0,
  408.                 TFlags             flags = 0,
  409.                 int                ifd   = -1,
  410.                 size_t             errbuf_size = 256);
  411.     // Destructor
  412.     ~CCgiRequest(void);
  413.     // Get name(not value!) of a "standard" property
  414.     static const string& GetPropertyName(ECgiProp prop);
  415.     // Get value of a "standard" property (return empty string if not defined)
  416.     const string& GetProperty(ECgiProp prop) const;
  417.     // Get value of a random client property;  if "http" is TRUE then add
  418.     // prefix "HTTP_" to the property name.
  419.     // NOTE:  usually, the value is extracted from the environment variable
  420.     //        named "$[HTTP]_<key>". Be advised, however, that in the case of
  421.     //        FastCGI application, the set (and values) of env.variables change
  422.     //        from request to request, and they differ from those returned
  423.     //        by CNcbiApplication::GetEnvironment()!
  424.     const string& GetRandomProperty(const string& key, bool http = true) const;
  425.     // Get content length using value of the property 'eCgi_ContentLength'.
  426.     // Return "kContentLengthUnknown" if Content-Length header is missing.
  427.     static const size_t kContentLengthUnknown;
  428.     size_t GetContentLength(void) const;
  429.     // Retrieve the request cookies
  430.     const CCgiCookies& GetCookies(void) const;
  431.     CCgiCookies& GetCookies(void);
  432.     // Get a set of entries(decoded) received from the client.
  433.     // Also includes "indexes" if "indexes_as_entries" in the
  434.     // constructor was "true"(default).
  435.     const TCgiEntries& GetEntries(void) const;
  436.     TCgiEntries& GetEntries(void);
  437.     // Get entry value by name
  438.     // NOTE:  There can be more than one entry with the same name;
  439.     //        only one of these entry will be returned.
  440.     // To get all matches, use GetEntries() and "multimap::" member functions.
  441.     const CCgiEntry& GetEntry(const string& name, bool* is_found = 0) const;
  442.     
  443.     // Get a set of indexes(decoded) received from the client.
  444.     // It will always be empty if "indexes_as_entries" in the constructor
  445.     // was "true"(default).
  446.     const TCgiIndexes& GetIndexes(void) const;
  447.     TCgiIndexes& GetIndexes(void);
  448.     // Return pointer to the input stream.
  449.     // Return NULL if the input stream is absent, or if it has been
  450.     // automagically read and parsed already (the "POST" method, and empty or
  451.     // "application/x-www-form-urlencoded" or "multipart/form-data" type,
  452.     // and "fDoNotParseContent" flag was not passed to the constructor).
  453.     CNcbiIstream* GetInputStream(void) const;
  454.     // Returns file descriptor of input stream, or -1 if unavailable.
  455.     int           GetInputFD(void) const;
  456.     // Set input stream to "is".
  457.     // If "own" is set to TRUE then this stream will be destroyed
  458.     // as soon as SetInputStream() gets called with another stream pointer.
  459.     // NOTE: SetInputStream(0) will be called in ::~CCgiRequest().
  460.     void SetInputStream(CNcbiIstream* is, bool own = false, int fd = -1);
  461.     // Decode the URL-encoded(FORM or ISINDEX) string "str" into a set of
  462.     // entries <"name", "value"> and add them to the "entries" set.
  463.     // The new entries are added without overriding the original ones, even
  464.     // if they have the same names.
  465.     // FORM    format:  "name1=value1&.....", ('=' and 'value' are optional)
  466.     // ISINDEX format:  "val1+val2+val3+....."
  467.     // If the "str" is in ISINDEX format then the entry "value" will be empty.
  468.     // On success, return zero;  otherwise return location(1-based) of error
  469.     static SIZE_TYPE ParseEntries(const string& str, TCgiEntries& entries);
  470.     // Decode the URL-encoded string "str" into a set of ISINDEX-like entries
  471.     // and add them to the "indexes" set
  472.     // On success, return zero, otherwise return location(1-based) of error
  473.     static SIZE_TYPE ParseIndexes(const string& str, TCgiIndexes& indexes);
  474. private:
  475.     // set of environment variables
  476.     const CNcbiEnvironment*    m_Env;
  477.     auto_ptr<CNcbiEnvironment> m_OwnEnv;
  478.     // set of the request FORM-like entries(already retrieved; cached)
  479.     TCgiEntries m_Entries;
  480.     // set of the request ISINDEX-like indexes(already retrieved; cached)
  481.     TCgiIndexes m_Indexes;
  482.     // set of the request cookies(already retrieved; cached)
  483.     CCgiCookies m_Cookies;
  484.     // input stream
  485.     CNcbiIstream* m_Input; 
  486.     // input file descriptor, if available.
  487.     int           m_InputFD;
  488.     bool          m_OwnInput;
  489.     // Request initialization error buffer size;
  490.     // when initialization code hits unexpected EOF it will try to 
  491.     // add diagnostics and print out accumulated request buffer 
  492.     // 0 in this variable means no buffer diagnostics
  493.     size_t        m_ErrBufSize;
  494.     // the real constructor code
  495.     void x_Init(const CNcbiArguments*   args,
  496.                 const CNcbiEnvironment* env,
  497.                 CNcbiIstream*           istr,
  498.                 TFlags                  flags,
  499.                 int                     ifd);
  500.     // retrieve(and cache) a property of given name
  501.     const string& x_GetPropertyByName(const string& name) const;
  502.     // prohibit default initialization and assignment
  503.     CCgiRequest(const CCgiRequest&);
  504.     CCgiRequest& operator= (const CCgiRequest&);
  505. };  // CCgiRequest
  506. // URL encode flags
  507. enum EUrlEncode {
  508.     eUrlEncode_SkipMarkChars,
  509.     eUrlEncode_ProcessMarkChars
  510. };
  511. // Decode the URL-encoded string "str";  return the result of decoding
  512. // If "str" format is invalid then throw CParseException
  513. NCBI_XCGI_EXPORT
  514. extern string URL_DecodeString(const string& str);
  515. // URL-encode a string "str" to the "x-www-form-urlencoded" form;
  516. // return the result of encoding. If 
  517. NCBI_XCGI_EXPORT
  518. extern string URL_EncodeString
  519.     (const      string& str,
  520.      EUrlEncode encode_mark_chars = eUrlEncode_SkipMarkChars
  521.      );
  522. /* @} */
  523. /////////////////////////////////////////////////////////////////////////////
  524. /////////////////////////////////////////////////////////////////////////////
  525. //  IMPLEMENTATION of INLINE functions
  526. /////////////////////////////////////////////////////////////////////////////
  527. ///////////////////////////////////////////////////////
  528. //  CCgiCookie::
  529. //
  530. // CCgiCookie::SetXXX()
  531. inline void CCgiCookie::SetValue(const string& str) {
  532.     x_CheckField(str, " ;");
  533.     m_Value = str;
  534. }
  535. inline void CCgiCookie::SetDomain(const string& str) {
  536.     x_CheckField(str, " ;");
  537.     m_Domain = str;
  538. }
  539. inline void CCgiCookie::SetPath(const string& str) {
  540.     x_CheckField(str, ";,");
  541.     m_Path = str;
  542. }
  543. inline void CCgiCookie::SetExpDate(const tm& exp_date) {
  544.     m_Expires = exp_date;
  545. }
  546. inline void CCgiCookie::SetSecure(bool secure) {
  547.     m_Secure = secure;
  548. }
  549. // CCgiCookie::GetXXX()
  550. inline const string& CCgiCookie::GetName(void) const {
  551.     return m_Name;
  552. }
  553. inline const string& CCgiCookie::GetValue(void) const {
  554.     return m_Value;
  555. }
  556. inline const string& CCgiCookie::GetDomain(void) const {
  557.     return m_Domain;
  558. }
  559. inline const string& CCgiCookie::GetPath(void) const {
  560.     return m_Path;
  561. }
  562. inline bool CCgiCookie::GetSecure(void) const {
  563.     return m_Secure;
  564. }
  565. ///////////////////////////////////////////////////////
  566. //  CCgiCookies::
  567. //
  568. inline CCgiCookies::CCgiCookies(void)
  569.     : m_Cookies()
  570. {
  571.     return;
  572. }
  573. inline CCgiCookies::CCgiCookies(const string& str)
  574.     : m_Cookies()
  575. {
  576.     Add(str);
  577. }
  578. inline bool CCgiCookies::Empty(void) const
  579. {
  580.     return m_Cookies.empty();
  581. }
  582. inline size_t CCgiCookies::Remove(const string& name, bool destroy)
  583. {
  584.     TRange range;
  585.     return Find(name, &range) ? Remove(range, destroy) : 0;
  586. }
  587. inline CCgiCookies::~CCgiCookies(void)
  588. {
  589.     Clear();
  590. }
  591. ///////////////////////////////////////////////////////
  592. //  CCgiRequest::
  593. //
  594. inline const CCgiCookies& CCgiRequest::GetCookies(void) const {
  595.     return m_Cookies;
  596. }
  597. inline CCgiCookies& CCgiRequest::GetCookies(void) {
  598.     return m_Cookies;
  599. }
  600. inline const TCgiEntries& CCgiRequest::GetEntries(void) const {
  601.     return m_Entries;
  602. }
  603. inline TCgiEntries& CCgiRequest::GetEntries(void) {
  604.     return m_Entries;
  605. }
  606. inline TCgiIndexes& CCgiRequest::GetIndexes(void) {
  607.     return m_Indexes;
  608. }
  609. inline const TCgiIndexes& CCgiRequest::GetIndexes(void) const {
  610.     return m_Indexes;
  611. }
  612. inline CNcbiIstream* CCgiRequest::GetInputStream(void) const {
  613.     return m_Input;
  614. }
  615. inline int CCgiRequest::GetInputFD(void) const {
  616.     return m_InputFD;
  617. }
  618. END_NCBI_SCOPE
  619. /*
  620. * ===========================================================================
  621. * $Log: ncbicgi.hpp,v $
  622. * Revision 1000.1  2003/11/18 15:42:41  gouriano
  623. * PRODUCTION: UPGRADED [ORIGINAL] Dev-tree R1.63
  624. *
  625. * Revision 1.63  2003/11/05 18:40:55  dicuccio
  626. * Added export specifiers
  627. *
  628. * Revision 1.62  2003/07/08 19:03:59  ivanov
  629. * Added optional parameter to the URL_Encode() to enable mark charactres encoding
  630. *
  631. * Revision 1.61  2003/04/16 21:48:17  vakatov
  632. * Slightly improved logging format, and some minor coding style fixes.
  633. *
  634. * Revision 1.60  2003/04/10 19:01:42  siyan
  635. * Added doxygen support
  636. *
  637. * Revision 1.59  2003/03/11 19:17:10  kuznets
  638. * Improved error diagnostics in CCgiRequest
  639. *
  640. * Revision 1.58  2003/02/19 17:50:30  kuznets
  641. * Added function AddExpTime to CCgiCookie class
  642. *
  643. * Revision 1.57  2002/09/17 19:57:35  ucko
  644. * Add position field to CGI entries; minor reformatting.
  645. *
  646. * Revision 1.56  2002/07/17 17:04:07  ucko
  647. * Drop no longer necessary ...Ex names; add more wrappers to CCgiEntry.
  648. *
  649. * Revision 1.55  2002/07/10 18:39:12  ucko
  650. * Tweaked CCgiEntry to allow for more efficient copying on systems
  651. * without efficient string copying.
  652. * Made CCgiEntry-based functions the only version; kept "Ex" names as
  653. * temporary synonyms, to go away in a few days.
  654. * Added more CCgiEntry operations to make the above change relatively
  655. * transparent.
  656. *
  657. * Revision 1.54  2002/07/05 07:03:29  vakatov
  658. * CCgiEntry::  added another constructor (for WorkShop)
  659. *
  660. * Revision 1.53  2002/07/03 20:24:30  ucko
  661. * Extend to support learning uploaded files' names; move CVS logs to end.
  662. *
  663. * Revision 1.52  2002/01/10 23:39:28  vakatov
  664. * Cosmetics
  665. *
  666. * Revision 1.51  2001/10/04 18:17:51  ucko
  667. * Accept additional query parameters for more flexible diagnostics.
  668. * Support checking the readiness of CGI input and output streams.
  669. *
  670. * Revision 1.50  2001/06/19 20:08:29  vakatov
  671. * CCgiRequest::{Set,Get}InputStream()  -- to provide safe access to the
  672. * requests' content body
  673. *
  674. * Revision 1.49  2001/06/13 21:04:35  vakatov
  675. * Formal improvements and general beautifications of the CGI lib sources.
  676. *
  677. * Revision 1.48  2001/05/17 14:49:25  lavr
  678. * Typos corrected
  679. *
  680. * Revision 1.47  2001/02/02 20:55:11  vakatov
  681. * CCgiRequest::GetEntry() -- "const"
  682. *
  683. * Revision 1.46  2001/01/30 23:17:30  vakatov
  684. * + CCgiRequest::GetEntry()
  685. *
  686. * Revision 1.45  2000/11/01 20:34:04  vasilche
  687. * Added HTTP_EOL string macro.
  688. *
  689. * Revision 1.44  2000/05/01 17:04:31  vasilche
  690. * MSVC doesn't allow content initialization in class body.
  691. *
  692. * Revision 1.43  2000/05/01 16:58:12  vasilche
  693. * Allow missing Content-Length and Content-Type headers.
  694. *
  695. * Revision 1.42  2000/02/01 22:19:53  vakatov
  696. * CCgiRequest::GetRandomProperty() -- allow to retrieve value of
  697. * properties whose names are not prefixed by "HTTP_" (optional).
  698. * Get rid of the aux.methods GetServerPort() and GetRemoteAddr() which
  699. * are obviously not widely used (but add to the volume of API).
  700. *
  701. * Revision 1.41  2000/01/20 17:52:05  vakatov
  702. * Two CCgiRequest:: constructors:  one using raw "argc", "argv", "envp",
  703. * and another using auxiliary classes "CNcbiArguments" and "CNcbiEnvironment".
  704. * + constructor flag CCgiRequest::fOwnEnvironment to take ownership over
  705. * the passed "CNcbiEnvironment" object.
  706. *
  707. * Revision 1.40  1999/12/30 22:11:59  vakatov
  708. * Fixed and added comments.
  709. * CCgiCookie::GetExpDate() -- use a more standard time string format.
  710. *
  711. * Revision 1.39  1999/11/02 20:35:38  vakatov
  712. * Redesigned of CCgiCookie and CCgiCookies to make them closer to the
  713. * cookie standard, smarter, and easier in use
  714. *
  715. * Revision 1.38  1999/09/03 21:26:44  vakatov
  716. * + #include <memory>
  717. *
  718. * Revision 1.37  1999/06/21 16:04:15  vakatov
  719. * CCgiRequest::CCgiRequest() -- the last(optional) arg is of type
  720. * "TFlags" rather than the former "bool"
  721. *
  722. * Revision 1.36  1999/05/11 03:11:46  vakatov
  723. * Moved the CGI API(along with the relevant tests) from "corelib/" to "cgi/"
  724. *
  725. * Revision 1.35  1999/05/04 16:14:04  vasilche
  726. * Fixed problems with program environment.
  727. * Added class CNcbiEnvironment for cached access to C environment.
  728. *
  729. * Revision 1.34  1999/04/14 19:52:20  vakatov
  730. * + <time.h>
  731. *
  732. * Revision 1.33  1999/03/08 22:42:49  vakatov
  733. * Added "string CCgiCookie::GetValue(void)"
  734. *
  735. * Revision 1.32  1999/01/14 21:25:14  vasilche
  736. * Changed CPageList to work via form image input elements.
  737. *
  738. * Revision 1.31  1999/01/07 21:15:19  vakatov
  739. * Changed prototypes for URL_DecodeString() and URL_EncodeString()
  740. *
  741. * Revision 1.30  1999/01/07 20:06:03  vakatov
  742. * + URL_DecodeString()
  743. * + URL_EncodeString()
  744. *
  745. * Revision 1.29  1998/12/28 17:56:25  vakatov
  746. * New CVS and development tree structure for the NCBI C++ projects
  747. *
  748. * Revision 1.28  1998/12/14 20:25:35  sandomir
  749. * changed with Command handling
  750. *
  751. * Revision 1.27  1998/12/09 19:25:32  vakatov
  752. * Made CCgiRequest::GetRandomProperty() look "const"
  753. *
  754. * Revision 1.26  1998/12/04 23:38:34  vakatov
  755. * Workaround SunPro's "buggy const"(see "BW_01")
  756. * Renamed "CCgiCookies::Erase()" method to "...Clear()"
  757. *
  758. * Revision 1.25  1998/12/01 15:39:35  sandomir
  759. * xmlstore.hpp|cpp moved to another dir
  760. *
  761. * Revision 1.24  1998/12/01 00:27:16  vakatov
  762. * Made CCgiRequest::ParseEntries() to read ISINDEX data, too.
  763. * Got rid of now redundant CCgiRequest::ParseIndexesAsEntries()
  764. *
  765. * Revision 1.23  1998/11/30 21:23:17  vakatov
  766. * CCgiRequest:: - by default, interprete ISINDEX data as regular FORM entries
  767. * + CCgiRequest::ParseIndexesAsEntries()
  768. * Allow FORM entry in format "name1&name2....." (no '=' necessary after name)
  769. *
  770. * Revision 1.22  1998/11/27 20:55:18  vakatov
  771. * CCgiRequest::  made the input stream arg. be optional(std.input by default)
  772. *
  773. * Revision 1.21  1998/11/27 19:44:31  vakatov
  774. * CCgiRequest::  Engage cmd.-line args if "$REQUEST_METHOD" is undefined
  775. *
  776. * Revision 1.20  1998/11/26 00:29:50  vakatov
  777. * Finished NCBI CGI API;  successfully tested on MSVC++ and SunPro C++ 5.0
  778. *
  779. * Revision 1.19  1998/11/24 23:07:28  vakatov
  780. * Draft(almost untested) version of CCgiRequest API
  781. *
  782. * Revision 1.18  1998/11/24 21:31:30  vakatov
  783. * Updated with the ISINDEX-related code for CCgiRequest::
  784. * TCgiEntries, ParseIndexes(), GetIndexes(), etc.
  785. *
  786. * Revision 1.17  1998/11/24 17:52:14  vakatov
  787. * Starting to implement CCgiRequest::
  788. * Fully implemented CCgiRequest::ParseEntries() static function
  789. *
  790. * Revision 1.16  1998/11/20 22:36:38  vakatov
  791. * Added destructor to CCgiCookies:: class
  792. * + Save the works on CCgiRequest:: class in a "compilable" state
  793. *
  794. * Revision 1.15  1998/11/19 23:41:09  vakatov
  795. * Tested version of "CCgiCookie::" and "CCgiCookies::"
  796. *
  797. * Revision 1.14  1998/11/19 20:02:49  vakatov
  798. * Logic typo:  actually, the cookie string does not contain "Cookie: "
  799. *
  800. * Revision 1.13  1998/11/19 19:50:00  vakatov
  801. * Implemented "CCgiCookies::"
  802. * Slightly changed "CCgiCookie::" API
  803. *
  804. * Revision 1.12  1998/11/18 21:47:50  vakatov
  805. * Draft version of CCgiCookie::
  806. *
  807. * Revision 1.11  1998/11/17 23:47:13  vakatov
  808. * + CCgiRequest::EMedia
  809. *
  810. * Revision 1.10  1998/11/17 02:02:08  vakatov
  811. * Compiles through with SunPro C++ 5.0
  812. * ==========================================================================
  813. */
  814. #endif  /* NCBICGI__HPP */