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

Go to the SVN repository for this file.

1 /* $Id: cgi2rcgi.cpp 100705 2023-08-31 20:10:12Z lavr $
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, Dmitry Kazimirov
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 
34 #include <cgi/cgiapp_cached.hpp>
35 #include <cgi/cgictx.hpp>
36 #include <cgi/cgi_serial.hpp>
37 
38 #include <html/commentdiag.hpp>
39 #include <html/html.hpp>
40 #include <html/page.hpp>
41 
42 #include <util/xregexp/regexp.hpp>
43 #include <util/checksum.hpp>
44 #include <util/retry_ctx.hpp>
45 
49 
51 
52 #include <corelib/ncbistr.hpp>
53 #include <corelib/ncbimisc.hpp>
54 #include <corelib/ncbi_system.hpp>
55 
56 #include <array>
57 #include <vector>
58 #include <functional>
59 #include <map>
60 #include <sstream>
61 #include <unordered_map>
62 
63 #define GRID_APP_NAME "cgi2rcgi"
64 
66 
67 #define HTTP_NCBI_JSID "NCBI-JSID"
68 
69 static const string kSinceTime = "ctg_time";
70 
72  fUseQueryString = 1 << 0,
74  fMakePersistent = 1 << 2,
76 
77  // Old values, now synonyms
80 };
81 
82 
84 {
86 
87  void CheckEntry(const string& name, const string& value, bool is_requested = true);
88  void AddAffinityEntry(string name);
89 
90  static vector<string> GetListenJobs(const string& value);
91  static CDeadline GetDeadline(const string& value);
92 
93 private:
94  static void CheckJobKey(const string& value);
95  static void CheckCancel(const string& value);
96  static void CheckCtgTime(const string& value) { NStr::StringToInt(value); }
97  static void CheckGetResults(const string& value) { NStr::StringToBool(value); }
98  static void CheckAffinity(const string& value);
99 
100  struct SEntry;
101  vector<SEntry> m_Entries;
102 };
103 
105 {
106  string name;
107 
108  template <class TF>
109  SEntry(string n, TF f) : name(std::move(n)), m_Func(f) {}
110 
111  bool Check(const string& value);
112 
113 private:
114  function<void(const string&)> m_Func;
115  bool m_Validated = false;
116 };
117 
119 {
120  if (m_Validated || value.empty()) {
121  return true;
122  }
123 
124  if (!m_Func) {
125  return false;
126  }
127 
128  try {
129  m_Func(value);
130  m_Validated = true;
131  }
132  catch (CCgiRequestException&) {
133  // This type is safe to rethrow and has more precise message
134  throw;
135  }
136  catch (...) {
138  "Invalid " << name << " value (not shown for safety reasons)");
139  }
140 
141  return true;
142 }
143 
145  m_Entries({
146  { "listen_jobs", GetListenJobs },
147  { "timeout", GetDeadline },
148  { "job_key", CheckJobKey },
149  { "cancel", CheckCancel },
150  { "ctg_time", CheckCtgTime },
151  { "get_results", CheckGetResults },
152  })
153 {
154 }
155 
156 void SInputValidator::CheckEntry(const string& name, const string& value, bool is_requested)
157 {
158  auto l = [&](const SEntry& entry) { return NStr::CompareNocase(entry.name, name) == 0; };
159  auto found = find_if(m_Entries.begin(), m_Entries.end(), l);
160 
161  // Throw if no validation function has found but the input value has been explicitly requested
162  if (((found == m_Entries.end()) || !found->Check(value)) && is_requested) {
164  FORMAT(name << " has no validation defined"), CCgiException::e501_NotImplemented);
165  }
166 }
167 
169 {
170  m_Entries.push_back(SEntry(std::move(name), CheckAffinity));
171 }
172 
173 vector<string> SInputValidator::GetListenJobs(const string& value)
174 {
175  vector<string> rv;
176  NStr::Split(value, ",", rv);
177 
178  for (const auto& job_id : rv) {
179  CheckJobKey(job_id);
180  }
181 
182  return rv;
183 }
184 
186 {
187  CTimeout timeout(CTimeout::eZero);
188 
189  if (!value.empty()) {
190  timeout.Set(NStr::StringToDouble(value));
191  }
192 
193  return CDeadline(timeout);
194 }
195 
197 {
198  // Pool is required to check compound IDs
199  CCompoundIDPool pool;
200  CNetScheduleKey key(value, pool);
201 
202  if (!key.version) {
203  // CNetScheduleKey allows anything if that starts with a digit, so the additional check
205 
206  // NetSchedule API can fail (abort) on old job key formats (version == 0)
207  NCBI_THROW(CCgiRequestException, eData, "Old job key formats are not supported");
208  }
209 }
210 
212 {
213  // Cannot use NStr::StringToBool here as cgi2rcgi.inc.html uses "Cancel the job" as a value
214  if (!NStr::MatchesMask(value, "[ 0-9a-zA-Z_-]*")) {
215  NCBI_THROW(CCgiRequestException, eData, "Invalid cancel value (not shown for safety reasons)");
216  }
217 }
218 
220 {
221  if (!NStr::MatchesMask(value, "[0-9a-zA-Z_-]*")) {
222  NCBI_THROW(CCgiRequestException, eData, "Invalid affinity value (not shown for safety reasons)");
223  }
224 }
225 
226 
228 {
230 
231  string operator()(const string& what)
232  {
234  // Must correspond to TExceptionMessage
235  auto message = m_Registry->GetString("CGI", "Exception_Message", "Some exception was thrown (not shown for safety reasons)");
236  return message.empty() ? what : message;
237  }
238 
239 private:
241 };
242 
243 
244 /** @addtogroup NetScheduleClient
245  *
246  * @{
247  */
248 
249 /////////////////////////////////////////////////////////////////////////////
250 // Grid Cgi Context
251 // Context in which a request is processed
252 //
253 class CGridCgiContext
254 {
255 public:
256  CGridCgiContext(SInputValidator& input_validator, CHTMLPage& page,
257  CHTMLPage& custom_http_header, CCgiContext& ctx);
258 
259  // Get the HTML page
260  CHTMLPage& GetHTMLPage() { return m_Page; }
261 
262  // Get the self URL
263  string GetSelfURL(bool include_entries = true) const;
264 
265  // Get current job progress message
266  const string& GetJobProgressMessage() const
267  { return m_ProgressMsg; }
268 
269  // Get a value from a CGI request. if there is no an entry with a
270  // given name it returns an empty string.
271  const string& GetPersistentEntryValue(const string& entry_name) const;
272 
273  void GetQueryStringEntryValue(const string& entry_name,
274  string& value) const;
275  void GetRequestEntryValue(const string& entry_name, string& value) const;
276 
278 
279  void PullUpPersistentEntry(const string& entry_name);
280  void PullUpPersistentEntry(const string& entry_name, string& value, int pulling = eDefaultPulling);
281  void DefinePersistentEntry(const string& entry_name, const string& value);
283  { return m_PersistentEntries; }
285 
287 
288  void SelectView(const string& view_name);
289  bool NeedRenderPage() const { return m_NeedRenderPage; }
291  bool NeedMetaRefresh() const { return m_NeedMetaRefresh; }
292 
293  string& GetJobKey() { return m_JobKey; }
294  string& GetJqueryCallback() { return m_JqueryCallback; }
295 
296 public:
297  // Remove all persistent entries from cookie and self url.
298  void Clear();
299 
300  void SetJobProgressMessage(const string& msg)
301  { m_ProgressMsg = msg; }
302 
303  void AddTagMap(const string& n, const string& v, CHTMLPlainText::EEncodeMode m = CHTMLPlainText::eHTMLEncode)
304  {
305  m_Page.AddTagMap(n, new CHTMLPlainText(m, v));
307  }
308 
309 private:
311  CHTMLPage& m_Page;
316  string m_ProgressMsg;
317  string m_JobKey;
319  bool m_NeedRenderPage;
321 };
322 
323 
324 /////////////////////////////////////////////////////////////////////////////
325 
326 
328  CHTMLPage& custom_http_header, CCgiContext& ctx) :
329  m_InputValidator(input_validator),
330  m_Page(page),
331  m_CustomHTTPHeader(custom_http_header),
332  m_CgiContext(ctx),
333  m_NeedRenderPage(true)
334 {
335  const CCgiRequest& req = ctx.GetRequest();
336  string query_string = req.GetProperty(eCgi_QueryString);
338 
339  const string kNoMetaRefreshHeader = "X_NCBI_RETRY_NOMETAREFRESH";
340  const string& no_meta_refresh = req.GetRandomProperty(kNoMetaRefreshHeader);
341  m_NeedMetaRefresh = no_meta_refresh.empty() || no_meta_refresh == "0";
342 }
343 
344 string CGridCgiContext::GetSelfURL(bool include_entries) const
345 {
347 
348  if (!include_entries) {
349  return url;
350  }
351 
352  bool first = true;
354  for (it = m_PersistentEntries.begin();
355  it != m_PersistentEntries.end(); ++it) {
356  const string& name = it->first;
357  const string& value = it->second;
358  if (!name.empty() && !value.empty()) {
359  if (first) {
360  url += '?';
361  first = false;
362  }
363  else
364  url += '&';
365  url += name + '=' + NStr::URLEncode(value);
366  }
367  }
368  return url;
369 }
370 
372  const string& entry_name) const
373 {
375  if (it != m_PersistentEntries.end())
376  return it->second;
377  return kEmptyStr;
378 }
379 
380 void CGridCgiContext::GetQueryStringEntryValue(const string& entry_name,
381  string& value) const
382 {
384  if (NStr::CompareNocase(entry_name, eit->first) == 0) {
385  string v = eit->second;
386  if (!v.empty())
387  value = v;
388  }
389  }
390 }
391 
392 void CGridCgiContext::GetRequestEntryValue(const string& entry_name,
393  string& value) const
394 {
396  ITERATE(TCgiEntries, eit, entries) {
397  if (NStr::CompareNocase(entry_name, eit->first) == 0) {
398  string v = eit->second;
399  if (!v.empty())
400  value = v;
401  }
402  }
403 }
404 
405 void CGridCgiContext::PullUpPersistentEntry(const string& entry_name)
406 {
407  string value = kEmptyStr;
408  PullUpPersistentEntry(entry_name, value);
409 }
410 
412  const string& entry_name, string& value, int pulling)
413 {
414  if (pulling & fUseQueryString) {
415  GetQueryStringEntryValue(entry_name, value);
416  }
417 
418  if (value.empty() && (pulling & fUseRequestContent)) {
419  GetRequestEntryValue(entry_name, value);
420  }
421 
422  if (pulling & fMakePersistent) {
424  DefinePersistentEntry(entry_name, value);
425  }
426 
427  m_InputValidator.CheckEntry(entry_name, value);
428 }
429 
430 void CGridCgiContext::DefinePersistentEntry(const string& entry_name,
431  const string& value)
432 {
433  if (value.empty()) {
435  m_PersistentEntries.find(entry_name);
436  if (it != m_PersistentEntries.end())
438  } else {
439  m_PersistentEntries[entry_name] = value;
440  }
441 }
442 
444  CHTMLPlainText::EEncodeMode encode_mode)
445 {
447  AddTagMap("QUERY_STRING:" + eit->first, eit->second, encode_mode);
448  m_InputValidator.CheckEntry(eit->first, eit->second, false);
449  }
450 }
451 
453 {
455 }
456 
457 void CGridCgiContext::SelectView(const string& view_name)
458 {
459  m_CustomHTTPHeader.AddTagMap("CUSTOM_HTTP_HEADER",
460  new CHTMLText("<@HEADER_" + view_name + "@>"));
461  m_Page.AddTagMap("STAT_VIEW", new CHTMLText("<@VIEW_" + view_name + "@>"));
462 }
463 
464 /////////////////////////////////////////////////////////////////////////////
465 //
466 // Grid CGI Front-end Application
467 //
468 // Class for CGI applications starting background jobs using
469 // NetSchedule. Implements job submission, status check,
470 // error processing, etc. All request processing is done on the back end.
471 // CGI application is responsible for UI rendering.
472 //
474 {
475 public:
476  // This method is called on the CGI application initialization -- before
477  // starting to process a HTTP request or even receiving one.
478  virtual void Init();
479 
480  // Factory method for the Context object construction.
483  int ifd, int ofd, int flags);
484 
485  // The main method of this CGI application.
486  // HTTP requests are processed in this method.
487  virtual int ProcessRequest(CCgiContext& ctx);
488 
489 private:
490  void DefineRefreshTags(CGridCgiContext& grid_ctx, const string& url, int delay);
491 
492 private:
493  void ListenJobs(const string& job_ids_value, const string& timeout_value);
494  void CheckJob(CGridCgiContext& grid_ctx);
495  void SubmitJob(CCgiRequest& request, CGridCgiContext& grid_ctx);
496  void PopulatePage(CGridCgiContext& grid_ctx);
497  int RenderPage();
501 
505 
508  unique_ptr<CGridClient> m_GridClient;
510 
511 private:
512  void ReadJob(istream&, CGridCgiContext&);
513 
514  // This method is called when result is available immediately
515  void OnJobDone(CGridCgiContext&);
516 
517  // This method is called when the worker node reported a failure.
518  void OnJobFailed(const string& msg, CGridCgiContext& ctx);
519 
520  string m_Title;
524  string m_DateFormat;
529 
530  unique_ptr<CHTMLPage> m_Page;
531  unique_ptr<CHTMLPage> m_CustomHTTPHeader;
532 
534  vector<string> m_HtmlIncs;
535 
539 
541 
547 };
548 
550 {
551  // Standard CGI framework initialization
553 
554  // Grid client initialization
556  string grid_cgi_section("grid_cgi");
557 
558  // Must correspond to TEnableVersionRequest
559  config.Set("CGI", "EnableVersionRequest", "false");
560 
561  // Must correspond to TServConn_ErrorOnUnexpectedReply
562  if (!config.HasEntry("netservice_api", "error_on_unexpected_reply")) {
563  config.Set("netservice_api", "error_on_unexpected_reply", "true");
564  }
565 
566  // Default value must correspond to SRCgiWait value
567  m_RefreshDelay = config.GetInt(grid_cgi_section,
568  "refresh_delay", 5, IRegistry::eReturn);
569 
570  m_RefreshWait = config.GetInt(grid_cgi_section,
571  "refresh_wait", 0, IRegistry::eReturn);
572  if (m_RefreshWait < 0) m_RefreshWait = 0;
573  if (m_RefreshWait > 20) m_RefreshWait = 20;
574 
575  m_FirstDelay = config.GetInt(grid_cgi_section,
576  "expect_complete", 5, IRegistry::eReturn);
577 
578  if (m_FirstDelay > 20)
579  m_FirstDelay = 20;
580 
581  if (m_FirstDelay < 0)
582  m_FirstDelay = 0;
583 
586 
587  m_GridClient.reset(new CGridClient(
590  config.GetBool(grid_cgi_section, "automatic_cleanup",
591  true, IRegistry::eReturn) ?
593  config.GetBool(grid_cgi_section, "use_progress",
594  true, IRegistry::eReturn) ?
596 
597  // Allows CGI client to put the diagnostics to:
598  // HTML body (as comments) -- using CGI arg "&diag-destination=comments"
599  RegisterDiagFactory("comments", new CCommentDiagFactory);
600  // E-mail -- using CGI arg "&diag-destination=email:user@host"
602 
603 
604  // Initialize processing of both cmd-line arguments and HTTP entries
605 
606  // Create CGI argument descriptions class
607  // (For CGI applications only keys can be used)
608  unique_ptr<CArgDescriptions> arg_desc(new CArgDescriptions);
609 
610  // Specify USAGE context
611  arg_desc->SetUsageContext(GetArguments().GetProgramBasename(),
612  "Cgi2RCgi application");
613 
614  arg_desc->AddOptionalKey("Cancel",
615  "Cancel",
616  "Cancel Job",
618 
619  // Setup arg.descriptions for this application
620  SetupArgDescriptions(arg_desc.release());
621 
622  // Read configuration parameters
623  string cgi2rcgi_section("cgi2rcgi");
624 
625  m_ContentType = config.GetString(cgi2rcgi_section,
626  "content_type", kEmptyStr);
627  if (m_ContentType.empty() || m_ContentType == "text/html") {
629  m_HTMLPassThrough = config.GetBool(cgi2rcgi_section,
630  "html_pass_through", false);
631  } else {
632  m_TargetEncodeMode = m_ContentType == "application/json" ?
634  m_HTMLPassThrough = true;
635  }
636 
637  m_Title = config.GetString(cgi2rcgi_section, "cgi_title",
638  "Remote CGI Status Checker");
639 
640  m_HtmlTemplate = config.GetString(cgi2rcgi_section, "html_template",
641  "cgi2rcgi.html");
642 
643  string incs = config.GetString(cgi2rcgi_section, "html_template_includes",
644  "cgi2rcgi.inc.html");
645 
646  NStr::Split(incs, ",; ", m_HtmlIncs,
648 
649 
650  m_FallBackUrl = config.GetString(cgi2rcgi_section,
651  "fall_back_url", kEmptyStr);
652  m_FallBackDelay = config.GetInt(cgi2rcgi_section,
653  "error_fall_back_delay", -1, IRegistry::eReturn);
654 
655  m_CancelGoBackDelay = config.GetInt(cgi2rcgi_section,
656  "cancel_fall_back_delay", 0, IRegistry::eReturn);
657 
658  if (m_FallBackUrl.empty()) {
659  m_FallBackDelay = -1;
660  m_CancelGoBackDelay = -1;
661  }
662 
663  m_AffinitySource = 0;
664  m_AffinitySetLimit = 0;
665  m_AffinityName = config.GetString(cgi2rcgi_section,
666  "affinity_name", kEmptyStr);
667 
668  if (!m_AffinityName.empty()) {
669  vector<string> affinity_methods;
670  NStr::Split(config.GetString(cgi2rcgi_section,
671  "affinity_source", "GET"), ", ;&|", affinity_methods,
673  for (vector<string>::const_iterator it = affinity_methods.begin();
674  it != affinity_methods.end(); ++it) {
675  if (*it == "GET")
677  else if (*it == "POST")
679  else {
680  NCBI_THROW_FMT(CArgException, eConstraint,
681  "Invalid affinity_source value '" << *it << '\'');
682  }
683  }
684  m_AffinitySetLimit = config.GetInt(cgi2rcgi_section,
685  "narrow_affinity_set_to", 0);
687  }
688 
689  // Disregard the case of CGI arguments
691 
692  if (config.GetBool(cgi2rcgi_section, "donot_parse_content",
693  true, IRegistry::eReturn) &&
696 
698 
699  m_DateFormat = config.GetString(cgi2rcgi_section,
700  "date_format", "D B Y, h:m:s");
701 
702  m_ElapsedTimeFormat = config.GetString(cgi2rcgi_section,
703  "elapsed_time_format", "S");
704 
705  m_InterceptJQueryCallback = config.GetBool("CGI", "CORS_JQuery_Callback_Enable",
706  false, IRegistry::eReturn);
707 
708  m_AddJobIdToHeader = config.GetBool(cgi2rcgi_section, "add_job_id_to_response",
709  false, IRegistry::eReturn);
710 
711  m_DisplayDonePage = config.GetValue(cgi2rcgi_section, "display_done_page", false);
712  m_PortAdded = false;
713 
715 }
716 
719  int ifd, int ofd, int flags)
720 {
723  inp, out, ifd, ofd, flags);
724 
727  inp, out, ifd, ofd, flags | CCgiRequest::fSaveRequestContent);
728 
729  // The 'env' argument is only valid in FastCGI mode.
730  if (env == NULL)
731  env = &SetEnvironment();
732 
733  size_t content_length = 0;
734 
735  try {
736  content_length = (size_t) NStr::StringToUInt(
738  }
739  catch (...) {
740  }
741 
742  // Based on the CONTENT_LENGTH CGI parameter, decide whether to parse
743  // the POST request in search of the job_key parameter.
745  out, ifd, ofd, flags | (content_length > 0 &&
746  content_length < 128 ? CCgiRequest::fSaveRequestContent :
748 }
749 
750 static const string kGridCgiForm =
751  "<FORM METHOD=\"GET\" ACTION=\"<@SELF_URL@>\">\n"
752  "<@HIDDEN_FIELDS@>\n<@STAT_VIEW@>\n"
753  "</FORM>";
754 
755 static const string kPlainTextView = "<@STAT_VIEW@>";
756 
758 {
759 public:
761 
762  virtual bool TestAttribute(const string& attr_name,
763  const string& test_pattern);
764 
765 private:
767 };
768 
769 bool CRegexpTemplateFilter::TestAttribute(const string& attr_name,
770  const string& test_pattern)
771 {
772  CNCBINode* node = m_Page->MapTag(attr_name);
773 
774  if (node == NULL)
775  return false;
776 
777  stringstream node_stream;
778 
779  node->Print(node_stream, CNCBINode::ePlainText);
780 
781  CRegexp regexp(test_pattern, CRegexp::fCompile_ignore_case);
782 
783  return regexp.IsMatch(node_stream.str());
784 }
785 
786 #define CALLBACK_PARAM "callback="
787 
788 static void s_RemoveCallbackParameter(string* query_string)
789 {
790  SIZE_TYPE callback_pos = NStr::Find(*query_string, CALLBACK_PARAM);
791 
792  if (callback_pos == NPOS)
793  return;
794 
795  // See if 'callback' is the last parameter in the query string.
796  const char* callback_end = strchr(query_string->c_str() +
797  callback_pos + sizeof(CALLBACK_PARAM) - 1, '&');
798  if (callback_end != NULL)
799  query_string->erase(callback_pos,
800  callback_end - query_string->data() - callback_pos + 1);
801  else if (callback_pos == 0)
802  query_string->clear();
803  else if (query_string->at(callback_pos - 1) == '&')
804  query_string->erase(callback_pos - 1);
805 }
806 
808 {
810 
811  // Add server port to client node name.
812  if (!m_PortAdded) {
813  m_PortAdded = true;
814  const string port(env.Get(CCgiRequest::GetPropertyName(eCgi_ServerPort)));
816  }
817 
818  // Given "CGI context", get access to its "HTTP request" and
819  // "HTTP response" sub-objects
820  CCgiRequest& request = ctx.GetRequest();
821  m_Response = &ctx.GetResponse();
823 
826 
827  // Create an HTML page (using the template HTML file)
828  try {
829  m_Page.reset(new CHTMLPage(m_Title, m_HtmlTemplate));
830  CHTMLText* stat_view = new CHTMLText(!m_HTMLPassThrough ?
832  m_Page->AddTagMap("VIEW", stat_view);
833  }
834  catch (exception& e) {
835  ERR_POST("Failed to create " << m_Title << " HTML page: " << e.what());
836  return 2;
837  }
838  m_CustomHTTPHeader.reset(new CHTMLPage);
839  m_CustomHTTPHeader->SetTemplateString("<@CUSTOM_HTTP_HEADER@>");
841 
842  string listen_jobs;
843  string timeout;
844  grid_ctx.PullUpPersistentEntry("listen_jobs", listen_jobs);
845  grid_ctx.PullUpPersistentEntry("timeout", timeout);
846 
847  grid_ctx.PullUpPersistentEntry("job_key", grid_ctx.GetJobKey());
848  grid_ctx.PullUpPersistentEntry("Cancel");
849 
851 
853 
854  try {
856  TCgiEntries& entries = request.GetEntries();
857  TCgiEntries::iterator jquery_callback_it = entries.find("callback");
858  if (jquery_callback_it != entries.end()) {
859  grid_ctx.GetJqueryCallback() = jquery_callback_it->second;
860  entries.erase(jquery_callback_it);
861  string query_string_param(
863  string query_string = env.Get(query_string_param);
864  if (!query_string.empty()) {
865  s_RemoveCallbackParameter(&query_string);
866  env.Set(query_string_param, query_string);
867  }
868  }
869  }
870 
872 
873  try {
874  if (!listen_jobs.empty()) {
875  ListenJobs(listen_jobs, timeout);
876  grid_ctx.NeedRenderPage(false);
877  } else
878  if (!grid_ctx.GetJobKey().empty()) {
879  CheckJob(grid_ctx);
880  } else {
881  SubmitJob(request, grid_ctx);
882  }
883  } // try
884  catch (CCgiRequestException&) {
885  // Pass input validator exception
886  throw;
887  }
888  catch (exception& ex) {
889  ERR_POST("Job's reported as failed: " << ex.what());
890  OnJobFailed(m_ExceptionMessage(ex.what()), grid_ctx);
891  }
892 
893  if (grid_ctx.NeedRenderPage()) PopulatePage(grid_ctx);
894  } //try
895  catch (CCgiRequestException&) {
896  // Pass input validator exception
897  throw;
898  }
899  catch (exception& e) {
900  ERR_POST("Failed to populate " << m_Title <<
901  " HTML page: " << e.what());
902  return 3;
903  }
904 
905  return grid_ctx.NeedRenderPage() ? RenderPage() : 0;
906 }
907 
909 {
910  switch (job_status) {
913  return true;
914 
915  default:
916  return false;
917  }
918 }
919 
921 {
924 
925  SJob(const string& id) { job_id = id; }
926 };
927 
928 struct SJobs : unordered_map<string, SJob>
929 {
930  friend CNcbiOstream& operator<<(CNcbiOstream& out, SJobs jobs);
931 };
932 
933 void CCgi2RCgiApp::ListenJobs(const string& job_ids_value, const string& timeout_value)
934 {
935  auto job_ids = SInputValidator::GetListenJobs(job_ids_value);
936 
937  if (job_ids.empty()) return;
938 
939  SJobs jobs;
940 
941  for (const auto& job_id : job_ids) {
942  jobs.emplace(job_id, job_id);
943  }
944 
945  auto deadline = SInputValidator::GetDeadline(timeout_value);
946 
947  // Request notifications unless there is a job that is already not pending/running
948 
949  CNetScheduleSubmitter submitter = m_GridClient->GetNetScheduleSubmitter();
951 
952  bool wait_notifications = true;
953 
954  for (auto&& j : jobs) {
955  const auto& job_id = j.first;
956  auto& job = j.second;
957 
958  wait_notifications = wait_notifications && !deadline.IsExpired();
959 
960  try {
961  if (wait_notifications) {
962  tie(job.status, ignore, job.progress_msg) =
963  handler.RequestJobWatching(m_NetScheduleAPI, job_id, deadline);
964  } else {
965  job.status = m_NetScheduleAPI.GetJobDetails(job);
966  }
967  } catch (CNetScheduleException& ex) {
969  job.status = CNetScheduleAPI::eJobNotFound;
970  }
971 
972  wait_notifications = wait_notifications && s_IsPendingOrRunning(job.status);
973  }
974 
975 
976  // If all jobs are still pending/running, wait for a notification
977 
978  if (wait_notifications) {
979  while (handler.WaitForNotification(deadline)) {
980  SNetScheduleOutputParser parser(handler.GetMessage());
981 
982  auto it = jobs.find(parser("job_key"));
983 
984  // If it's one of requested jobs
985  if (it != jobs.end()) {
986  auto& job = it->second;
987  job.status = CNetScheduleAPI::StringToStatus(parser("job_status"));
988  job.progress_msg = parser("msg");
989  job.progress_msg_truncated = !parser("msg_truncated").empty();
990 
991  if (!s_IsPendingOrRunning(job.status)) break;
992  }
993  }
994 
995  // Recheck still pending/running jobs, just in case
996  for (auto&& j : jobs) {
997  auto& job = j.second;
998 
999  if (s_IsPendingOrRunning(job.status)) {
1000  job.progress_msg_truncated = false;
1001 
1002  try {
1003  job.status = m_NetScheduleAPI.GetJobDetails(job);
1004  } catch (CNetScheduleException& ex) {
1006  job.status = CNetScheduleAPI::eJobNotFound;
1007  job.progress_msg.clear();
1008  }
1009  }
1010  }
1011  }
1012 
1013 
1014  // Output jobs and their current states
1015 
1017 
1018  try {
1019  out << jobs;
1020  }
1021  catch (exception& e) {
1022  if (out) throw;
1023 
1024  ERR_POST(Warning << "Failed to write jobs and their states to client: " << e.what());
1025  }
1026 }
1027 
1029 {
1030  char delimiter = '{';
1031  out << "Content-type: application/json\nStatus: 200 OK\n\n";
1032 
1033  for (const auto& j : jobs) {
1034  const auto& job_id = j.first;
1035  const auto& job = j.second;
1036 
1037  const auto status = CNetScheduleAPI::StatusToString(job.status);
1038  const auto message = NStr::JsonEncode(job.progress_msg, NStr::eJsonEnc_Quoted);
1039  out << delimiter << "\n \"" << job_id << "\":\n {\n \"Status\": \"" << status << "\"";
1040 
1041  if (!job.progress_msg.empty()) {
1042  out << ",\n \"Message\": " << message;
1043  if (job.progress_msg_truncated) out << ",\n \"Truncated\": true";
1044  }
1045 
1046  out << "\n }";
1047  delimiter = ',';
1048  }
1049 
1050  out << "\n}" << endl;
1051  return out;
1052 }
1053 
1055 {
1056  bool done = true;
1057 
1058  GetDiagContext().Extra().Print("ctg_poll", "true");
1059  m_GridClient->SetJobKey(grid_ctx.GetJobKey());
1060 
1062 
1063  if (m_RefreshWait) {
1064  CDeadline wait_deadline(m_RefreshWait);
1065 
1066  status =
1068  grid_ctx.GetJobKey(),
1069  wait_deadline,
1073  }
1074 
1075  if (!grid_ctx.HasCtgTime()) {
1076  status = GetStatusAndCtgTime(grid_ctx);
1077 
1078  } else if (!m_RefreshWait) {
1079  status = GetStatus(grid_ctx);
1080  }
1081 
1082  done = CheckIfJobDone(grid_ctx, status);
1083 
1084  if (done)
1085  grid_ctx.Clear();
1086  else {
1087  // Check if job cancellation has been requested
1088  // via the user interface(HTML).
1089  if (GetArgs()["Cancel"] ||
1090  !grid_ctx.GetPersistentEntryValue("Cancel").empty())
1091  m_GridClient->CancelJob(grid_ctx.GetJobKey());
1092 
1093  DefineRefreshTags(grid_ctx, grid_ctx.GetSelfURL(), m_RefreshDelay);
1094  }
1095 }
1096 
1098  CGridCgiContext& grid_ctx)
1099 {
1100  bool done = true;
1101 
1102  if (!m_AffinityName.empty()) {
1103  string affinity;
1105  if (!affinity.empty()) {
1106  if (m_AffinitySetLimit > 0) {
1108  crc32.AddChars(affinity.data(), affinity.length());
1109  affinity = NStr::UIntToString(
1110  crc32.GetChecksum() % m_AffinitySetLimit);
1111  }
1112  m_GridClient->SetJobAffinity(affinity);
1113  }
1114  }
1115  try {
1116  // The job is ready to be sent to the queue.
1117  // Prepare the input data.
1118  CNcbiOstream& os = m_GridClient->GetOStream();
1119  // Send the input data.
1120  request.Serialize(os);
1121  string saved_content(kEmptyStr);
1122  try {
1123  saved_content = request.GetContent();
1124  }
1125  catch (...) {
1126  // An exception is normal when the content
1127  // is not saved, disregard the exception.
1128  }
1129  if (!saved_content.empty())
1130  os.write(saved_content.data(), saved_content.length());
1131 
1133  NStr::NumericToString(GetFastLocalTime().GetTimeT()));
1134 
1135  CNetScheduleAPI::EJobStatus status = m_GridClient->SubmitAndWait(m_FirstDelay);
1136 
1137  CNetScheduleJob& job(m_GridClient->GetJob());
1138 
1139  grid_ctx.GetJobKey() = job.job_id;
1140 
1141  grid_ctx.DefinePersistentEntry("job_key", grid_ctx.GetJobKey());
1142  GetDiagContext().Extra().Print("job_key", grid_ctx.GetJobKey());
1143 
1144  done = !s_IsPendingOrRunning(status) && CheckIfJobDone(grid_ctx, status);
1145 
1146  if (!done) {
1147  // The job has just been submitted.
1148  // Render a report page
1149  grid_ctx.SelectView("JOB_SUBMITTED");
1150  DefineRefreshTags(grid_ctx, grid_ctx.GetSelfURL(),
1151  m_RefreshDelay);
1152  }
1153  }
1154  catch (CNetScheduleException& ex) {
1155  ERR_POST("Failed to submit a job: " << ex.what());
1156  OnJobFailed(ex.GetErrCode() ==
1158  "NetSchedule Queue is busy" : m_ExceptionMessage(ex.what()), grid_ctx);
1159  done = true;
1160  }
1161  catch (CCgiRequestException&) {
1162  // Pass input validator exception
1163  throw;
1164  }
1165  catch (exception& ex) {
1166  ERR_POST("Failed to submit a job: " << ex.what());
1167  OnJobFailed(m_ExceptionMessage(ex.what()), grid_ctx);
1168  done = true;
1169  }
1170 
1171  if (done)
1172  grid_ctx.Clear();
1173 }
1174 
1176 {
1177  grid_ctx.AddTagMap("SELF_URL", grid_ctx.GetSelfURL(), CHTMLPlainText::eNoEncode);
1178 
1179  if (!m_HTMLPassThrough) {
1180  // Preserve persistent entries as hidden fields
1181  string hidden_fields;
1183  grid_ctx.GetPersistentEntries().begin();
1184  it != grid_ctx.GetPersistentEntries().end(); ++it)
1185  hidden_fields += "<INPUT TYPE=\"HIDDEN\" NAME=\"" + it->first
1186  + "\" VALUE=\"" + NStr::HtmlEncode(it->second) + "\">\n";
1187  m_Page->AddTagMap("HIDDEN_FIELDS",
1188  new CHTMLPlainText(hidden_fields, true));
1189  }
1190 
1191  CTime now(GetFastLocalTime());
1192  m_Page->AddTagMap("DATE",
1193  new CHTMLText(now.AsString(m_DateFormat)));
1194  string since_time = grid_ctx.GetPersistentEntryValue(kSinceTime);
1195  if (!since_time.empty()) {
1196  grid_ctx.AddTagMap("SINCE_TIME", since_time);
1197  time_t tt = NStr::StringToInt(since_time);
1198  CTime start;
1199  start.SetTimeT(tt);
1200  m_Page->AddTagMap("SINCE",
1201  new CHTMLText(start.AsString(m_DateFormat)));
1202  CTimeSpan ts = now - start;
1203  m_Page->AddTagMap("ELAPSED_TIME_MSG_HERE",
1204  new CHTMLText("<@ELAPSED_TIME_MSG@>"));
1205  m_Page->AddTagMap("ELAPSED_TIME",
1207  }
1208  grid_ctx.AddTagMap("JOB_ID", grid_ctx.GetJobKey());
1209  if (m_AddJobIdToHeader) {
1211  }
1212  string progress_message;
1213  try {
1214  progress_message = m_GridClient->GetProgressMessage();
1215  }
1216  catch (CException& e) {
1217  ERR_POST("Could not retrieve progress message for " <<
1218  grid_ctx.GetJobKey() << ": " << e);
1219  }
1220  grid_ctx.SetJobProgressMessage(progress_message);
1221  grid_ctx.GetHTMLPage().AddTagMap("PROGERSS_MSG",
1222  new CHTMLPlainText(m_TargetEncodeMode, progress_message));
1223  grid_ctx.GetHTMLPage().AddTagMap("PROGRESS_MSG",
1224  new CHTMLPlainText(m_TargetEncodeMode, progress_message));
1225 }
1226 
1228 {
1230 
1231  // Compose and flush the resultant HTML page
1232  try {
1233  CRegexpTemplateFilter page_filter(m_Page.get());
1234  CRegexpTemplateFilter header_filter(m_CustomHTTPHeader.get());
1235 
1236  vector<string>::const_iterator it;
1237  for (it = m_HtmlIncs.begin(); it != m_HtmlIncs.end(); ++it) {
1238  string lib = NStr::TruncateSpaces(*it);
1239  m_Page->LoadTemplateLibFile(lib, &page_filter);
1240  m_CustomHTTPHeader->LoadTemplateLibFile(lib, &header_filter);
1241  }
1242 
1243  stringstream header_stream;
1244  m_CustomHTTPHeader->Print(header_stream, CNCBINode::ePlainText);
1245 
1246  string header_line;
1247  string status_line;
1248 
1249  enum {
1250  eNoStatusLine,
1251  eReadingStatusLine,
1252  eGotStatusLine
1253  } status_line_status = eNoStatusLine;
1254 
1255  while (header_stream.good()) {
1256  getline(header_stream, header_line);
1257  if (header_line.empty())
1258  continue;
1259  if (status_line_status == eReadingStatusLine) {
1260  if (isspace(header_line[0])) {
1261  status_line += header_line;
1262  continue;
1263  }
1264  status_line_status = eGotStatusLine;
1265  }
1266  if (NStr::StartsWith(header_line, "Status:", NStr::eNocase)) {
1267  status_line_status = eReadingStatusLine;
1268  status_line = header_line;
1269  continue;
1270  }
1271  out << header_line << "\r\n";
1272  }
1273  if (status_line_status != eNoStatusLine) {
1274  CTempString status_code_and_reason(
1275  status_line.data() + (sizeof("Status:") - 1),
1276  status_line.size() - (sizeof("Status:") - 1));
1277  NStr::TruncateSpacesInPlace(status_code_and_reason);
1278  CTempString status_code, reason;
1279  NStr::SplitInTwo(status_code_and_reason, CTempString(" \t", 2),
1280  status_code, reason,
1282  m_Response->SetStatus(NStr::StringToUInt(status_code), reason);
1283  }
1285  m_Page->Print(out, CNCBINode::eHTML);
1286  }
1287  catch (CCgiRequestException&) {
1288  // Pass input validator exception
1289  throw;
1290  }
1291  catch (exception& e) {
1292  if (!out) {
1293  ERR_POST(Warning << "Failed to write " << m_Title << " HTML page to client: " << e.what());
1294  return 0;
1295  }
1296 
1297  ERR_POST("Failed to compose/send " << m_Title <<
1298  " HTML page: " << e.what());
1299  return 4;
1300  }
1301 
1302  return 0;
1303 }
1304 
1306  const string& url, int idelay)
1307 {
1308  const auto idelay_str = NStr::IntToString(idelay);
1309 
1310  if (!m_HTMLPassThrough && idelay >= 0 && grid_ctx.NeedMetaRefresh()) {
1311  CHTMLText* redirect = new CHTMLText(
1312  "<META HTTP-EQUIV=Refresh "
1313  "CONTENT=\"<@REDIRECT_DELAY@>; URL=<@REDIRECT_URL@>\">");
1314  m_Page->AddTagMap("REDIRECT", redirect);
1315 
1316  CHTMLPlainText* delay = new CHTMLPlainText(idelay_str);
1317  m_Page->AddTagMap("REDIRECT_DELAY", delay);
1318  }
1319 
1320  grid_ctx.AddTagMap("REDIRECT_URL", url, CHTMLPlainText::eNoEncode);
1321  m_Response->SetHeaderValue("Expires", "0");
1322  m_Response->SetHeaderValue("Pragma", "no-cache");
1323  m_Response->SetHeaderValue("Cache-Control",
1324  "no-cache, no-store, max-age=0, private, must-revalidate");
1325 
1326  if (idelay >= 0) {
1327  m_Response->SetHeaderValue("NCBI-RCGI-RetryURL", url);
1328 
1329  // Must correspond to SRCgiWait values
1332  }
1333 }
1334 
1335 
1337  CGridCgiContext& grid_ctx)
1338 {
1340  try {
1341  status = m_GridClient->GetStatus();
1342  }
1343  catch (CNetSrvConnException& e) {
1344  ERR_POST("Failed to retrieve job status for " <<
1345  grid_ctx.GetJobKey() << ": " << e);
1346 
1348 
1350 
1351  CNetServer bad_server(service.GetServer(key.host, key.port));
1352 
1353  // Skip to the next available server in the service.
1354  // If the server that caused a connection exception
1355  // was the only server in the service, rethrow the
1356  // exception.
1357  CNetServiceIterator it(service.ExcludeServer(bad_server));
1358 
1359  if (!it)
1360  throw;
1361 
1362  CNetScheduleAdmin::TQueueInfo queue_info;
1363 
1364  m_NetScheduleAPI.GetAdmin().GetQueueInfo(it.GetServer(), queue_info);
1365 
1366  if ((Uint8) GetFastLocalTime().GetTimeT() > NStr::StringToUInt8(
1367  grid_ctx.GetPersistentEntryValue(kSinceTime)) +
1368  NStr::StringToUInt(queue_info["timeout"]))
1370  else {
1371  status = CNetScheduleAPI::eRunning;
1372  grid_ctx.GetHTMLPage().AddTagMap("MSG",
1374  "Failed to retrieve job status: " + e.GetMsg()));
1375  }
1376  }
1377 
1378  return status;
1379 }
1380 
1381 void s_GetCtgTime(CGridCgiContext& grid_ctx, string event)
1382 {
1383  const CTempString kTimestamp = "timestamp";
1384  const string kFormat = "M/D/Y h:m:G";
1385 
1386  CAttrListParser parser;
1387  parser.Reset(event);
1388  CTempString name;
1389  string value;
1390  size_t column;
1391 
1392  do {
1393  if (parser.NextAttribute(&name, &value, &column) == CAttrListParser::eNoMoreAttributes) return;
1394  } while (name != kTimestamp);
1395 
1396  grid_ctx.DefinePersistentEntry(kSinceTime, NStr::NumericToString(CTime(value, kFormat).GetTimeT()));
1397 }
1398 
1400 {
1401  const string kStatus = "status: ";
1402  const string kEvent1 = "event1: ";
1403 
1405  auto output = m_NetScheduleAPI.GetAdmin().DumpJob(grid_ctx.GetJobKey());
1406  string line;
1407 
1408  while (output.ReadLine(line)) {
1409  if (NStr::StartsWith(line, kStatus)) {
1410  rv = CNetScheduleAPI::StringToStatus(line.substr(kStatus.size()));
1411 
1412  } else if (NStr::StartsWith(line, kEvent1)) {
1413  s_GetCtgTime(grid_ctx, line.substr(kEvent1.size()));
1414  }
1415  }
1416 
1417  return rv;
1418 }
1419 
1421  CGridCgiContext& grid_ctx, CNetScheduleAPI::EJobStatus status)
1422 {
1423  bool done = true;
1424  const string status_str = CNetScheduleAPI::StatusToString(status);
1425  m_Response->SetHeaderValue("NCBI-RCGI-JobStatus",
1426  status_str);
1427  grid_ctx.GetHTMLPage().AddTagMap("JOB_STATUS",
1428  new CHTMLPlainText(status_str, true));
1429 
1430  switch (status) {
1432  // The worker node has finished the job and the
1433  // result is ready to be retrieved.
1434  OnJobDone(grid_ctx);
1435  break;
1436 
1438  // a job has failed
1439  OnJobFailed(m_GridClient->GetErrorMessage(), grid_ctx);
1440  break;
1441 
1443  // The job has been canceled
1445  // Render a job cancellation page
1446  grid_ctx.SelectView("JOB_CANCELED");
1447 
1448  DefineRefreshTags(grid_ctx, m_FallBackUrl.empty() ?
1449  grid_ctx.GetSelfURL(false) : m_FallBackUrl,
1451  break;
1452 
1454  // The job has expired
1455  OnJobFailed("Job is not found.", grid_ctx);
1456  break;
1457 
1459  // The job is in the NetSchedule queue and
1460  // is waiting for a worker node.
1461  // Render a status report page
1462  grid_ctx.SelectView("JOB_PENDING");
1463  done = false;
1464  break;
1465 
1467  // The job is being processed by a worker node
1468  // Render a status report page
1469  grid_ctx.SelectView("JOB_RUNNING");
1470  done = false;
1471  break;
1472 
1473  default:
1474  LOG_POST(Note << "Unexpected job state");
1475  }
1476  SetRequestId(grid_ctx.GetJobKey(), status == CNetScheduleAPI::eDone);
1477  return done;
1478 }
1479 
1481 {
1483 
1484  string err_msg;
1485 
1486  try {
1487  bool no_jquery = ctx.GetJqueryCallback().empty();
1488 
1489  // No need to amend anything
1490  if (no_jquery && !m_AddJobIdToHeader) {
1491  NcbiStreamCopy(out, is);
1492  ctx.NeedRenderPage(false);
1493  return;
1494  }
1495 
1496  // Amending HTTP header
1497  string header_line;
1498  while (getline(is, header_line)) {
1500  if (header_line.empty())
1501  break;
1502 
1503  if (no_jquery)
1504  out << header_line << "\r\n";
1505  else if (NStr::StartsWith(header_line, "Content-Type", NStr::eNocase))
1506  out << "Content-Type: text/javascript\r\n";
1507  else if (!NStr::StartsWith(header_line, "Content-Length", NStr::eNocase))
1508  out << header_line << "\r\n";
1509  }
1510 
1511  if (m_AddJobIdToHeader) {
1512  out << HTTP_NCBI_JSID << ": " << ctx.GetJobKey() << "\r\n";
1513  }
1514 
1515  out << "\r\n";
1516 
1517  if (no_jquery) {
1518  NcbiStreamCopy(out, is);
1519  } else {
1520  out << ctx.GetJqueryCallback() << '(';
1521  NcbiStreamCopy(out, is);
1522  out << ')';
1523  }
1524  ctx.NeedRenderPage(false);
1525  return;
1526  }
1527  catch (CException& ex) {
1528  err_msg = ex.ReportAll();
1529  }
1530  catch (exception& ex) {
1531  err_msg = ex.what();
1532  }
1533 
1534  if (!is) {
1535  ERR_POST("Failed to read job output: " << err_msg);
1536  OnJobFailed("Failed to read job output: " + m_ExceptionMessage(err_msg), ctx);
1537  } else if (!out) {
1538  ERR_POST(Warning << "Failed to write job output to client: " << err_msg);
1539  ctx.NeedRenderPage(false); // Client will not get the message anyway
1540  } else {
1541  ERR_POST("Failed while relaying job output: " << err_msg);
1542  OnJobFailed("Failed while relaying job output: " + m_ExceptionMessage(err_msg), ctx);
1543  }
1544 }
1545 
1547 {
1548  if (m_DisplayDonePage) {
1549  string get_results;
1550  ctx.PullUpPersistentEntry("get_results", get_results);
1551 
1552  if (get_results.empty()) {
1553  ctx.SelectView("JOB_DONE");
1554  DefineRefreshTags(ctx, ctx.GetSelfURL() + "&get_results=true", m_RefreshDelay);
1555  return;
1556  }
1557  }
1558 
1559  CNcbiIstream& is = m_GridClient->GetIStream();
1560 
1561  // This must be after m_GridClient->GetIStream(), otherwise size would be empty
1562  if (m_GridClient->GetBlobSize() > 0) {
1563  ReadJob(is, ctx);
1564  } else {
1565  const char* str_page;
1566 
1567  switch (m_TargetEncodeMode) {
1569  str_page = "<html><head><title>Empty Result</title>"
1570  "</head><body>Empty Result</body></html>";
1571  break;
1573  str_page = "{}";
1574  break;
1575  default:
1576  str_page = "";
1577  }
1578 
1579  ctx.GetHTMLPage().SetTemplateString(str_page);
1580  }
1581 }
1582 
1583 void CCgi2RCgiApp::OnJobFailed(const string& msg,
1585 {
1586  ctx.DefinePersistentEntry(kSinceTime, kEmptyStr);
1587  // Render a error page
1588  ctx.SelectView("JOB_FAILED");
1589 
1590  string fall_back_url = m_FallBackUrl.empty() ?
1591  ctx.GetSelfURL(false) : m_FallBackUrl;
1592  DefineRefreshTags(ctx, fall_back_url, m_FallBackDelay);
1593 
1594  ctx.GetHTMLPage().AddTagMap("MSG",
1596 }
1597 
1598 /////////////////////////////////////////////////////////////////////////////
1599 int main(int argc, const char* argv[])
1600 {
1602 
1604  CCgi2RCgiApp app;
1605  return app.AppMain(argc, argv);
1606 }
static Int32 incs[14]
Definition: blocksort.c:480
EEntryPulling
Definition: cgi2rcgi.cpp:71
static const string kSinceTime
Definition: cgi2rcgi.cpp:69
#define HTTP_NCBI_JSID
Definition: cgi2rcgi.cpp:67
USING_NCBI_SCOPE
Definition: cgi2rcgi.cpp:65
Checksum and hash calculation classes.
CArgDescriptions –.
Definition: ncbiargs.hpp:541
CArgException –.
Definition: ncbiargs.hpp:120
ENextAttributeType NextAttribute(CTempString *attr_name, string *attr_value, size_t *attr_column)
void Reset(const char *position, const char *eol)
CCgiRequestException –.
CCgiRequest::
Definition: ncbicgi.hpp:685
CChecksum – Checksum calculator.
Definition: checksum.hpp:302
Pool of recycled CCompoundID objects.
CDeadline.
Definition: ncbitime.hpp:1830
Grid CGI Context Context in which a request is processed.
Definition: grid_cgiapp.hpp:68
void SetJobProgressMessage(const string &msg)
Definition: cgi2rcgi.cpp:300
void DefinePersistentEntry(const string &entry_name, const string &value)
void PullUpPersistentEntry(const string &entry_name)
CHTMLPage & GetHTMLPage()
Definition: cgi2rcgi.cpp:260
bool NeedRenderPage() const
Definition: cgi2rcgi.cpp:289
const string & GetJobProgressMessage() const
Definition: cgi2rcgi.cpp:266
Grid Client (the submitter).
CHTMLPage –.
Definition: page.hpp:161
CNcbiArguments –.
Definition: ncbienv.hpp:236
CNcbiEnvironment –.
Definition: ncbienv.hpp:110
CNcbiRegistry –.
Definition: ncbireg.hpp:913
Client API for NetCache server.
Client API for NCBI NetSchedule server.
void GetQueueInfo(CNetServer server, const string &queue_name, TQueueInfo &queue_info)
void DumpJob(CNcbiOstream &out, const string &job_key)
NetSchedule internal exception.
CNetScheduleAPI::EJobStatus WaitForJobEvent(const string &job_key, CDeadline &deadline, CNetScheduleAPI ns_api, TJobStatusMask status_mask, int last_event_index=kMax_Int, int *new_event_index=NULL)
Smart pointer to the job submission part of the NetSchedule API.
CNetServer GetServer(unsigned host, unsigned short port)
CNetServiceIterator ExcludeServer(CNetServer::TInstance server)
Start iteration excluding 'server' (return the next server after 'server' or NULL).
Net Service exception.
CRegexp –.
Definition: regexp.hpp:74
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
CTimeSpan.
Definition: ncbitime.hpp:1313
CTime –.
Definition: ncbitime.hpp:296
CTimeout – Timeout interval.
Definition: ncbitime.hpp:1693
void erase(iterator pos)
Definition: map.hpp:167
container_type::const_iterator const_iterator
Definition: map.hpp:53
const_iterator begin() const
Definition: map.hpp:151
const_iterator end() const
Definition: map.hpp:152
void clear()
Definition: map.hpp:169
const_iterator find(const key_type &key) const
Definition: map.hpp:153
static CMemoryRegistry registry
Definition: cn3d_tools.cpp:81
Diagnostic handler for embedding diagnostics in comments.
void(*)(CSeq_entry_Handle seh, IWorkbench *wb, const CSerialObject &obj) handler
The NCBI C++ standard methods for dealing with std::string.
struct config config
static uch flags
std::ofstream out("events_result.xml")
main entry point for tests
CS_CONTEXT * ctx
Definition: t0006.c:12
static void get_results(DBPROCESS *dbproc, int start)
Definition: t0006.c:17
#define true
Definition: bool.h:35
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
static SQLCHAR output[256]
Definition: print.c:5
static const char * column
Definition: stats.c:23
static HENV env
Definition: transaction2.c:38
static FILE * f
Definition: readconf.c:23
#define GRID_APP_CHECK_VERSION_ARGS()
NetSchedule Framework specs.
CNcbiEnvironment & SetEnvironment(void)
Get a non-const copy of the application's cached environment.
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:832
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
CNcbiRegistry & GetRWConfig(void)
Get the application's cached configuration parameters, accessible for read-write for an application's...
const CNcbiArguments & GetArguments(void) const
Get the application's cached unprocessed command-line arguments.
@ eString
An arbitrary string.
Definition: ncbiargs.hpp:589
virtual void SetupArgDescriptions(CArgDescriptions *arg_desc)
Setup the command line argument descriptions.
Definition: cgiapp.cpp:794
const CCgiRequest & GetRequest(void) const
Definition: cgictx.hpp:374
void SetRequestFlags(int flags)
Set cgi parsing flag.
Definition: cgiapp.hpp:130
void Init(void) override
This method is called on the CGI application initialization – before starting to process a HTTP reque...
void RegisterDiagFactory(const string &key, CDiagFactory *fact)
Definition: cgiapp.cpp:1259
virtual const CArgs & GetArgs(void) const
Get parsed command line arguments extended with CGI parameters.
Definition: cgiapp.cpp:1065
void SetRequestId(const string &rid, bool is_done)
Definition: cgiapp.cpp:1462
virtual CCgiContext * CreateContextWithFlags(CNcbiArguments *args, CNcbiEnvironment *env, CNcbiIstream *inp, CNcbiOstream *out, int ifd, int ofd, int flags)
The same as CreateContext(), but allows for a custom set of flags to be specified in the CCgiRequest ...
Definition: cgiapp.cpp:912
const string & GetSelfURL(ESelfUrlPort) const
Using HTTP environment variables, compose the CGI's own URL as: SCHEME://SERVER_NAME[:SERVER_PORT]/SC...
Definition: cgictx.hpp:217
#define NCBI_CGI_THROW_WITH_STATUS(exception, err_code, message, status)
const TCgiEntries & GetEntries(void) const
Get a set of entries(decoded) received from the client.
Definition: ncbicgi.hpp:1181
static SIZE_TYPE ParseEntries(const string &str, TCgiEntries &entries)
Decode the URL-encoded(FORM or ISINDEX) string "str" into a set of entries <"name",...
Definition: ncbicgi.cpp:1530
void SetHeaderValue(const string &name, const string &value)
Definition: ncbicgir.cpp:151
void Serialize(CNcbiOstream &os) const
Serialize/Deserialize a request to/from a stream.
Definition: ncbicgi.cpp:1566
CNcbiOstream & out(void) const
Get output stream. Throw exception if GetOutput() is NULL.
Definition: ncbicgir.cpp:257
void SetStatus(unsigned int code, const string &reason=kEmptyStr)
Definition: ncbicgir.cpp:197
void RequireWriteHeader(bool require)
Define if WriteHeader() must be called or can be skipped.
Definition: ncbicgir.hpp:401
const string & GetProperty(ECgiProp prop) const
Get value of a "standard" property (return empty string if not defined)
Definition: ncbicgi.cpp:1432
const string & GetContent(void) const
Get request content.
Definition: ncbicgi.cpp:1416
void SetContentType(const string &type)
Set content type (text/html by default if not provided)
Definition: ncbicgir.hpp:337
const string & GetRandomProperty(const string &key, bool http=true) const
Get value of a random client property; if "http" is TRUE then add prefix "HTTP_" to the property name...
Definition: ncbicgi.cpp:1438
CNcbiOstream & WriteHeader(void) const
Write HTTP response header to the output stream.
Definition: ncbicgir.hpp:396
int TFlags
Startup initialization.
Definition: ncbicgi.hpp:703
static const string GetPropertyName(ECgiProp prop)
Get name (not value!) of a "standard" property.
Definition: ncbicgi.cpp:949
@ eCgi_ContentLength
Definition: ncbicgi.hpp:392
@ eCgi_QueryString
Definition: ncbicgi.hpp:399
@ eCgi_ServerPort
Definition: ncbicgi.hpp:384
@ fSaveRequestContent
Save request content (available through GetContent())
Definition: ncbicgi.hpp:720
@ fDoNotParseContent
do not automatically parse the request's content body (from "istr")
Definition: ncbicgi.hpp:712
@ fCaseInsensitiveArgs
use case insensitive CGI arguments
Definition: ncbicgi.hpp:714
#define NULL
Definition: ncbistd.hpp:225
CDiagContext_Extra & Print(const string &name, const string &value)
The method does not print the argument, but adds it to the string.
Definition: ncbidiag.cpp:2622
CDiagContext & GetDiagContext(void)
Get diag context instance.
Definition: logging.cpp:818
CDiagContext_Extra Extra(void) const
Create a temporary CDiagContext_Extra object.
Definition: ncbidiag.hpp:2095
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
static void SetOldPostFormat(bool value)
Set old/new format flag.
Definition: ncbidiag.cpp:3352
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
Definition: ncbidiag.hpp:226
TErrCode GetErrCode(void) const
Get error code.
Definition: ncbiexpt.cpp:453
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
void Warning(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1191
string ReportAll(TDiagPostFlags flags=eDPF_Exception) const
Report all exceptions.
Definition: ncbiexpt.cpp:370
#define NCBI_THROW_FMT(exception_class, err_code, message)
The same as NCBI_THROW but with message processed as output to ostream.
Definition: ncbiexpt.hpp:719
virtual const char * what(void) const noexcept
Standard report (includes full backlog).
Definition: ncbiexpt.cpp:342
#define FORMAT(message)
Format message using iostreams library.
Definition: ncbiexpt.hpp:672
virtual CNCBINode * MapTag(const string &name)
Resolve <@XXX> tag.
Definition: page.cpp:175
class CHTMLPage::CTemplateLibFilter TTemplateLibFilter
Interface for a filter, which must be passed to one the LoadTemplateLib methods to select relevant pa...
virtual void AddTagMap(const string &name, BaseTagMapper *mapper)
Tag mappers.
Definition: page.cpp:289
virtual CNcbiOstream & Print(CNcbiOstream &out, TMode mode=eHTML)
Definition: node.cpp:296
@ eJSONEncode
Encode for JSON output.
Definition: html.hpp:268
@ eNoEncode
Do not encode prior to printing.
Definition: html.hpp:266
@ eHTMLEncode
Encode for HTML output.
Definition: html.hpp:267
@ eHTML
Definition: node.hpp:109
@ ePlainText
Definition: node.hpp:110
vector< SEntry > m_Entries
Definition: cgi2rcgi.cpp:100
static vector< string > GetListenJobs(const string &value)
Definition: cgi2rcgi.cpp:173
bool m_PortAdded
Definition: cgi2rcgi.cpp:544
CCgiContext & m_CgiContext
bool HasCtgTime() const
Definition: cgi2rcgi.cpp:284
string & GetJobKey()
Definition: cgi2rcgi.cpp:293
bool m_InterceptJQueryCallback
Definition: cgi2rcgi.cpp:526
unique_ptr< CHTMLPage > m_Page
Definition: cgi2rcgi.cpp:530
SJob(const string &id)
Definition: cgi2rcgi.cpp:925
CNcbiRegistry * m_Registry
Definition: cgi2rcgi.cpp:240
EJobStatus
Job status codes.
@ eUseQueryString
Definition: cgi2rcgi.cpp:78
@ fMakePersistent
Definition: cgi2rcgi.cpp:74
@ fUseRequestContent
Definition: cgi2rcgi.cpp:73
@ fUseQueryString
Definition: cgi2rcgi.cpp:72
@ eDefaultPulling
Definition: cgi2rcgi.cpp:75
@ eUseRequestContent
Definition: cgi2rcgi.cpp:79
bool CheckIfJobDone(CGridCgiContext &, CNetScheduleAPI::EJobStatus)
Definition: cgi2rcgi.cpp:1420
TCgiEntries m_ParsedQueryString
unique_ptr< CHTMLPage > m_CustomHTTPHeader
Definition: cgi2rcgi.cpp:531
void SetJobProgressMessage(const string &msg)
CNetScheduleSubmitter GetSubmitter()
Create an instance of CNetScheduleSubmitter.
SExceptionMessage m_ExceptionMessage
Definition: cgi2rcgi.cpp:546
void SubmitJob(CCgiRequest &request, CGridCgiContext &grid_ctx)
Definition: cgi2rcgi.cpp:1097
CHTMLPage * m_Page
Definition: cgi2rcgi.cpp:766
CHTMLPlainText::EEncodeMode m_TargetEncodeMode
Definition: cgi2rcgi.cpp:542
string m_ElapsedTimeFormat
Definition: cgi2rcgi.cpp:525
void DefinePersistentEntry(const string &entry_name, const string &value)
Definition: cgi2rcgi.cpp:430
void PullUpPersistentEntry(const string &entry_name)
Save this entry as a cookie add it to serf url.
Definition: cgi2rcgi.cpp:405
SEntry(string n, TF f)
Definition: cgi2rcgi.cpp:109
void Clear()
Remove all persisted entries from cookie and self url.
Definition: cgi2rcgi.cpp:452
void DefineRefreshTags(CGridCgiContext &grid_ctx, const string &url, int delay)
Definition: cgi2rcgi.cpp:1305
CRegexpTemplateFilter(CHTMLPage *page)
Definition: cgi2rcgi.cpp:760
CHTMLPage & GetHTMLPage(void)
Get an HTML page.
Definition: grid_cgiapp.hpp:75
CNetScheduleAPI::EJobStatus GetStatus(CGridCgiContext &)
Definition: cgi2rcgi.cpp:1336
CHTMLPage & m_CustomHTTPHeader
Definition: cgi2rcgi.cpp:312
void NeedRenderPage(bool value)
Definition: cgi2rcgi.cpp:290
EJobStatus GetJobDetails(CNetScheduleJob &job, time_t *job_exptime=NULL, ENetScheduleQueuePauseMode *pause_mode=NULL)
Get job details.
static void s_RemoveCallbackParameter(string *query_string)
Definition: cgi2rcgi.cpp:788
const TPersistentEntries & GetPersistentEntries() const
Definition: cgi2rcgi.cpp:282
function< void(const string &)> m_Func
Definition: cgi2rcgi.cpp:114
CNetScheduleAPI::EJobStatus GetStatusAndCtgTime(CGridCgiContext &grid_ctx)
Definition: cgi2rcgi.cpp:1399
void GetQueryStringEntryValue(const string &entry_name, string &value) const
Definition: cgi2rcgi.cpp:380
int m_FallBackDelay
Definition: cgi2rcgi.cpp:522
bool m_HTMLPassThrough
Definition: cgi2rcgi.cpp:543
bool s_IsPendingOrRunning(CNetScheduleAPI::EJobStatus job_status)
Definition: cgi2rcgi.cpp:908
#define CALLBACK_PARAM
Definition: cgi2rcgi.cpp:786
void SelectView(const string &view_name)
Definition: cgi2rcgi.cpp:457
bool m_DisplayDonePage
Definition: cgi2rcgi.cpp:528
SExceptionMessage(CNcbiRegistry *registry=nullptr)
Definition: cgi2rcgi.cpp:229
string operator()(const string &what)
Definition: cgi2rcgi.cpp:231
map< string, string > TPersistentEntries
Definition: cgi2rcgi.cpp:277
string m_Title
Definition: cgi2rcgi.cpp:520
CNetCacheAPI m_NetCacheAPI
Definition: cgi2rcgi.cpp:507
string m_JqueryCallback
Definition: cgi2rcgi.cpp:318
static void CheckGetResults(const string &value)
Definition: cgi2rcgi.cpp:97
string m_AffinityName
Definition: cgi2rcgi.cpp:536
void CheckEntry(const string &name, const string &value, bool is_requested=true)
Definition: cgi2rcgi.cpp:156
int m_CancelGoBackDelay
Definition: cgi2rcgi.cpp:523
TPersistentEntries m_PersistentEntries
Definition: cgi2rcgi.cpp:315
int m_AffinitySource
Definition: cgi2rcgi.cpp:537
string GetSelfURL(void) const
Get Self URL.
Definition: grid_cgiapp.cpp:75
int m_RefreshDelay
Definition: cgi2rcgi.cpp:502
CNetScheduleAPI::EJobStatus status
Definition: cgi2rcgi.cpp:922
CHTMLPage & m_Page
virtual bool TestAttribute(const string &attr_name, const string &test_pattern)
Definition: cgi2rcgi.cpp:769
static const string kPlainTextView
Definition: cgi2rcgi.cpp:755
static string StatusToString(EJobStatus status)
Printable status type.
bool NeedMetaRefresh() const
Definition: cgi2rcgi.cpp:291
bool NeedRenderPage() const
int m_AffinitySetLimit
Definition: cgi2rcgi.cpp:538
void ReadJob(istream &, CGridCgiContext &)
Definition: cgi2rcgi.cpp:1480
int m_RefreshWait
Definition: cgi2rcgi.cpp:503
void s_GetCtgTime(CGridCgiContext &grid_ctx, string event)
Definition: cgi2rcgi.cpp:1381
string m_HtmlTemplate
Definition: cgi2rcgi.cpp:533
SInputValidator m_InputValidator
Definition: cgi2rcgi.cpp:545
int m_FirstDelay
Definition: cgi2rcgi.cpp:504
string m_DateFormat
Definition: cgi2rcgi.cpp:524
static const string kGridCgiForm
Definition: cgi2rcgi.cpp:750
void LoadQueryStringTags(CHTMLPlainText::EEncodeMode encode_mode)
Definition: cgi2rcgi.cpp:443
const string & GetJobKey(void) const
Get Current job key.
virtual CCgiContext * CreateContextWithFlags(CNcbiArguments *args, CNcbiEnvironment *env, CNcbiIstream *inp, CNcbiOstream *out, int ifd, int ofd, int flags)
The same as CreateContext(), but allows for a custom set of flags to be specified in the CCgiRequest ...
Definition: cgi2rcgi.cpp:717
string m_ContentType
Definition: cgi2rcgi.cpp:540
string m_FallBackUrl
Definition: cgi2rcgi.cpp:521
virtual int ProcessRequest(CCgiContext &ctx)
This is the method you should override.
Definition: cgi2rcgi.cpp:807
static CDeadline GetDeadline(const string &value)
Definition: cgi2rcgi.cpp:185
SInputValidator & m_InputValidator
Definition: cgi2rcgi.cpp:310
static void CheckCancel(const string &value)
Definition: cgi2rcgi.cpp:211
void PopulatePage(CGridCgiContext &grid_ctx)
Definition: cgi2rcgi.cpp:1175
int RenderPage()
Definition: cgi2rcgi.cpp:1227
virtual void Init()
This method is called on the CGI application initialization – before starting to process a HTTP reque...
Definition: cgi2rcgi.cpp:549
CCgiResponse * m_Response
Definition: cgi2rcgi.cpp:509
int main(int argc, const char *argv[])
Definition: cgi2rcgi.cpp:1599
void AddAffinityEntry(string name)
Definition: cgi2rcgi.cpp:168
bool m_AddJobIdToHeader
Definition: cgi2rcgi.cpp:527
const string & GetPersistentEntryValue(const string &entry_name) const
Definition: cgi2rcgi.cpp:371
void GetRequestEntryValue(const string &entry_name, string &value) const
Definition: cgi2rcgi.cpp:392
void OnJobFailed(const string &msg, CGridCgiContext &ctx)
Definition: cgi2rcgi.cpp:1583
void OnJobDone(CGridCgiContext &)
Definition: cgi2rcgi.cpp:1546
CNetService GetService()
void CheckJob(CGridCgiContext &grid_ctx)
Definition: cgi2rcgi.cpp:1054
void ListenJobs(const string &job_ids_value, const string &timeout_value)
Definition: cgi2rcgi.cpp:933
static void CheckCtgTime(const string &value)
Definition: cgi2rcgi.cpp:96
CNetScheduleAPIExt m_NetScheduleAPI
Definition: cgi2rcgi.cpp:506
static void CheckJobKey(const string &value)
Definition: cgi2rcgi.cpp:196
unique_ptr< CGridClient > m_GridClient
Definition: cgi2rcgi.cpp:508
bool Check(const string &value)
Definition: cgi2rcgi.cpp:118
static EJobStatus StringToStatus(const CTempString &status_str)
Parse status string into enumerator value.
CNetScheduleAdmin GetAdmin()
friend CNcbiOstream & operator<<(CNcbiOstream &out, SJobs jobs)
Definition: cgi2rcgi.cpp:1028
bool progress_msg_truncated
Definition: cgi2rcgi.cpp:923
string job_id
Output job key.
string & GetJqueryCallback()
Definition: cgi2rcgi.cpp:294
static void CheckAffinity(const string &value)
Definition: cgi2rcgi.cpp:219
bool m_NeedMetaRefresh
Definition: cgi2rcgi.cpp:320
CGridCgiContext(CHTMLPage &page, CCgiContext &ctx)
Definition: grid_cgiapp.cpp:63
vector< string > m_HtmlIncs
Definition: cgi2rcgi.cpp:534
void AddTagMap(const string &n, const string &v, CHTMLPlainText::EEncodeMode m=CHTMLPlainText::eHTMLEncode)
Definition: cgi2rcgi.cpp:303
@ eDone
Job is ready (computed successfully)
@ eCanceled
Explicitly canceled.
@ eRunning
Running on a worker node.
@ eJobNotFound
No such job.
@ ePending
Waiting for execution.
@ eFailed
Failed to run (execution timeout)
uint64_t Uint8
8-byte (64-bit) unsigned integer
Definition: ncbitype.h:105
bool IsMatch(CTempString str, TMatch flags=fMatch_default)
Check existence substring which match a specified pattern.
Definition: regexp.cpp:253
@ fCompile_ignore_case
Definition: regexp.hpp:111
virtual string GetString(const string &section, const string &name, const string &default_value, TFlags flags=0) const
Get the parameter string value.
Definition: ncbireg.cpp:321
@ eReturn
Return default value.
Definition: ncbireg.hpp:203
static const char * kHeader_Url
Definition: retry_ctx.hpp:208
static const char * kHeader_Delay
Definition: retry_ctx.hpp:206
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
IO_PREFIX::istream CNcbiIstream
Portable alias for istream.
Definition: ncbistre.hpp:146
bool NcbiStreamCopy(CNcbiOstream &os, CNcbiIstream &is)
Copy the entire contents of stream "is" to stream "os".
Definition: ncbistre.cpp:211
static bool StringToBool(const CTempString str)
Convert string to bool.
Definition: ncbistr.cpp:2812
NCBI_NS_STD::string::size_type SIZE_TYPE
Definition: ncbistr.hpp:132
#define kEmptyStr
Definition: ncbistr.hpp:123
static int CompareNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive compare of a substring with another string.
Definition: ncbistr.cpp:219
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:630
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3452
static bool MatchesMask(CTempString str, CTempString mask, ECase use_case=eCase)
Match "str" against the "mask".
Definition: ncbistr.cpp:389
static double StringToDouble(const CTempStringEx str, TStringToNumFlags flags=0)
Convert string to double.
Definition: ncbistr.cpp:1381
static string HtmlEncode(const CTempString str, THtmlEncode flags=fHtmlEnc_EncodeAll)
Encode a string for HTML.
Definition: ncbistr.cpp:4113
#define NPOS
Definition: ncbistr.hpp:133
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate whitespace in a string (in-place)
Definition: ncbistr.cpp:3192
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5078
static SIZE_TYPE Find(const CTempString str, const CTempString pattern, ECase use_case=eCase, EDirection direction=eForwardSearch, SIZE_TYPE occurrence=0)
Find the pattern in the string.
Definition: ncbistr.cpp:2882
static string UIntToString(unsigned int value, TNumToStringFlags flags=0, int base=10)
Convert UInt to string.
Definition: ncbistr.hpp:5103
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5406
static Uint8 StringToUInt8(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to Uint8.
Definition: ncbistr.cpp:871
static bool SplitInTwo(const CTempString str, const CTempString delim, string &str1, string &str2, TSplitFlags flags=0)
Split a string into two pieces using the specified delimiters.
Definition: ncbistr.cpp:3545
static unsigned int StringToUInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to unsigned int.
Definition: ncbistr.cpp:642
static string Sanitize(CTempString str, TSS_Flags flags=fSS_print)
Sanitize a string, allowing only specified classes of characters.
Definition: ncbistr.hpp:2878
static string JsonEncode(const CTempString str, EJsonEncode encoding=eJsonEnc_UTF8)
Encode a string for JSON.
Definition: ncbistr.cpp:4625
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
static string URLEncode(const CTempString str, EUrlEncode flag=eUrlEnc_SkipMarkChars)
URL-encode string.
Definition: ncbistr.cpp:6053
static string TruncateSpaces(const string &str, ETrunc where=eTrunc_Both)
Truncate whitespace in a string.
Definition: ncbistr.cpp:3177
@ eJsonEnc_Quoted
Quote resulting string.
Definition: ncbistr.hpp:3096
@ fSplit_Truncate
Definition: ncbistr.hpp:2503
@ fSplit_MergeDelimiters
Merge adjacent delimiters.
Definition: ncbistr.hpp:2500
@ eUrlEnc_URIPath
Encode path part of an URI.
Definition: ncbistr.hpp:3151
@ eTrunc_End
Truncate trailing whitespace only.
Definition: ncbistr.hpp:2241
@ eNocase
Case insensitive compare.
Definition: ncbistr.hpp:1206
string AsString(const CTimeFormat &format=kEmptyStr, TSeconds out_tz=eCurrentTimeZone) const
Transform time to string.
Definition: ncbitime.cpp:1512
string AsString(const CTimeFormat &fmt=kEmptyStr) const
Transform time span to string.
Definition: ncbitime.cpp:2681
void Set(EType type)
Set special value.
Definition: ncbitime.cpp:3577
CTime GetFastLocalTime(void)
Quick and dirty getter of local time.
Definition: ncbitime.cpp:4167
CTime & SetTimeT(const time_t t)
Set time using time_t time value.
Definition: ncbitime.hpp:2298
@ eZero
Zero timeout, equal to CTimeout(0,0).
Definition: ncbitime.hpp:1700
HTML classes.
where both of them are integers Note
yy_size_t n
const struct ncbi::grid::netcache::search::fields::KEY key
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
int isspace(Uchar c)
Definition: ncbictype.hpp:69
Miscellaneous common-use basic types and functionality.
The HTML page.
static const string kStatus
Retry context class.
static const char delimiter[]
static SLJIT_INLINE sljit_ins l(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
static SLJIT_INLINE sljit_ins msg(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
void AddToClientNode(const string &data)
CCompoundIDPool GetCompoundIDPool()
Job description.
Meaningful information encoded in the NetSchedule key.
#define _ASSERT
done
Definition: token1.c:1
C++ wrappers for the Perl-compatible regular expression (PCRE) library.
static wxAcceleratorEntry entries[3]
#define crc32
Definition: zconf_cf.h:43
Modified on Fri Sep 20 14:58:28 2024 by modify_doxy.py rev. 669887