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

Go to the SVN repository for this file.

1 /* $Id: fcgi_mt_sample.cpp 94523 2021-08-12 13:43:58Z grichenk $
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: Aleksey Grichenko
27  *
28  * File Description:
29  * Plain example of a FastCGI MT application.
30  *
31  * USAGE: fcgi_mt_sample.fcgi?message=Some+Message
32  *
33  * NOTE: needs HTML template file "cgi_sample.html" in curr. dir to run,
34  *
35  */
36 
37 #include <ncbi_pch.hpp>
38 #include <cgi/fcgiapp_mt.hpp>
39 #include <cgi/cgictx.hpp>
40 #include <html/html.hpp>
41 #include <html/page.hpp>
42 
43 // To get CGI client API (in-house only, optional)
44 // #include <connect/ext/ncbi_localnet.h>
45 
47 
48 
49 /////////////////////////////////////////////////////////////////////////////
50 // CFastCgiMTSampleApplication::
51 //
52 
54 {
55 public:
56  void Init(void) override;
58 
59 private:
60  // These 2 functions just demonstrate the use of cmd-line argument parsing
61  // mechanism in CGI application -- for the processing of both cmd-line
62  // arguments and HTTP entries
63  void x_SetupArgs(void);
64 };
65 
66 
67 /////////////////////////////////////////////////////////////////////////////
68 // CFastCgiMTSampleRequestProcessor::
69 //
70 
72 {
73 public:
75  : CCgiRequestProcessorMT(app) {}
77 
78  int ProcessRequest(CCgiContext& context) override;
79 
80 private:
81  void x_LookAtArgs(void);
82 };
83 
84 
86 {
87  // Standard CGI framework initialization
89 
90  // Describe possible cmd-line and HTTP entries
91  // (optional)
92  x_SetupArgs();
93 }
94 
95 
97 {
98  return new CFastCgiMTSampleRequestProcessor(*this);
99 }
100 
101 
103 {
104  // Disregard the case of CGI arguments
106 
107  // Create CGI argument descriptions class
108  // (For CGI applications only keys can be used)
109  unique_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
110 
111  // Specify USAGE context
112  arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
113  "FastCGI MT sample application");
114 
115  arg_desc->AddOptionalKey("message",
116  "message",
117  "Message passed to CGI application",
120 
121  arg_desc->AddDefaultKey("delay",
122  "delay",
123  "Delay before sending reply, seconds",
125 
126  // Setup arg.descriptions for this application
127  SetupArgDescriptions(arg_desc.release());
128 }
129 
130 
132 {
133  // Parse, verify, and look at cmd-line and CGI parameters via "CArgs"
134  // (optional)
135  x_LookAtArgs();
136 
137  int delay = GetArgs()["delay"].AsInteger();
138  if ( delay ) SleepSec(delay);
139 
140  // Given "CGI context", get access to its "HTTP request" and
141  // "HTTP response" sub-objects
142  const CCgiRequest& request = ctx.GetRequest();
143  CCgiResponse& response = ctx.GetResponse();
144 
145  /*
146  // To get CGI client API (in-house only, optional)
147  const char* const* client_tracking_env = request.GetClientTrackingEnv();
148  unsigned int client_ip = NcbiGetCgiClientIP(eCgiClientIP_TryAll, client_tracking_env);
149  int is_local_client = NcbiIsLocalCgiClient(client_tracking_env);
150  */
151 
152  // Try to retrieve the message ('message=...') from the HTTP request.
153  // NOTE: the case sensitivity was turned off in Init().
154  bool is_message = false;
155  string message = request.GetEntry("Message", &is_message);
156  if ( is_message ) {
157  message = "'" + message + "'";
158  } else {
159  message = "<NONE>";
160  }
161 
162  // NOTE: While this sample uses the CHTML* classes for generating HTML,
163  // you are encouraged to use XML/XSLT and the NCBI port of XmlWrapp.
164  // For more info:
165  // http://ncbi.github.io/cxx-toolkit/pages/ch_xmlwrapp
166  // http://www.ncbi.nlm.nih.gov/IEB/ToolBox/CPP_DOC/doxyhtml/namespacexml.html
167 
168  // Create a HTML page (using template HTML file "cgi_sample.html")
169  unique_ptr<CHTMLPage> page;
170  try {
171  // Find page template
172  string html_path = "cgi_sample.html";
173  if ( !CFile(html_path).Exists() ) {
174  html_path = CDirEntry::ConcatPath(CDirEntry(GetApp().GetProgramExecutablePath()).GetDir(), html_path);
175  }
176  page.reset(new CHTMLPage("Sample CGI", html_path));
177  } catch (exception& e) {
178  ERR_POST("Failed to create Sample CGI HTML page: " << e.what());
179  return 2;
180  }
181 
182  // Register substitution for the template parameters <@MESSAGE@> and
183  // <@SELF_URL@>
184  try {
185  CHTMLPlainText* text = new CHTMLPlainText(message);
186  _TRACE("foo");
187  page->AddTagMap("MESSAGE", text);
188 
189  CHTMLPlainText* self_url = new CHTMLPlainText(ctx.GetSelfURL());
190  page->AddTagMap("SELF_URL", self_url);
191  }
192  catch (exception& e) {
193  ERR_POST("Failed to populate Sample CGI HTML page: " << e.what());
194  return 3;
195  }
196 
197  // Compose and flush the resultant HTML page
198  try {
199  _TRACE("stream status: " << ctx.GetStreamStatus());
200  response.WriteHeader();
201  if (request.GetRequestMethod() != CCgiRequest::eMethod_HEAD) {
202  page->Print(response.out(), CNCBINode::eHTML);
203  }
204  } catch (CCgiHeadException&) {
205  throw;
206  } catch (exception& e) {
207  ERR_POST("Failed to compose/send Sample CGI HTML page: " << e.what());
208  return 4;
209  }
210 
211  return 0;
212 }
213 
214 
216 {
217  // You can catch CArgException& here to process argument errors,
218  // or you can handle it in OnException()
219  const CArgs& args = GetArgs();
220 
221  // "args" now contains both command line arguments and the arguments
222  // extracted from the HTTP request
223 
224  if ( args["message"] ) {
225  // get the first "message" argument only...
226  const string& m = args["message"].AsString();
227  (void) m.c_str(); // just get rid of compiler warning about unused variable
228 
229  // ...or get the whole list of "message" arguments
230  const auto& values = args["message"].GetStringList(); // const CArgValue::TStringArray&
231 
232  for (const auto& v : values) {
233  // do something with each message 'v' (string)
234  (void) v.c_str(); // just get rid of compiler warning about unused variable
235  }
236  } else {
237  // no "message" argument is present
238  }
239 }
240 
241 
242 /////////////////////////////////////////////////////////////////////////////
243 // MAIN
244 //
245 
246 int NcbiSys_main(int argc, ncbi::TXChar* argv[])
247 {
248  return CFastCgiMTSampleApplication().AppMain(argc, argv);
249 }
CArgDescriptions –.
Definition: ncbiargs.hpp:541
CArgs –.
Definition: ncbiargs.hpp:379
CCgiHeadException –.
Base class for request processors.
Definition: cgiapp.hpp:579
CCgiRequest::
Definition: ncbicgi.hpp:685
CDirEntry –.
Definition: ncbifile.hpp:262
CCgiRequestProcessor * CreateRequestProcessor(void) override
Create request processor to process the request.
void Init(void) override
This method is called on the CGI application initialization – before starting to process a HTTP reque...
CFastCgiMTSampleRequestProcessor(CFastCgiMTSampleApplication &app)
~CFastCgiMTSampleRequestProcessor(void) override
int ProcessRequest(CCgiContext &context) override
Process request provided by the context. By default calls application's ProcessRequest.
CFile –.
Definition: ncbifile.hpp:1604
CHTMLPage –.
Definition: page.hpp:161
CS_CONTEXT * ctx
Definition: t0006.c:12
int NcbiSys_main(int argc, ncbi::TXChar *argv[])
USING_NCBI_SCOPE
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 CNcbiArguments & GetArguments(void) const
Get the application's cached unprocessed command-line arguments.
@ fAllowMultiple
Repeated key arguments are legal (use with AddKey)
Definition: ncbiargs.hpp:635
@ eString
An arbitrary string.
Definition: ncbiargs.hpp:589
@ eInteger
Convertible into an integer number (int or Int8)
Definition: ncbiargs.hpp:592
virtual void SetupArgDescriptions(CArgDescriptions *arg_desc)
Setup the command line argument descriptions.
Definition: cgiapp.cpp:794
virtual void Init(void)
This method is called on the CGI application initialization – before starting to process a HTTP reque...
Definition: cgiapp.cpp:864
void SetRequestFlags(int flags)
Set cgi parsing flag.
Definition: cgiapp.hpp:130
CArgs & GetArgs(void)
Definition: cgiapp.hpp:640
CCgiApplication & GetApp(void)
Definition: cgiapp.hpp:632
CNcbiOstream & out(void) const
Get output stream. Throw exception if GetOutput() is NULL.
Definition: ncbicgir.cpp:257
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
ERequestMethod GetRequestMethod(void) const
Get request method.
Definition: ncbicgi.cpp:1810
@ fCaseInsensitiveArgs
use case insensitive CGI arguments
Definition: ncbicgi.hpp:714
#define _TRACE(message)
Definition: ncbidbg.hpp:122
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
static string ConcatPath(const string &first, const string &second)
Concatenate two parts of the path for the current OS.
Definition: ncbifile.cpp:776
@ eHTML
Definition: node.hpp:109
char TXChar
Definition: ncbistr.hpp:172
HTML classes.
static void text(MDB_val *v)
Definition: mdb_dump.c:62
void SleepSec(unsigned long sec, EInterruptOnSignal onsignal=eRestartOnSignal)
Sleep.
The HTML page.
Modified on Fri Dec 08 08:23:33 2023 by modify_doxy.py rev. 669887