GSI Object Oriented Online Offline (Go4)  GO4-6.2.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
TGo4HttpProxy.cpp
Go to the documentation of this file.
1 // $Id: TGo4HttpProxy.cpp 3462 2022-01-18 07:08:29Z linev $
2 //-----------------------------------------------------------------------
3 // The GSI Online Offline Object Oriented (Go4) Project
4 // Experiment Data Processing at EE department, GSI
5 //-----------------------------------------------------------------------
6 // Copyright (C) 2000- GSI Helmholtzzentrum fuer Schwerionenforschung GmbH
7 // Planckstr. 1, 64291 Darmstadt, Germany
8 // Contact: http://go4.gsi.de
9 //-----------------------------------------------------------------------
10 // This software can be used under the license agreements as stated
11 // in Go4License.txt file which is part of the distribution.
12 //-----------------------------------------------------------------------
13 
14 #include "TGo4HttpProxy.h"
15 
16 #include "TROOT.h"
17 #include "TClass.h"
18 #include "TList.h"
19 #include "TH1.h"
20 #include "TH2.h"
21 #include "TGraph.h"
22 #include "TBufferFile.h"
23 
24 #include "TGo4Condition.h"
25 #include "TGo4Slot.h"
26 #include "TGo4Iter.h"
27 #include "TGo4ObjectProxy.h"
28 #include "TGo4Ratemeter.h"
29 #include "TGo4AnalysisStatus.h"
30 
31 #include <QtNetwork>
32 #include <QTimer>
33 #include <QElapsedTimer>
34 #include <QApplication>
35 #include <QEventLoop>
36 #include <QInputDialog>
37 
39  QObject(),
40  qnam(),
41  fHReply(0),
42  fProxy(p)
43 {
44  connect(&qnam, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)),
45  this, SLOT(authenticationRequiredSlot(QNetworkReply*, QAuthenticator*)));
46 }
47 
49 {
50 }
51 
53 {
54  if (fHReply==0) return;
55 
56  QByteArray res = fHReply->readAll();
57  fHReply->deleteLater();
58  fHReply = 0;
59  fProxy->GetHReply(res);
60 }
61 
62 void QHttpProxy::httpHReqError(QNetworkReply::NetworkError code)
63 {
64  if (gDebug>0)
65  printf("QHttpProxy::httpHReqError %d %s\n", code, fHReply ? fHReply->errorString().toLatin1().constData() : "---");
66  if (fHReply) {
67  fHReply->deleteLater();
68  fHReply = 0;
69  }
70 }
71 
73 {
75  QTimer::singleShot(2000, this, SLOT(updateRatemeter()));
76 }
77 
79 {
80  if (fProxy) fProxy->UpdateHierarchy(kFALSE);
81 }
82 
84 {
86 }
87 
88 
89 void QHttpProxy::StartRequest(const char* url)
90 {
91  fHReply = qnam.get(QNetworkRequest(QUrl(url)));
92 
93  connect(fHReply, SIGNAL(finished()),
94  this, SLOT(httpFinished()));
95 
96  connect(fHReply, SIGNAL(error(QNetworkReply::NetworkError)),
97  this, SLOT(httpHReqError(QNetworkReply::NetworkError)));
98 
99  connect(fHReply, SIGNAL(sslErrors(const QList<QSslError>&)),
100  fHReply, SLOT(ignoreSslErrors()));
101 
102  QSslConfiguration cfg = fHReply->sslConfiguration();
103  cfg.setProtocol(QSsl::AnyProtocol/*QSsl::TlsV1SslV3*/);
104  fHReply->setSslConfiguration(cfg);
105 }
106 
107 void QHttpProxy::authenticationRequiredSlot(QNetworkReply* repl, QAuthenticator* auth)
108 {
109  if (fProxy->fUserName.Length()>0) {
110  auth->setUser(fProxy->fUserName.Data());
111  auth->setPassword(fProxy->fPassword.Data());
112  return;
113  }
114 
115  bool ok = false;
116  QString user_name =
117  QInputDialog::getText(0, tr("Authentication required"),
118  tr("User name:"), QLineEdit::Normal,
119  "", &ok);
120  if (!ok) return;
121  QString passwd =
122  QInputDialog::getText(0, tr("Authentication required"),
123  tr("User password:"), QLineEdit::Password,
124  "", &ok);
125  if (!ok) return;
126 
127  fProxy->fUserName = user_name.toLatin1().constData();
128  fProxy->fPassword = passwd.toLatin1().constData();
129 
130  auth->setUser(user_name);
131  auth->setPassword(passwd);
132 }
133 
134 const char* GetHttpRootClassName(const char* kind)
135 {
136  if ((kind==0) || (*kind==0)) return 0;
137  if (strncmp(kind,"ROOT.", 5)!=0) return 0;
138  if (strcmp(kind+5,"TGo4AnalysisWebStatus")==0) return "TGo4AnalysisStatus";
139  return kind+5;
140 }
141 
142 // ============================================================================================
143 
144 TGo4HttpAccess::TGo4HttpAccess(TGo4HttpProxy* proxy, XMLNodePointer_t node, Int_t kind, const char* extra_arg) :
145  TGo4Access(),
146  fProxy(proxy),
147  fNode(node),
148  fUrlPath(),
149  fKind(kind),
150  fNameAttr(),
151  fKindAttr(),
152  fExtraArg(),
153  fReceiver(0),
154  fRecvPath(),
155  fReply(0)
156 {
157  const char* _name = fProxy->fXML->GetAttr(fNode,"_realname");
158  if (_name == 0) _name = fProxy->fXML->GetAttr(fNode,"_name");
159  if (_name) fNameAttr = _name;
160 
161  fUrlPath = fProxy->MakeUrlPath(node);
162 
163  const char* _kind = fProxy->fXML->GetAttr(fNode,"_kind");
164  if (_kind) fKindAttr = _kind;
165  if (extra_arg!=0) fExtraArg = extra_arg;
166 }
167 
169 {
170  if (fKind==3) return TGraph::Class();
171  if (fKind==4) return gROOT->GetClass("TGo4ParameterStatus");
172  if (fKind==5) return gROOT->GetClass("TTree");
173  if (fKind==6) return gROOT->GetClass("TGo4AnalysisStatus");
174  if (fKind==7) return gROOT->GetClass("TList");
175  if (fKind==8) return gROOT->GetClass("TGo4HistogramStatus");
177 }
178 
179 const char* TGo4HttpAccess::GetObjectName() const
180 {
181  return fNameAttr.Data();
182 }
183 
185 {
186  if (fKind==3) return "TGraph";
187  if (fKind==4) return "TGo4ParameterStatus";
188  if (fKind==6) return "TGo4AnalysisStatus";
189  if (fKind==7) return "TList";
190  if (fKind==8) return "TGo4HistogramStatus";
191 
192  const char* clname = GetHttpRootClassName(fKindAttr.Data());
193 
194  return clname ? clname : "TObject";
195 }
196 
198 {
199  if (rcv==0) return 0;
200 
201  TClass* obj_cl = GetObjectClass();
202  if (obj_cl==0) {
203  printf("TGo4HttpAccess fail to get class %s for object %s\n", GetObjectClassName(), path);
204  return 0;
205  }
206 
207  if (obj_cl->GetBaseClassOffset(TObject::Class()) != 0) {
208  printf("TGo4HttpAccess cannot used class %s not derived from TObject\n", GetObjectClassName());
209  return 0;
210  }
211 
212  fReceiver = rcv;
213  fRecvPath = path;
214 
215  TString url = fProxy->fNodeName;
216  if (fUrlPath.Length()>0) { url.Append("/"); url.Append(fUrlPath); }
217 
218  switch (fKind) {
219  case 0: url.Append("/h.xml?compact"); break;
220  case 1: url.Append("/root.bin.gz"); break;
221  case 2: url.Append("/get.xml"); break;
222  case 3: url.Append("/get.xml.gz?history=100&compact"); break;
223  case 4: url.Append("/exe.bin.gz?method=CreateStatus&_destroy_result_"); break;
224  case 5: url.Append("/exe.bin.gz?method=CreateSampleTree&sample=0&_destroy_result_"); break;
225  case 6: url.Append("/exe.bin.gz?method=CreateStatus&_destroy_result_"); break;
226  case 7: url.Append("/exe.bin.gz?method=Select&max=10000"); break;
227  case 8: url.Form("%s/Control/go4_sniffer/exe.bin.gz?method=CreateItemStatus&_destroy_result_&itemname=\"%s\"", fProxy->fNodeName.Data(), fUrlPath.Data()); break;
228  default: url.Append("/root.bin.gz"); break;
229  }
230 
231  if (fExtraArg.Length()>0) {
232  if (url.Index("?") != kNPOS) url.Append("&"); else url.Append("?");
233  url.Append(fExtraArg);
234  }
235 
236  fReply = fProxy->fComm.qnam.get(QNetworkRequest(QUrl(url.Data())));
237  connect(fReply, SIGNAL(finished()), this, SLOT(httpFinished()));
238 
239  connect(fReply, SIGNAL(error(QNetworkReply::NetworkError)),
240  this, SLOT(httpError(QNetworkReply::NetworkError)));
241 
242  if (gDebug>2) printf("TGo4HttpAccess::AssignObjectTo Request URL %s\n", url.Data());
243 
244  return 2;
245 }
246 
247 void TGo4HttpAccess::httpError(QNetworkReply::NetworkError)
248 {
249  // may do special handling for http errors
250 }
251 
252 
254 {
255  QByteArray res = fReply->readAll();
256  fReply->deleteLater();
257  fReply = 0;
258 
259  if (gDebug>2) printf("TGo4HttpAccess::httpFinished Get reply size %d\n", res.size());
260 
261  // regular ratemeter update used to check connection status
262  if (fUrlPath == "Status/Ratemeter") {
263  Bool_t conn = res.size() > 0;
264 
265  // if proxy in shutdown state - cancel all action in case of communication error
266  if (!conn && fProxy->CheckShutdown()) return;
267 
268  if (!conn) DoObjectAssignement(fReceiver, fRecvPath.Data(), new TNamed("disconnected","title"), kTRUE); else
269  if (fProxy->fConnected != conn) fProxy->UpdateHierarchy(kFALSE);
270 
271  fProxy->fConnected = conn;
272  }
273 
274  // do nothing when nothing received
275  if (res.size()==0) { if (gDebug>0) printf("TGo4HttpAccess::httpFinished error with %s\n", fUrlPath.Data()); return; }
276 
277  if (fKind == 0) {
278 
279  TXMLEngine* xml = fProxy->fXML;
280 
281  XMLDocPointer_t doc = xml->ParseString(res.data());
282 
283  if (doc==0) return;
284 
285  XMLNodePointer_t top = xml->GetChild(xml->DocGetRootElement(doc));
286 
287  xml->FreeAllAttr(fNode);
288 
289  XMLAttrPointer_t attr = xml->GetFirstAttr(top);
290  while (attr!=0) {
291  xml->NewAttr(fNode, 0, xml->GetAttrName(attr), xml->GetAttrValue(attr));
292  attr = xml->GetNextAttr(attr);
293  }
294 
295  XMLNodePointer_t chld;
296  while ((chld = xml->GetChild(top)) != 0) {
297  xml->UnlinkNode(chld);
298  xml->AddChild(fNode, chld);
299  }
300 
301  xml->FreeDoc(doc);
302 
303  if (fProxy->fxParentSlot!=0)
305  }
306 
307  TObject* obj = 0;
308 
309  if (fKind == 2) {
310  TXMLEngine* xml = fProxy->fXML;
311 
312  XMLDocPointer_t doc = xml->ParseString(res.data());
313  if (doc==0) return;
314 
315  XMLNodePointer_t top = xml->DocGetRootElement(doc);
316 
317  const char* _kind = xml->GetAttr(top, "_kind");
318  const char* _name = xml->GetAttr(top, "_name");
319  const char* _title = xml->GetAttr(top, "_title");
320  const char* xtitle = xml->GetAttr(top, "xtitle");
321  const char* ytitle = xml->GetAttr(top, "ytitle");
322  const char* xlabels = xml->GetAttr(top, "xlabels");
323  const char* ylabels = xml->GetAttr(top, "ylabels");
324 
325  if (strcmp(_kind,"ROOT.TH1D")==0) {
326  Int_t nbins = xml->GetIntAttr(top, "nbins");
327  Int_t left = TString(xml->GetAttr(top, "left")).Atof();
328  Int_t right = TString(xml->GetAttr(top, "right")).Atof();
329  TH1D* h1 = new TH1D(_name, _title, nbins, left, right);
330  h1->SetDirectory(0);
331  const char* bins = xml->GetAttr(top, "bins") + 1;
332  for (int n =-3; n<nbins+2; n++) {
333  const char* separ = strpbrk(bins,",]");
334  if (separ==0) { printf("Error parsing histogram bins\n"); break; }
335  if (n>=0) {
336  Double_t v = TString(bins, separ-bins).Atof();
337  h1->SetBinContent(n, v);
338  }
339  bins = separ+1;
340  }
341  h1->ResetStats();
342  obj = h1;
343  } else {
344  Int_t nbins1 = xml->GetIntAttr(top, "nbins1");
345  Int_t left1 = TString(xml->GetAttr(top, "left1")).Atof();
346  Int_t right1 = TString(xml->GetAttr(top, "right1")).Atof();
347  Int_t nbins2 = xml->GetIntAttr(top, "nbins2");
348  Int_t left2 = TString(xml->GetAttr(top, "left2")).Atof();
349  Int_t right2 = TString(xml->GetAttr(top, "right2")).Atof();
350  TH2D* h2 = new TH2D(_name, _title, nbins1, left1, right1, nbins2, left2, right2);
351  h2->SetDirectory(0);
352  const char* bins = xml->GetAttr(top, "bins") + 1;
353  for (int n =-6; n<(nbins1+2)*(nbins2+2); n++) {
354  const char* separ = strpbrk(bins,",]");
355  if (separ==0) { printf("Error parsing histogram bins\n"); break; }
356  if (n>=0) {
357  Double_t v = TString(bins, separ-bins).Atof();
358  h2->SetBinContent(n % (nbins1 + 2), n / (nbins1 + 2), v);
359  }
360  bins = separ+1;
361  }
362  h2->ResetStats();
363  obj = h2;
364  }
365 
366  if (obj!=0) {
367  if (xtitle!=0)
368  ((TH1*)obj)->GetXaxis()->SetTitle(xtitle);
369  if (ytitle!=0)
370  ((TH1*)obj)->GetYaxis()->SetTitle(ytitle);
371  if (xlabels!=0) {
372  TObjArray* arr = TString(xlabels).Tokenize(",");
373  for (int n=0; n<=(arr ? arr->GetLast() : -1);n++)
374  ((TH1*)obj)->GetXaxis()->SetBinLabel(1 + n, arr->At(n)->GetName());
375  delete arr;
376  }
377  if (ylabels!=0) {
378  TObjArray* arr = TString(ylabels).Tokenize(",");
379  for (int n=0; n<=(arr ? arr->GetLast() : -1);n++)
380  ((TH1*)obj)->GetYaxis()->SetBinLabel(1 + n, arr->At(n)->GetName());
381  delete arr;
382  }
383  }
384 
385  xml->FreeDoc(doc);
386 
387  } else
388 
389  if (fKind == 3) {
390  TXMLEngine* xml = fProxy->fXML;
391 
392  // printf("History %s\n", res.data());
393 
394  XMLDocPointer_t doc = xml->ParseString(res.data());
395  if (doc==0) return;
396 
397  XMLNodePointer_t top = xml->DocGetRootElement(doc);
398 
399  XMLNodePointer_t chld = top;
400  Int_t cnt = 0;
401  while (chld!=0) {
402  if (xml->GetAttr(chld, "value") && xml->GetAttr(chld, "time")) cnt++;
403  chld = (chld==top) ? xml->GetChild(top) : xml->GetNext(chld);
404  }
405 
406  TGraph* gr = new TGraph(cnt);
407  gr->SetName(xml->GetAttr(top, "_name"));
408  gr->SetTitle(Form("%s ratemeter", xml->GetAttr(top, "_name")));
409 
410  chld = top;
411  Int_t i = cnt-1;
412  while (chld!=0) {
413  const char* time = xml->GetAttr(chld, "time");
414  const char* value = xml->GetAttr(chld, "value");
415  if ((time!=0) && (value!=0)) {
416  QDateTime tm = QDateTime::fromString(time, Qt::ISODate);
417 #if QT_VERSION < QT_VERSION_CHECK(5,8,0)
418  gr->SetPoint(i, tm.toTime_t(), TString(value).Atof());
419 #else
420  gr->SetPoint(i, tm.toSecsSinceEpoch(), TString(value).Atof());
421 #endif
422  i = (i+1) % cnt;
423  }
424  chld = (chld==top) ? xml->GetChild(top) : xml->GetNext(chld);
425  }
426 
427  xml->FreeDoc(doc);
428  obj = gr;
429 
430  gr->GetXaxis()->SetTimeDisplay(1);
431  gr->GetXaxis()->SetTimeFormat("%H:%M:%S%F1970-01-01 00:00:00");
432  } else {
433 
434  TClass* obj_cl = GetObjectClass();
435 
436  if (gDebug>2) printf("TGo4HttpAccess::httpFinished Reconstruct object class %s\n", obj_cl ? obj_cl->GetName() : "---");
437 
438  if ((obj_cl==0) || (obj_cl->GetBaseClassOffset(TObject::Class()) != 0)) return;
439 
440  obj = (TObject*) obj_cl->New();
441  if (obj==0) {
442  printf("TGo4HttpAccess fail to create object of class %s\n", GetObjectClassName());
443  return;
444  }
445 
446  TBufferFile buf(TBuffer::kRead, res.size(), res.data(), kFALSE);
447  buf.MapObject(obj, obj_cl);
448 
449  obj->Streamer(buf);
450 
451  // workaround - when ratemeter received, check running state
452  if (obj->IsA() == TGo4Ratemeter::Class()) {
453  fProxy->fbAnalysisRunning = ((TGo4Ratemeter*) obj)->IsRunning();
454  }
455 
456  if ((fKind==6) && (obj!=0))
457  fProxy->SetAnalysisReady(kTRUE);
458 
459  }
460 
461  DoObjectAssignement(fReceiver, fRecvPath.Data(), obj, kTRUE);
462 }
463 
464 // =========================================================================
465 
467  protected:
468  TXMLEngine *fXML;
469  XMLNodePointer_t fParent;
470  XMLNodePointer_t fChild;
471 
472  public:
473  TGo4HttpLevelIter(TXMLEngine* xml, XMLNodePointer_t item) :
474  TGo4LevelIter(),
475  fXML(xml),
476  fParent(item),
477  fChild()
478  {
479  }
480 
481  virtual ~TGo4HttpLevelIter() {}
482 
483  virtual Bool_t next()
484  {
485  if (fParent == 0) return kFALSE;
486 
487  while (true) {
488 
489  if (fChild == 0) {
490  fChild = fXML->GetChild(fParent);
491  } else {
492  fChild = fXML->GetNext(fChild);
493  }
494 
495  if (fChild==0) return kFALSE;
496 
497  if (fXML->HasAttr(fChild,"_hidden")) continue;
498 
499  break;
500  }
501 
502  return fChild!=0;
503  }
504 
505  virtual Bool_t isfolder() {
506  return fXML->GetChild(fChild)!=0;
507  }
508 
509  virtual Int_t getflag(const char* flagname)
510  {
511  if (strcmp(flagname,"IsRemote")==0) return 1;
512 
513  if (strcmp(flagname,"IsDeleteProtect")==0)
514  return fXML->HasAttr(fChild, "_can_delete") ? 0 : 1;
515 
516  if (strcmp(flagname,"IsResetProtect")==0)
517  return fXML->HasAttr(fChild, "_no_reset") ? 1 : 0;
518 
519  if (strcmp(flagname,"_numargs")==0) {
520  const char* _numargs = fXML->GetAttr(fChild,"_numargs");
521  return (_numargs==0) ? -1 : TString(_numargs).Atoi();
522  }
523 
524  return -1;
525  }
526 
528  {
529  if (!isfolder()) return 0;
530  return new TGo4HttpLevelIter(fXML,fChild);
531  }
532 
533  virtual TGo4Slot* getslot() { return 0; }
534 
535  virtual const char* name()
536  {
537  const char* real = fXML->GetAttr(fChild,"_realname");
538  return real!=0 ? real : fXML->GetAttr(fChild,"_name");
539  }
540 
541  virtual const char* info() { return fXML->GetAttr(fChild,"_title"); }
542  virtual Int_t sizeinfo() { return 0; }
543 
544  virtual Int_t GetKind() {
545  if (isfolder()) return TGo4Access::kndFolder;
546 
547  if (fXML->HasAttr(fChild,"_go4event")) return TGo4Access::kndEventElement;
548 
549  if (fXML->HasAttr(fChild,"_more")) return TGo4Access::kndMoreFolder;
550 
551  const char* _kind = fXML->GetAttr(fChild,"_kind");
552  if ((_kind!=0) && strcmp(_kind,"Command") == 0) return TGo4Access::kndRootCommand;
553 
554  const char *drawfunc = fXML->GetAttr(fChild,"_drawfunc");
555  if (drawfunc && !strcmp(drawfunc, "GO4.drawParameter")) return TGo4Access::kndGo4Param;
556 
557  const char* classname = GetClassName();
558 
559  if (classname==0) return TGo4Access::kndNone;
560 
561  if (strcmp(classname,"TLeafElement")==0) return TGo4Access::kndTreeLeaf;
562 
563  return TGo4Access::kndObject;
564  }
565 
566  virtual const char* GetClassName()
567  {
568  const char* _kind = fXML->GetAttr(fChild,"_kind");
569  const char* res = GetHttpRootClassName(_kind);
570  if (res!=0) return res;
571  if (_kind && !strcmp(_kind,"rate") && fXML->HasAttr(fChild,"_history")) return "TGraph";
572  return isfolder() ? "TFolder" : 0;
573  }
574 };
575 
576 // =====================================================================
577 
579  TGo4ServerProxy(),
580  fXML(0),
581  fxHierarchy(0),
582  fComm(this),
583  fRateCnt(0),
584  fStatusCnt(0),
585  fDebugCnt(0),
586  fbAnalysisRunning(kFALSE),
587  fUserName(),
588  fPassword(),
589  fConnected(kTRUE),
590  fRegularReq(0)
591 {
592  fXML = new TXMLEngine;
593  fUserName = "anonymous";
594  // SetAccount("observer","go4view");
595  // SetAccount("controller","go4ctrl");
596 }
597 
599 {
600  fXML->FreeDoc(fxHierarchy);
601  fxHierarchy = 0;
602 
603  delete fXML; fXML = 0;
604 }
605 
606 void TGo4HttpProxy::SetAccount(const char* username, const char* passwd)
607 {
608  fUserName = username ? username : "";
609  fPassword = passwd ? passwd : "";
610 }
611 
613 {
615 
616  if (!IsGo4Analysis()) return;
617 
618  TGo4Slot* subslot = new TGo4Slot(fxParentSlot, "Settings", "Analysis configuration");
619  subslot->SetProxy(new TGo4ObjectProxy());
620 
621  subslot = new TGo4Slot(fxParentSlot, "Ratemeter", "Analysis ratemeter");
622  subslot->SetProxy(new TGo4ObjectProxy());
623 
624  subslot = new TGo4Slot(fxParentSlot, "Loginfo", "Latest status messages");
625  subslot->SetProxy(new TGo4ObjectProxy());
626 
627  subslot = new TGo4Slot(fxParentSlot, "Debugoutput", "Debug output of go4 analysis");
628  subslot->SetProxy(new TGo4ObjectProxy());
629 
630  QTimer::singleShot(2000, &fComm, SLOT(updateRatemeter()));
631 }
632 
633 
634 XMLNodePointer_t TGo4HttpProxy::FindItem(const char* name, XMLNodePointer_t curr) const
635 {
636  if (curr==0) curr = fXML->GetChild(fXML->DocGetRootElement(fxHierarchy));
637 
638  if ((curr==0) || (name==0) || (*name==0)) return curr;
639 
640  const char* slash = strchr(name,'/');
641  bool doagain = false;
642 
643  do {
644  int len = (slash==0) ? strlen(name) : (slash - name);
645 
646  XMLNodePointer_t chld = fXML->GetChild(curr);
647  while (chld!=0) {
648  const char* _name = fXML->GetAttr(chld,"_realname");
649  if (_name==0) _name = fXML->GetAttr(chld,"_name");
650 
651  if ((_name!=0) && (strlen(_name) == len) && (strncmp(_name, name, len)==0))
652  return FindItem(slash ? slash+1 : 0, chld);
653 
654  chld = fXML->GetNext(chld);
655  }
656 
657  // we try to process situation when item name contains slashes
658  doagain = slash!=0;
659  if (slash) slash = strchr(slash+1,'/');
660 
661  } while (doagain);
662 
663  return 0;
664 }
665 
666 TString TGo4HttpProxy::MakeUrlPath(XMLNodePointer_t item)
667 {
668  if (item==0) return TString("");
669 
670  XMLNodePointer_t root = fXML->GetChild(fXML->DocGetRootElement(fxHierarchy));
671 
672  TString res;
673 
674  while (item != root) {
675  const char* _name = fXML->GetAttr(item,"_name");
676  if (_name==0) return TString("");
677  if (res.Length()>0)
678  res = TString(_name) + "/" + res;
679  else
680  res = _name;
681 
682  item = fXML->GetParent(item);
683  if (item==0) return TString("");
684  }
685 
686  return res;
687 }
688 
689 
690 void TGo4HttpProxy::GetHReply(QByteArray& res)
691 {
692  if (res.size()==0) return;
693  XMLDocPointer_t doc = fXML->ParseString(res.data());
694 
695  if (doc!=0) {
696  fXML->FreeDoc(fxHierarchy);
697  fxHierarchy = doc;
698  }
699 
700  if (fxParentSlot!=0)
702 }
703 
705 {
706  TGo4ServerProxy::GetContainedObjectInfo(); // evaluate roles
707  fInfoStr +="(";
708  fInfoStr +=GetUserName();
709  fInfoStr +="@";
711  fInfoStr +=")";
712  const char* analname = fXML->GetAttr(FindItem(""), "_analysis_name");
713  if (analname!=0) {
714  fInfoStr += " name:";
715  fInfoStr += analname;
716  }
717 
718  return fInfoStr.Data();
719 }
720 
721 Bool_t TGo4HttpProxy::Connect(const char* nodename)
722 {
723  fNodeName = nodename;
724 
725  if ((fNodeName.Index("http://")!=0) && (fNodeName.Index("https://")!=0))
726  fNodeName = TString("http://") + fNodeName;
727 
728  return UpdateHierarchy(kTRUE);
729 }
730 
732 {
733  return (fxHierarchy!=0) && (fComm.fHReply==0);
734 }
735 
737 {
738  if (fComm.fHReply!=0) return kTRUE;
739 
740  TString req = fNodeName + "/h.xml?compact";
741 
742  fComm.StartRequest(req.Data());
743 
744  if (!sync) return kTRUE;
745 
746  QElapsedTimer t;
747  t.start();
748 
749  // wait several seconds
750  while (t.elapsed() < 5000) {
751  if (fComm.fHReply==0) break;
752  QApplication::processEvents();
753  }
754 
755  return fxHierarchy != 0;
756 }
757 
759 {
760  return fxHierarchy != 0;
761 }
762 
764 {
765  XMLNodePointer_t item = FindItem(name);
766 
767  if (item==0) return 0;
768 
769  const char* _kind = fXML->GetAttr(item,"_kind");
770 
771  Int_t kind = 1;
772 
773  if (!strcmp(_kind,"rate") && fXML->HasAttr(item,"_history")) kind = 3; else
774  if (fXML->HasAttr(item,"_dabc_hist")) kind = 2; else
775  if (fXML->HasAttr(item,"_more")) kind = 0;
776 
777  return new TGo4HttpAccess(this, item, kind);
778 }
779 
781 {
782  if (fxHierarchy == 0) return 0;
783  XMLNodePointer_t top = fXML->GetChild(fXML->DocGetRootElement(fxHierarchy));
784 
785  return top==0 ? 0 : new TGo4HttpLevelIter(fXML, top);
786 }
787 
788 void TGo4HttpProxy::WriteData(TGo4Slot* slot, TDirectory* dir, Bool_t onlyobjs)
789 {
790 }
791 
792 void TGo4HttpProxy::ReadData(TGo4Slot* slot, TDirectory* dir)
793 {
794 }
795 
796 void TGo4HttpProxy::Update(TGo4Slot* slot, Bool_t strong)
797 {
798  if (strong) {
799  UpdateHierarchy(kFALSE);
800  }
801 }
802 
804 {
805  // return kTRUE when server has Restrict methods
806  // It is indication of new functionality like commands with arguments or support of POST requests
807 
808  return fXML->HasAttr(FindItem(""),"_has_restrict");
809 }
810 
812 {
813  // return kTRUE when server has ProduceMulti method
814  // One could use it to submit many requests at once
815 
816  return fXML->HasAttr(FindItem(""),"_has_produce_multi");
817 }
818 
819 
821 {
822  XMLNodePointer_t item = FindItem("");
823  if (item==0) return kFALSE;
824 
825  const char* _kind = fXML->GetAttr(item,"_kind");
826  const char* _title = fXML->GetAttr(item,"_title");
827 
828  if ((_kind==0) || (_title==0)) return kFALSE;
829 
830  return !strcmp(_kind,"ROOT.Session") && !strcmp(_title,"GO4 analysis");
831 }
832 
833 Bool_t TGo4HttpProxy::CheckUserName(const char* expects, Bool_t dflt)
834 {
835  XMLNodePointer_t item = FindItem("");
836  if (item==0) return dflt;
837 
838  const char* username = fXML->GetAttr(item,"_username");
839  if (username==0) return dflt;
840 
841  return strcmp(username, expects)==0;
842 }
843 
844 
846 {
847  return UpdateHierarchy(kFALSE);
848 }
849 
851 {
852  QTimer::singleShot(delay_sec*1000, &fComm, SLOT(updateHierarchy()));
853 
854  return kTRUE;
855 }
856 
858 {
859  if (!IsGo4Analysis() || IsViewer()) return kFALSE;
860 
861  return ServerHasRestrict();
862 }
863 
864 
866 {
867  if (SubmitRequest("Control/Analysis", 6, SettingsSlot()))
868  SetAnalysisSettingsReady(kTRUE); // workaround - mark as we finished with settings
869 }
870 
872 {
873  TGo4AnalysisStatus* status = 0;
874  if (SettingsSlot()!=0)
875  status = dynamic_cast<TGo4AnalysisStatus*>(SettingsSlot()->GetAssignedObject());
876 
877  if (status)
878  PostObject("Control/Analysis/exe.bin?method=ApplyStatus&status", status, 2);
879 }
880 
882 {
883  SetAnalysisSettingsReady(kFALSE);
884 
885  SubmitCommand("Control/CmdClose");
886 }
887 
889 {
890  // when command submitted without arguments, histograms and conditions folder will be cleared
891  SubmitCommand("Control/CmdClear");
892 }
893 
894 void TGo4HttpProxy::ClearAnalysisObject(const char* fullpath)
895 {
896  TString foldername, objectname;
897  TGo4Slot::ProduceFolderAndName(fullpath, foldername, objectname);
898 
899  objectname = TString("\"") + objectname + TString("\"");
900 
901  SubmitCommand("Control/CmdClearObject", -1, objectname.Data());
902 }
903 
904 void TGo4HttpProxy::RemoveObjectFromAnalysis(const char* fullpath)
905 {
906  TString foldername, objectname;
907  TGo4Slot::ProduceFolderAndName(fullpath, foldername, objectname);
908 
909  objectname = TString("\"") + objectname + TString("\"");
910 
911  SubmitCommand("Control/CmdDeleteObject", -1, objectname.Data());
912 }
913 
914 void TGo4HttpProxy::ExecuteLine(const char* line)
915 {
916  // use method of TGo4AnalysisWebStatus - this works with all THttpServer versions
917  if (FindItem("Control/Analysis"))
918  SubmitURL(TString::Format("Control/Analysis/exe.json?method=ExecuteLine&cmd=\"%s\"", line));
919 }
920 
922 {
923  SubmitCommand("Control/CmdStart");
924  fbAnalysisRunning = kTRUE;
925 }
926 
928 {
929  SubmitCommand("Control/CmdStop");
930  fbAnalysisRunning = kFALSE;
931 }
932 
933 Bool_t TGo4HttpProxy::RequestObjectStatus(const char* objectname, TGo4Slot* tgtslot)
934 {
935  return SubmitRequest(objectname, 4, tgtslot) != 0;
936 }
937 
938 Bool_t TGo4HttpProxy::SubmitURL(const char* path, Int_t waitres)
939 {
940  TString url = fNodeName;
941  url.Append("/");
942  url.Append(path);
943 
944  if (gDebug>1) printf("Submit URL %s\n", url.Data());
945 
946  QNetworkReply *netReply = fComm.qnam.get(QNetworkRequest(QUrl(url.Data())));
947 
948  QSslConfiguration cfg = netReply->sslConfiguration();
949  cfg.setProtocol(QSsl::AnyProtocol/*QSsl::TlsV1SslV3*/);
950  netReply->setSslConfiguration(cfg);
951 
952  if (waitres<=0) {
953  netReply->connect(netReply, SIGNAL(finished()), netReply, SLOT(deleteLater()));
954  return kTRUE;
955  }
956 
957  QEventLoop loop;
958  QElapsedTimer myTimer;
959  myTimer.start();
960 // JAM: just disable this if qt is too old (special for gsi installation 26-06-15)
961 #if QT_VERSION >= QT_VERSION_CHECK(4,6,0)
962  while (!netReply->isFinished()) {
963 #else
964  while(1) {
965 #endif
966  loop.processEvents(QEventLoop::AllEvents,100);
967  if (myTimer.elapsed() > waitres*1000) break;
968  }
969 
970  netReply->deleteLater();
971 #if QT_VERSION >= QT_VERSION_CHECK(4,6,0)
972  return netReply->isFinished();
973 #else
974  return kTRUE;
975 #endif
976 }
977 
978 TString TGo4HttpProxy::FindCommand(const char* name)
979 {
980  if ((name==0) || (*name==0)) return "";
981  if (NumCommandArgs(name)>=0) return name;
982 
983  TGo4Iter iter(fxParentSlot);
984 
985  while (iter.next()) {
986  if (iter.getflag("_numargs")<0) continue;
987  if (strcmp(iter.getname(),name)==0) return iter.getfullname();
988  }
989 
990  return "";
991 }
992 
993 Int_t TGo4HttpProxy::NumCommandArgs(const char* name)
994 {
995  XMLNodePointer_t item = FindItem(name);
996  if (item==0) return -1;
997 
998  const char* _numargs = fXML->GetAttr(item,"_numargs");
999  if (_numargs==0) return 0;
1000 
1001  return TString(_numargs).Atoi();
1002 }
1003 
1004 Bool_t TGo4HttpProxy::SubmitCommand(const char* name, Int_t waitres, const char* arg1, const char* arg2, const char* arg3)
1005 {
1006  TString url(name);
1007  url.Append("/cmd.json");
1008  if ((arg1!=0) && (*arg1!=0)) {
1009  url.Append("?arg1=");
1010  url.Append(arg1);
1011  if ((arg2!=0) && (*arg2!=0)) {
1012  url.Append("&arg2=");
1013  url.Append(arg2);
1014  if ((arg3!=0) && (*arg3!=0)) {
1015  url.Append("&arg3=");
1016  url.Append(arg3);
1017  }
1018  }
1019  }
1020 
1021  return SubmitURL(url.Data(), waitres);
1022 }
1023 
1024 Bool_t TGo4HttpProxy::PostObject(const char* prefix, TObject* obj, Int_t waitres, Bool_t destroy_after)
1025 {
1026  if (!ServerHasRestrict()) return kFALSE;
1027 
1028  TBufferFile *sbuf = new TBufferFile(TBuffer::kWrite, 100000);
1029  sbuf->MapObject(obj);
1030  obj->Streamer(*sbuf);
1031 
1032  QByteArray postData;
1033 #if QT_VERSION >= QT_VERSION_CHECK(4,6,0)
1034  postData.append(sbuf->Buffer(), sbuf->Length());
1035 #else
1036  postData.append(sbuf->Buffer());
1037 #endif
1038 
1039 
1040  delete sbuf;
1041 
1042  TString url = fNodeName;
1043  url.Append("/");
1044  url.Append(prefix);
1045  url.Append("=_post_object_&");
1046  if (destroy_after) url.Append("_destroy_post_&");
1047  url.Append("_post_class_=");
1048  url.Append(obj->ClassName());
1049 
1050  // printf("URL %s datalen %d\n", url.Data(), postData.length());
1051 
1052  QNetworkRequest req(QUrl(url.Data()));
1053 
1054  QNetworkReply *netReply = fComm.qnam.post(req, postData);
1055 
1056  QSslConfiguration cfg = netReply->sslConfiguration();
1057  cfg.setProtocol(QSsl::AnyProtocol/*QSsl::TlsV1SslV3*/);
1058  netReply->setSslConfiguration(cfg);
1059 
1060  if (waitres<=0) {
1061  netReply->connect(netReply, SIGNAL(finished()), netReply, SLOT(deleteLater()));
1062  return kTRUE;
1063  }
1064 
1065  QEventLoop loop;
1066  QElapsedTimer myTimer;
1067  myTimer.start();
1068 #if QT_VERSION >= QT_VERSION_CHECK(4,6,0)
1069  while (!netReply->isFinished()) {
1070 #else
1071  while (1) {
1072 #endif
1073  loop.processEvents(QEventLoop::AllEvents,100);
1074  if (myTimer.elapsed() > waitres*1000) break;
1075  }
1076 
1077  netReply->deleteLater();
1078 #if QT_VERSION >= QT_VERSION_CHECK(4,6,0)
1079  return netReply->isFinished();
1080 #else
1081  return kTRUE;
1082 #endif
1083 }
1084 
1085 
1086 Bool_t TGo4HttpProxy::UpdateAnalysisObject(const char* objectname, TObject* obj)
1087 {
1088  TString url;
1089 
1090  Bool_t destr = kTRUE;
1091 
1092  if (*objectname == 0) {
1093  url.Append("Control/go4_sniffer/exe.bin?method=AddAnalysisObject&obj");
1094  destr = kFALSE; // object will be owned by analysis
1095  } else {
1096  url.Append(objectname);
1097  url.Append("/exe.bin?method=");
1098 
1099  if (obj->InheritsFrom(TGo4Condition::Class())) {
1100  url.Append("UpdateFrom&counts=kFALSE&cond");
1101  } else {
1102  url.Append("SetStatus&status");
1103  }
1104  }
1105 
1106  return PostObject(url.Data(), obj, 2, destr);
1107 }
1108 
1110 {
1111  TGo4Slot* subslot = DebugOutputSlot();
1112  if (subslot) subslot->AssignObject(0, kFALSE);
1113 }
1114 
1116 {
1117  if (finished) {
1118  if (fRegularReq == 0) return;
1119 
1120  QByteArray res = fRegularReq->readAll();
1121  fRegularReq->deleteLater();
1122  fRegularReq = 0;
1123 
1124  if (res.size() <= 0) {
1125  fConnected = false;
1126 
1127  // check if proxy is in shutdown phase
1128  if (CheckShutdown()) return;
1129 
1130  RatemeterSlot()->AssignObject(new TNamed("disconnected","title"),kTRUE);
1131 
1132  return;
1133  }
1134 
1135  if (!fConnected) {
1136  UpdateHierarchy(kFALSE);
1137  fConnected = true;
1138  }
1139 
1140  if (gDebug>2) printf("TGo4HttpProxy:: get reply on multi.bin request with %d bytes\n", res.size());
1141 
1142  int pos = 0;
1143 
1144  for (int n=0;n<3;n++) {
1145  unsigned char* ptr = (unsigned char*) res.data() + pos;
1146  unsigned len = ((unsigned) ptr[0]) |
1147  (((unsigned) ptr[1]) << 8) |
1148  (((unsigned) ptr[2]) << 16) |
1149  (((unsigned) ptr[3]) << 24);
1150 
1151  ptr += 4;
1152  pos += 4 + len;
1153  if (len > res.size()) {
1154  printf("Error decoding multi.bin buffer\n");
1155  return;
1156  }
1157 
1158  if (gDebug>2) printf("Decoding portion of %d bytes\n", len);
1159 
1160  TClass* obj_cl = n==0 ? TGo4Ratemeter::Class() : TList::Class();
1161  TObject* obj = (TObject*) obj_cl->New();
1162 
1163  TBufferFile buf(TBuffer::kRead, len, ptr, kFALSE);
1164  buf.MapObject(obj, obj_cl);
1165 
1166  obj->Streamer(buf);
1167 
1168  if (n>0) {
1169  TGo4Slot* subslot = n==1 ? LoginfoSlot() : DebugOutputSlot();
1170  TList* curr = subslot ? dynamic_cast<TList*> (subslot->GetAssignedObject()) : 0;
1171  TList* next = dynamic_cast<TList*> (obj);
1172  if (curr && curr->First() && next && next->First()) {
1173  if (strcmp(curr->First()->GetName(), next->First()->GetName())==0) {
1174  // this is protection against sending same info many times
1175  // happend with sever snapshot
1176  delete obj;
1177  obj = 0;
1178  }
1179  }
1180  }
1181 
1182  switch(n) {
1183  case 0:
1184  fbAnalysisRunning = ((TGo4Ratemeter*) obj)->IsRunning();
1185  RatemeterSlot()->AssignObject(obj,kTRUE);
1186  break;
1187  case 1:
1188  if (obj) LoginfoSlot()->AssignObject(obj,kTRUE);
1189  break;
1190  case 2:
1191  if (obj) DebugOutputSlot()->AssignObject(obj,kTRUE);
1192  break;
1193  }
1194  }
1195 
1196  if (pos != res.size()) printf("Decoding fails %d != %d bytes\n", pos, res.size());
1197 
1198  return;
1199  }
1200 
1201 
1202  if (fRegularReq!=0) return;
1203 
1204  TString req;
1205 
1206  req.Append("Ratemeter/root.bin\n");
1207 
1208  req.Append("Msg/exe.bin?method=Select&max=10000");
1209  TGo4Slot* subslot = LoginfoSlot();
1210  TList* curr = subslot ? dynamic_cast<TList*> (subslot->GetAssignedObject()) : 0;
1211  if (curr && curr->First()) {
1212  req.Append("&id=");
1213  req.Append(curr->First()->GetName());
1214 
1215  }
1216  req.Append("\n");
1217 
1218  req.Append("Log/exe.bin?method=Select&max=10000");
1219  subslot = DebugOutputSlot();
1220  curr = subslot ? dynamic_cast<TList*> (subslot->GetAssignedObject()) : 0;
1221  if (curr && curr->First()) {
1222  req.Append("&id=");
1223  req.Append(curr->First()->GetName());
1224 
1225  }
1226  req.Append("\n");
1227 
1228  QByteArray postData;
1229 #if QT_VERSION >= QT_VERSION_CHECK(4,6,0)
1230  postData.append(req.Data(), req.Length());
1231 #else
1232  postData.append(req.Data());
1233 #endif
1234  if (gDebug>2) printf("Sending multi.bin request\n%s", req.Data());
1235 
1236  TString url = fNodeName;
1237  url.Append("/Status/multi.bin.gz?number=3");
1238 
1239  fRegularReq = fComm.qnam.post(QNetworkRequest(QUrl(url.Data())), postData);
1240 
1241  QSslConfiguration cfg = fRegularReq->sslConfiguration();
1242  cfg.setProtocol(QSsl::AnyProtocol/*QSsl::TlsV1SslV3*/);
1243  fRegularReq->setSslConfiguration(cfg);
1244 
1245  fRegularReq->connect(fRegularReq, SIGNAL(finished()), &fComm, SLOT(regularRequestFinished()));
1246 }
1247 
1248 Bool_t TGo4HttpProxy::CheckShutdown(Bool_t force)
1249 {
1250  if (force || (fShutdownCnt>0)) {
1252  fxParentSlot = 0;
1253  return kTRUE;
1254  }
1255  return kFALSE;
1256 }
1257 
1258 
1260 {
1261  if ((fShutdownCnt>0) && (--fShutdownCnt==0)) {
1262  CheckShutdown(kTRUE);
1263  return;
1264  }
1265 
1266  if (ServerHasMulti() || (fRegularReq!=0)) {
1268  return;
1269  }
1270 
1271  TGo4Slot* subslot = RatemeterSlot();
1272  if (subslot != 0) {
1273  // no new update since last call
1274  if ((subslot->GetAssignedObject()==0) || (fRateCnt != subslot->GetAssignCnt())) {
1275  fRateCnt = subslot->GetAssignCnt();
1276  SubmitRequest("Status/Ratemeter", 1, subslot);
1277  }
1278  }
1279 
1280  subslot = LoginfoSlot();
1281  if ((subslot!=0) && IsConnected()) {
1282  TList* curr = dynamic_cast<TList*> (subslot->GetAssignedObject());
1283  if ((curr==0) || (fStatusCnt != subslot->GetAssignCnt())) {
1284  TString arg;
1285  if (curr && curr->First()) {
1286  arg = "id=";
1287  arg += curr->First()->GetName();
1288  }
1289  fStatusCnt = subslot->GetAssignCnt();
1290  SubmitRequest("Status/Msg", 7, subslot, arg);
1291  }
1292  }
1293 
1294  subslot = DebugOutputSlot();
1295  if ((subslot!=0) && IsConnected()) {
1296  TList* curr = dynamic_cast<TList*> (subslot->GetAssignedObject());
1297  if ((curr==0) || (fDebugCnt != subslot->GetAssignCnt())) {
1298  TString arg;
1299  if (curr && curr->First()) {
1300  arg = "id=";
1301  arg += curr->First()->GetName();
1302  }
1303  fDebugCnt = subslot->GetAssignCnt();
1304  SubmitRequest("Status/Log", 7, subslot, arg);
1305  }
1306  }
1307 
1308 }
1309 
1310 void TGo4HttpProxy::RemoteTreeDraw(const char* treename,
1311  const char* varexp,
1312  const char* cutcond,
1313  const char* hname)
1314 {
1315  TString tfoldername, tobjectname;
1316  TGo4Slot::ProduceFolderAndName(treename, tfoldername, tobjectname);
1317 
1318  TString hfoldername, hobjectname;
1319  TGo4Slot::ProduceFolderAndName(hname, hfoldername, hobjectname);
1320 
1321  TString path;
1322  path.Form("Control/go4_sniffer/exe.json?method=RemoteTreeDraw&histoname=\"%s\"&treename=\"%s\"&varexpr=\"%s\"&cutexpr=\"%s\"",
1323  hobjectname.Data(), tobjectname.Data(), varexp, cutcond);
1324 
1325  SubmitURL(path, 2);
1326 }
1327 
1328 TGo4HttpAccess* TGo4HttpProxy::SubmitRequest(const char* itemname, Int_t kind, TGo4Slot* tgtslot, const char* extra_arg)
1329 {
1330  if ((itemname==0) || (tgtslot==0)) return 0;
1331 
1332  XMLNodePointer_t item = FindItem(itemname);
1333  if (item==0) return 0;
1334 
1335  if (kind==4) {
1336  // when status for histogram is requested, redirect request to the sniffer
1337  const char* _objkind = fXML->GetAttr(item, "_kind");
1338  if ((_objkind!=0) && ((strstr(_objkind, "ROOT.TH1")==_objkind) ||
1339  (strstr(_objkind, "ROOT.TH2")==_objkind) || (strstr(_objkind, "ROOT.TH3")==_objkind))) kind = 8;
1340  }
1341 
1342  TGo4HttpAccess* access = new TGo4HttpAccess(this, item, kind, extra_arg);
1343  access->AssignObjectToSlot(tgtslot); // request event itself
1344 
1345  return access;
1346 }
1347 
1348 
1349 void TGo4HttpProxy::RequestEventStatus(const char* evname, Bool_t astree, TGo4Slot* tgtslot)
1350 {
1351  if (tgtslot==0) {
1352  // this is remote printing of event
1353 
1354  TString url = evname;
1355  url.Append("/exe.bin?method=");
1356  url.Append(astree ? "ShowSampleTree" : "PrintEvent");
1357 
1358  SubmitURL(url);
1359  return;
1360  }
1361 
1362  SubmitRequest(evname, astree ? 5 : 1, tgtslot);
1363 }
1364 
1365 void TGo4HttpProxy::RemotePrintEvent(const char* evname,
1366  Int_t evnumber,
1367  Int_t subid,
1368  Bool_t ishex,
1369  Bool_t islong)
1370 {
1371  TString url;
1372  url.Form("Events/%s/exe.bin?method=SetPrintEvent&num=%d&sid=%d&longw=%d&hexw=%d&dataw=%d",
1373  evname, evnumber, subid, islong ? 1 : 0, ishex ? 1 : 0, ishex ? 0 : 1);
1374  SubmitURL(url);
1375 }
1376 
1377 void TGo4HttpProxy::ChageObjectProtection(const char* fullpath, const char* flags)
1378 {
1379  unsigned reset_bits(0), set_bits(0);
1380 
1381  TString opt = flags;
1382  if(opt.Contains("+D")) reset_bits |= TGo4Status::kGo4CanDelete;
1383  if(opt.Contains("-D")) set_bits |= TGo4Status::kGo4CanDelete;
1384  if(opt.Contains("+C")) set_bits |= TGo4Status::kGo4NoReset;
1385  if(opt.Contains("-C")) reset_bits |= TGo4Status::kGo4NoReset;
1386 
1387  TString url(fullpath);
1388  url.Append("/exe.bin?method=");
1389 
1390  if (reset_bits!=0) SubmitURL(url + TString::Format("ResetBit&f=%u",reset_bits));
1391  if (set_bits!=0) SubmitURL(url + TString::Format("SetBit&f=%u&prototype=UInt_t",set_bits));
1392 }
1393 
1394 void TGo4HttpProxy::PrintDynListEntry(const char* fullpath)
1395 {
1396  SubmitURL(TString(fullpath)+"/exe.bin?method=Print");
1397 }
1398 
1399 void TGo4HttpProxy::LoadConfigFile(const char* fname)
1400 {
1401  SubmitURL(TString::Format("Control/Analysis/exe.bin?method=LoadStatus&fname=%s", fname));
1402 }
1403 
1404 void TGo4HttpProxy::SaveConfigFile(const char* fname)
1405 {
1406  SubmitURL(TString::Format("Control/Analysis/exe.bin?method=SaveStatus&fname=%s", fname));
1407 }
1408 
1409 void TGo4HttpProxy::WriteAutoSave(const char* fname,
1410  Int_t complevel,
1411  Bool_t overwrite)
1412 {
1413  SubmitURL(TString::Format("Control/Analysis/exe.bin?method=WriteAutoSave&fname=%s&overwrite=%s&complevel=%d", fname, overwrite ? "kTRUE" : "kFALSE", complevel));
1414 }
1415 
1416 void TGo4HttpProxy::DisconnectAnalysis(Int_t waittime, Bool_t servershutdown)
1417 {
1418  if (servershutdown && IsGo4Analysis() && IsAdministrator()) {
1419  SubmitCommand("Control/CmdExit");
1420  fShutdownCnt = waittime;
1421  } else {
1422  CheckShutdown(kTRUE);
1423  }
1424 }
1425 
1426 
TGo4HttpProxy * fProxy
used only to receive hierarchy
Definition: TGo4HttpProxy.h:38
virtual Int_t AssignObjectTo(TGo4ObjectManager *rcv, const char *path)
TString fPassword
user name and password -
virtual void RequestAnalysisSettings()
static TClass * GetClass(const char *classname, Bool_t load=kFALSE)
Definition: TGo4Proxy.cxx:73
virtual void CloseAnalysisSettings()
Int_t fStatusCnt
counter for ratemeter updates
virtual void DisconnectAnalysis(Int_t waittime=30, Bool_t servershutdown=kFALSE)
virtual void ChageObjectProtection(const char *fullpath, const char *flags)
QNetworkReply * fReply
Definition: TGo4HttpProxy.h:82
virtual Bool_t CanSubmitObjects()
Bool_t fbAnalysisRunning
counter for debug output updates
virtual Bool_t next()
QNetworkAccessManager qnam
Definition: TGo4HttpProxy.h:36
void SetProxy(TGo4Proxy *cont)
Definition: TGo4Slot.cxx:310
TGo4Slot * LoginfoSlot()
virtual TString FindCommand(const char *name)
virtual TGo4LevelIter * subiterator()
virtual void ReadData(TGo4Slot *slot, TDirectory *dir)
virtual Bool_t HasSublevels() const
Int_t fDebugCnt
counter for status messages updates
friend class TGo4HttpAccess
const char * GetHttpRootClassName(const char *kind)
Bool_t PostObject(const char *prefix, TObject *obj, Int_t waitres=-1, Bool_t destroy_after=kTRUE)
virtual void Initialize(TGo4Slot *slot)
Bool_t CheckUserName(const char *expects, Bool_t dflt=kFALSE)
virtual void ClearAnalysisObject(const char *fullpath)
Bool_t ServerHasMulti()
virtual void RequestEventStatus(const char *evname, Bool_t astree, TGo4Slot *tgtslot)
TXMLEngine * fXML
virtual Bool_t IsViewer()
virtual Int_t sizeinfo()
virtual TClass * GetObjectClass() const
TString fRecvPath
Definition: TGo4HttpProxy.h:81
TString fNameAttr
Definition: TGo4HttpProxy.h:77
void ProcessUpdateTimer()
void DoObjectAssignement(TGo4ObjectManager *rcv, const char *path, TObject *obj, Bool_t owner)
Definition: TGo4Proxy.cxx:63
virtual void SaveConfigFile(const char *fname)
Bool_t SubmitURL(const char *path, Int_t waitres=-1)
virtual Bool_t IsConnected()
virtual const char * info()
virtual const char * GetObjectClassName() const
void authenticationRequiredSlot(QNetworkReply *, QAuthenticator *)
virtual ~QHttpProxy()
virtual const char * GetUserName() const
QHttpProxy(TGo4HttpProxy *p)
QNetworkReply * fRegularReq
true if connected
virtual Int_t getflag(const char *flagname)
void updateRatemeter()
Int_t getflag(const char *flagname)
Definition: TGo4Iter.cxx:132
Bool_t Connect(const char *nodename)
void httpFinished()
virtual ~TGo4HttpLevelIter()
virtual void Initialize(TGo4Slot *slot)
virtual Bool_t IsAdministrator()
TGo4Slot * RatemeterSlot()
TObject * GetAssignedObject()
Definition: TGo4Slot.cxx:370
XMLNodePointer_t fParent
void SetAnalysisReady(Bool_t on=kTRUE)
const char * getfullname()
Definition: TGo4Iter.cxx:151
TGo4HttpLevelIter(TXMLEngine *xml, XMLNodePointer_t item)
virtual void RemoteTreeDraw(const char *treename, const char *varexp, const char *cutcond, const char *hname)
TGo4Slot * DebugOutputSlot()
void ProcessRegularMultiRequest(Bool_t finished=kFALSE)
void StartRequest(const char *url)
virtual const char * GetContainedObjectInfo()
TGo4Slot * SettingsSlot()
virtual void ClearAllAnalysisObjects()
virtual void Update(TGo4Slot *slot, Bool_t strong)
virtual void StartAnalysis()
void GetHReply(QByteArray &res)
counter during shutdown
void SetAccount(const char *username, const char *passwd)
void SetAnalysisSettingsReady(Bool_t on=kTRUE)
TGo4Slot * fxParentSlot
virtual Int_t GetKind()
TGo4HttpProxy * fProxy
Definition: TGo4HttpProxy.h:65
TString fExtraArg
Definition: TGo4HttpProxy.h:79
virtual const char * GetContainedObjectInfo()
virtual Int_t NumCommandArgs(const char *name)
TGo4ObjectManager * fReceiver
Definition: TGo4HttpProxy.h:80
TGo4HttpAccess * SubmitRequest(const char *itemname, Int_t kind, TGo4Slot *tgtslot, const char *extra_arg=0)
virtual void WriteData(TGo4Slot *slot, TDirectory *dir, Bool_t onlyobjs)
virtual TGo4Slot * getslot()
QHttpProxy fComm
pointer on dabc::Hierarchy class
const char * getname()
Definition: TGo4Iter.cxx:114
virtual Bool_t RequestObjectStatus(const char *objectname, TGo4Slot *tgtslot)
void httpError(QNetworkReply::NetworkError)
virtual Bool_t SubmitCommand(const char *name, Int_t waitres=-1, const char *arg1=0, const char *arg2=0, const char *arg3=0)
virtual Bool_t IsGo4Analysis() const
XMLDocPointer_t fxHierarchy
XMLNodePointer_t fChild
virtual void ResetDebugOutputRequests()
virtual Bool_t NamesListReceived()
virtual void LoadConfigFile(const char *fname)
virtual void RemoveObjectFromAnalysis(const char *fullpath)
void httpHReqError(QNetworkReply::NetworkError)
virtual void SubmitAnalysisSettings()
Bool_t ServerHasRestrict()
void regularRequestFinished()
virtual Bool_t RefreshNamesList()
TString fKindAttr
Definition: TGo4HttpProxy.h:78
virtual void ExecuteLine(const char *line)
QNetworkReply * fHReply
central manager of network requests
Definition: TGo4HttpProxy.h:37
virtual ~TGo4HttpProxy()
TString fUserName
static void ProduceFolderAndName(const char *fullname, TString &foldername, TString &objectname)
Definition: TGo4Slot.cxx:664
void ForwardEvent(TGo4Slot *source, Int_t id, void *param=0)
Definition: TGo4Slot.cxx:581
virtual Bool_t UpdateAnalysisObject(const char *objectname, TObject *obj)
virtual void WriteAutoSave(const char *fname, Int_t complevel, Bool_t overwrite)
virtual TGo4LevelIter * MakeIter()
Int_t AssignObjectToSlot(TGo4Slot *slot)
Definition: TGo4Proxy.cxx:54
TString fNodeName
0 - not launched, 1 - external shell, 2 - in qt shell
virtual void Delete(Option_t *opt="")
Definition: TGo4Slot.cxx:187
XMLNodePointer_t fNode
Definition: TGo4HttpProxy.h:66
Bool_t AssignObject(TObject *obj, Bool_t owner)
Definition: TGo4Slot.cxx:358
void updateHierarchy()
TString MakeUrlPath(XMLNodePointer_t item)
Bool_t UpdateHierarchy(Bool_t sync=kTRUE)
virtual const char * GetServerName() const
virtual void RemotePrintEvent(const char *evname, Int_t evnumber, Int_t subid, Bool_t ishex, Bool_t islong)
virtual const char * GetObjectName() const
virtual Bool_t isfolder()
TGo4HttpAccess(TGo4HttpProxy *proxy, XMLNodePointer_t node, Int_t kind=1, const char *extra_arg=0)
Bool_t CheckShutdown(Bool_t force=kFALSE)
virtual TGo4Access * ProvideAccess(const char *name)
virtual const char * GetClassName()
virtual void StopAnalysis()
virtual Bool_t DelayedRefreshNamesList(Int_t delay_sec)
Int_t GetAssignCnt() const
Definition: TGo4Slot.h:104
virtual const char * name()
virtual void PrintDynListEntry(const char *fullpath)
Int_t fShutdownCnt
multiple request for rate, log and messages
XMLNodePointer_t FindItem(const char *name, XMLNodePointer_t curr=0) const
Bool_t next(Bool_t goesinto=kTRUE)
Definition: TGo4Iter.cxx:44
TString fUrlPath
Definition: TGo4HttpProxy.h:67