NCBI C++ ToolKit
cgi_session_sample.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: cgi_session_sample.cpp 90029 2020-05-05 14:03:22Z ivanov $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Maxim Didenko
27  *
28  *
29  */
30 
31 #include <ncbi_pch.hpp>
32 #include <corelib/ncbistre.hpp>
33 #include <cgi/cgiapp.hpp>
34 #include <cgi/cgictx.hpp>
35 #include <html/html.hpp>
36 
38 
40 
41 
42 /////////////////////////////////////////////////////////////////////////////
43 // CCgiSessionSampleApplication::
44 //
45 
47 {
48 public:
49  virtual int ProcessRequest(CCgiContext& ctx);
50 
51 protected:
52  /// Get storage for CGI session data
54 
55 private:
56  // Auxiliary method to print configuration file
57  void x_ShowConfigFile(CCgiResponse& response);
58 };
59 
60 
63 {
64  // NetCache requires some configuring; e.g. see "cgi_session_sample.ini"
65  const IRegistry& app_config = GetConfig();
66 
67  // Note: Framework will take the ownership over the CCgiSession_NetCache
68  return new CCgiSession_NetCache(app_config);
69 }
70 
71 
72 // Forward declarations of auxiliary functions to create the HTML representation skeleton
74 static CNodeRef s_CreateHTMLPage(CRef<CHTML_table> table, const string& form_url, const string& session_label);
75 
76 
78 {
79  // Given "CGI context", get its "HTTP request" and "HTTP response"
80  const CCgiRequest& request = ctx.GetRequest();
81  CCgiResponse& response = ctx.GetResponse();
82 
83  // if Show config file was requested
84  if ( !request.GetEntry("showconfig").empty() ) {
85  x_ShowConfigFile(response);
86  return 0;
87  }
88 
89  // Get CGI session.
90  // The framework searches for the session ID in the CGI request
91  // cookies and entries. If session ID is not found, then a new
92  // session will be created.
93  CCgiSession& session = request.GetSession();
94 
95  // Check if it was requested to delete current session or to create a
96  // new session ("Delete Session" or "Create Session" buttons in the form)
97  if ( !request.GetEntry("DeleteSession").empty() ) {
98  session.DeleteSession();
99  }
100  else if ( !request.GetEntry("CreateSession").empty() ) {
101  session.CreateNewSession();
102  }
103 
104  // If there is an active CGI session...
105  if (session.GetStatus() != CCgiSession::eDeleted) {
106  // Check if user typed into the text fields to add a new
107  // (or to change an existing) session variable
108  string name = request.GetEntry("AttrName");
109  if ( !name.empty() ) {
110  string value = request.GetEntry("AttrValue");
111 
112  // Store the value of the session variable
113  CNcbiOstream& os = session.GetAttrOStream(name);
114  os << value;
115 
116  // Alternatively (for a string value), the SetAttribute() method can also be used:
117  // session.SetAttribute(name, value);
118  }
119 
120  // Check if user requested to delete existing session variable (pressed "Delete Attribute" button)
122  for (const auto& name : names) {
123  if ( !request.GetEntry("Delete_" + name).empty() ) {
124  session.RemoveAttribute(name);
125  break;
126  }
127  }
128  }
129 
130  // Create layout of the table that shows session attributes (if any)
131 
133 
134  // Populate the HTML page with the session data
135  string session_label;
136  string self_url = ctx.GetSelfURL();
137  if (session.GetStatus() != CCgiSession::eDeleted) {
138  // Populate table with the list of known session variables
139  CCgiSession::TNames attrs(session.GetAttributeNames());
140  CHTML_table::TIndex row = 1;
141  for (const auto& name : attrs) {
142  table->Cell(row,0)->AppendPlainText(name);
143  table->Cell(row,1)->AppendPlainText(session.GetAttribute(name));
144  table->Cell(row,2)->AppendChild(new CHTML_submit("Delete_" + name, "Delete Attribute"));
145  ++row;
146  }
147  // Show session ID
148  session_label = "Session ID: " + session.GetId();
149  // If we want to pass session Id through a query string...
150  self_url += "?" + session.GetSessionIdName() + "=" + session.GetId();
151  } else {
152  // Session has been deleted, so no session data is available
153  session_label = "Session has been deleted";
154  }
155 
156  // Print HTTP header
157  response.WriteHeader();
158 
159  // Finish the HTML page, then print it
160  CNodeRef page = s_CreateHTMLPage(table, self_url, session_label);
161  page->Print(response.out());
162 
163  return 0;
164 }
165 
166 
167 /////////////////////////////////////////////////////////////////////////////
168 
169 
170 // Auxiliary function to print configuration file, if any
171 
173 {
174  CNodeRef Html(new CHTML_html);
175  CNodeRef Head(new CHTML_head);
176  Head->AppendChild(new CHTML_title("Sample CGI Session config file"));
177  Html->AppendChild(Head);
178  CNodeRef Body(new CHTML_body);
179  Html->AppendChild(Body);
180  CNcbiIfstream is(GetConfigPath().c_str());
181  CNcbiOstrstream os;
182  os << is.rdbuf();
183  Body->AppendChild(new CHTML_pre(CNcbiOstrstreamToString(os)));
184  response.WriteHeader();
185  Html->Print(response.out());
186 }
187 
188 
189 // Auxiliary function to create the HTML table to hold session attributes
190 
192 {
194  table->SetAttribute("border","1");
195  table->SetAttribute("width","600");
196  table->SetAttribute("cellspacing","0");
197  table->SetAttribute("cellpadding","2");
198  table->SetColumnWidth(0,"20%");
199  table->SetColumnWidth(1,"65%");
200  table->HeaderCell(0,0)->AppendPlainText("Name");
201  table->HeaderCell(0,1)->AppendPlainText("Value");
202  table->HeaderCell(0,2)->AppendPlainText("Action");
203  return table;
204 }
205 
206 
207 // Auxiliary function to create the HTML page to manage session and its data
208 
210  const string& form_url,
211  const string& session_label)
212 {
213  CNodeRef Html(new CHTML_html);
214  CNodeRef Head(new CHTML_head);
215  Head->AppendChild(new CHTML_title("Sample CGI Session"));
216  Html->AppendChild(Head);
217  CNodeRef Body(new CHTML_body);
218  Html->AppendChild(Body);
219  Body->AppendChild(new CHTML_h3(session_label));
220 
221  CRef<CHTML_form> Form(new CHTML_form(form_url, CHTML_form::ePost));
222  Body->AppendChild(Form);
223  Form->AppendChild(new CHTML_submit("DeleteSession", "Delete Session"));
224  Form->AppendChild(new CHTML_submit("CreateSession", "Create New Session"));
225  Form->AppendChild(new CHTML_hr);
226  Form->AppendChild(table);
227  Form->AppendChild(new CHTML_br);
228  Form->AppendPlainText("Set Attribute:");
229  Form->AppendChild(new CHTML_br);
230  Form->AppendChild(new CHTML_p);
231  Form->AppendPlainText("Name: ");
232  Form->AppendChild(new CHTML_text("AttrName"));
233  Form->AppendPlainText(" Value: ");
234  Form->AppendChild(new CHTML_text("AttrValue"));
235  Form->AppendChild(new CHTML_p);
236  Form->AppendChild(new CHTML_submit("SUBMIT", "Submit"));
237  Form->AppendChild(new CHTML_reset);
238  Form->AppendChild(new CHTML_hr);
239  string s(form_url);
240  string::size_type pos = s.find('?');
241  if (pos != string::npos) {
242  s = form_url.substr(0,pos);
243  }
244  Form->AppendChild(new CHTML_a(s + "?showconfig=1", "Show config file"));
245  return Html;
246 }
247 
248 
249 /////////////////////////////////////////////////////////////////////////////
250 // MAIN
251 //
252 
253 int NcbiSys_main(int argc, ncbi::TXChar* argv[])
254 {
255  return CCgiSessionSampleApplication().AppMain(argc, argv);
256 }
static CNodeRef s_CreateHTMLPage(CRef< CHTML_table > table, const string &form_url, const string &session_label)
int NcbiSys_main(int argc, ncbi::TXChar *argv[])
static CRef< CHTML_table > s_CreateHTMLTable()
USING_NCBI_SCOPE
CCgiRequest::
Definition: ncbicgi.hpp:685
virtual ICgiSessionStorage * GetSessionStorage(CCgiSessionParameters &) const
Get storage for CGI session data.
virtual int ProcessRequest(CCgiContext &ctx)
This is the method you should override.
void x_ShowConfigFile(CCgiResponse &response)
CCgiSession –.
Definition: cgi_session.hpp:62
CNcbiOstrstreamToString class helps convert CNcbiOstrstream to a string Sample usage:
Definition: ncbistre.hpp:802
CRef –.
Definition: ncbiobj.hpp:618
ICgiSessionStorage –.
IRegistry –.
Definition: ncbireg.hpp:73
char value[7]
Definition: config.c:431
CS_CONTEXT * ctx
Definition: t0006.c:12
static const struct name_t names[]
const CNcbiRegistry & GetConfig(void) const
Get the application's cached configuration parameters (read-only).
int AppMain(int argc, const char *const *argv, const char *const *envp=0, EAppDiagStream diag=eDS_Default, const char *conf=NcbiEmptyCStr, const string &name=NcbiEmptyString)
Main function (entry point) for the NCBI application.
Definition: ncbiapp.cpp:799
const string & GetConfigPath(void) const
Get the full path to the configuration file (if any) we ended up using.
bool empty() const
Definition: ncbicgi.hpp:538
CNcbiOstream & out(void) const
Get output stream. Throw exception if GetOutput() is NULL.
Definition: ncbicgir.cpp:257
CCgiSession & GetSession(ESessionCreateMode mode=eCreateIfNotExist) const
Get session.
Definition: ncbicgi.cpp:1605
CNcbiOstream & WriteHeader(void) const
Write HTTP response header to the output stream.
Definition: ncbicgir.hpp:396
const CCgiEntry & GetEntry(const string &name, bool *is_found=0) const
Get entry value by name.
Definition: ncbicgi.cpp:1449
string GetAttribute(const string &name) const
Get attribute data as string.
void DeleteSession(void)
Delete current session.
TNames GetAttributeNames(void) const
Retrieve names of all attributes attached to this session.
void CreateNewSession(void)
Create new session.
const string & GetSessionIdName(void) const
Get name for session ID.
list< string > TNames
Definition: cgi_session.hpp:64
void RemoveAttribute(const string &name)
Remove attribute from the session.
const string & GetId(void) const
Get session ID.
Definition: cgi_session.cpp:73
CNcbiOstream & GetAttrOStream(const string &name)
Get output stream to write an attribute's data to.
EStatus GetStatus(void) const
Get current status of the session.
@ eDeleted
The session is deleted.
Definition: cgi_session.hpp:75
unsigned TIndex
Definition: html.hpp:731
CNCBINode * AppendChild(CNCBINode *child)
virtual CNcbiOstream & Print(CNcbiOstream &out, TMode mode=eHTML)
Definition: node.cpp:296
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
IO_PREFIX::ifstream CNcbiIfstream
Portable alias for ifstream.
Definition: ncbistre.hpp:439
char TXChar
Definition: ncbistr.hpp:172
HTML classes.
<!DOCTYPE HTML >< html > n< header > n< title > PubSeq Gateway Help Page</title > n< style > n table
NCBI C++ stream class wrappers for triggering between "new" and "old" C++ stream libraries.
Modified on Tue Nov 28 02:22:00 2023 by modify_doxy.py rev. 669887