<commit_before>// $Id$
// Author: <NAME>   21/12/2013

/*************************************************************************
 * Copyright (C) 1995-2013, <NAME> and <NAME>.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "THttpServer.h"

#include "TThread.h"
#include "TTimer.h"
#include "TSystem.h"
#include "TROOT.h"
#include "TUrl.h"
#include "TEnv.h"
#include "TClass.h"
#include "RVersion.h"
#include "RConfigure.h"
#include "TRegexp.h"

#include "THttpEngine.h"
#include "THttpLongPollEngine.h"
#include "THttpWSHandler.h"
#include "TRootSniffer.h"
#include "TRootSnifferStore.h"
#include "TCivetweb.h"
#include "TFastCgi.h"

#include <string>
#include <cstdlib>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <chrono>

////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// THttpTimer                                                           //
//                                                                      //
// Specialized timer for THttpServer                                    //
// Provides regular calls of THttpServer::ProcessRequests() method      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class THttpTimer : public TTimer {
public:
   THttpServer &fServer; ///!< server processing requests

   /// constructor
   THttpTimer(Long_t milliSec, Bool_t mode, THttpServer &serv) : TTimer(milliSec, mode), fServer(serv) {}

   /// timeout handler
   /// used to process http requests in main ROOT thread
   virtual void Timeout() { fServer.ProcessRequests(); }
};

//////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// THttpServer                                                          //
//                                                                      //
// Online http server for arbitrary ROOT application                    //
//                                                                      //
// Idea of THttpServer - provide remote http access to running          //
// ROOT application and enable HTML/JavaScript user interface.          //
// Any registered object can be requested and displayed in the browser. //
// There are many benefits of such approach:                            //
//     * standard http interface to ROOT application                    //
//     * no any temporary ROOT files when access data                   //
//     * user interface running in all browsers                         //
//                                                                      //
// Starting HTTP server                                                 //
//                                                                      //
// To start http server, at any time  create instance                   //
// of the THttpServer class like:                                       //
//    serv = new THttpServer("http:8080");                              //
//                                                                      //
// This will starts civetweb-based http server with http port 8080.     //
// Than one should be able to open address "http://localhost:8080"      //
// in any modern browser (IE, Firefox, Chrome) and browse objects,      //
// created in application. By default, server can access files,         //
// canvases and histograms via gROOT pointer. All such objects          //
// can be displayed with JSROOT graphics.                               //
//                                                                      //
// At any time one could register other objects with the command:       //
//                                                                      //
// TGraph* gr = new TGraph(10);                                         //
// gr->SetName("gr1");                                                  //
// serv->Register("graphs/subfolder", gr);                              //
//                                                                      //
// If objects content is changing in the application, one could         //
// enable monitoring flag in the browser - than objects view            //
// will be regularly updated.                                           //
//                                                                      //
// More information: https://root.cern/root/htmldoc/guides/HttpServer/HttpServer.html  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

ClassImp(THttpServer);

////////////////////////////////////////////////////////////////////////////////
/// constructor
///
/// As argument, one specifies engine kind which should be
/// created like "http:8080". One could specify several engines
/// at once, separating them with semicolon (";"). Following engines are supported:
///
///       http - TCivetweb, civetweb-based implementation of http protocol
///       fastcgi - TFastCgi, special protocol for communicating with web servers
///
/// For each created engine one should provide socket port number like "http:8080" or "fastcgi:9000".
/// Additional engine-specific options can be supplied with URL syntax like "http:8080?thrds=10".
/// Full list of supported options should be checked in engines docu.
///
/// One also can configure following options, separated by semicolon:
///
///     readonly, ro   - set read-only mode (default)
///     readwrite, rw  - allows methods execution of registered objects
///     global         - scans global ROOT lists for existing objects (default)
///     noglobal       - disable scan of global lists
///     cors           - enable CORS header with origin="*"
///     cors=domain    - enable CORS header with origin="domain"
///     basic_sniffer  - use basic sniffer without support of hist, gpad, graph classes
///
/// For example, create http server, which allows cors headers and disable scan of global lists,
/// one should provide "http:8080;cors;noglobal" as parameter
///
/// THttpServer uses JavaScript ROOT (https://root.cern/js) to implement web clients UI.
/// Normally JSROOT sources are used from $ROOTSYS/js directory,
/// but one could set JSROOTSYS shell variable to specify alternative location

THttpServer::THttpServer(const char *engine) : TNamed("http", "ROOT http server")
{
   const char *jsrootsys = gSystem->Getenv("JSROOTSYS");
   if (!jsrootsys)
      jsrootsys = gEnv->GetValue("HttpServ.JSRootPath", jsrootsys);

   if (jsrootsys && *jsrootsys)
      if ((strncmp(jsrootsys, "http://", 7)==0) || (strncmp(jsrootsys, "https://", 8)==0))
         fJSROOT = jsrootsys;
      else
         fJSROOTSYS = jsrootsys;

   if (fJSROOTSYS.Length() == 0) {
      TString jsdir = TString::Format("%s/js", TROOT::GetDataDir().Data());
      if (gSystem->ExpandPathName(jsdir)) {
         ::Warning("THttpServer::THttpServer", "problems resolving '%s', set JSROOTSYS to proper JavaScript ROOT location",
                 jsdir.Data());
         fJSROOTSYS = ".";
      } else {
         fJSROOTSYS = jsdir;
      }
   }

   AddLocation("currentdir/", ".");
   AddLocation("jsrootsys/", fJSROOTSYS.Data());
   AddLocation("rootsys/", TROOT::GetRootSys());

   fDefaultPage = fJSROOTSYS + "/files/online.htm";
   fDrawPage = fJSROOTSYS + "/files/draw.htm";

   TRootSniffer *sniff = nullptr;
   if (strstr(engine, "basic_sniffer")) {
      sniff = new TRootSniffer("sniff");
      sniff->SetScanGlobalDir(kFALSE);
      sniff->CreateOwnTopFolder(); // use dedicated folder
   } else {
      sniff = (TRootSniffer *)gROOT->ProcessLineSync("new TRootSnifferFull(\"sniff\");");
   }<commit_msg>net/http: fix ambiguous else warning in THttpServer<commit_after>// $Id$
// Author: <NAME>   21/12/2013

/*************************************************************************
 * Copyright (C) 1995-2013, <NAME> and <NAME>.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "THttpServer.h"

#include "TThread.h"
#include "TTimer.h"
#include "TSystem.h"
#include "TROOT.h"
#include "TUrl.h"
#include "TEnv.h"
#include "TClass.h"
#include "RVersion.h"
#include "RConfigure.h"
#include "TRegexp.h"

#include "THttpEngine.h"
#include "THttpLongPollEngine.h"
#include "THttpWSHandler.h"
#include "TRootSniffer.h"
#include "TRootSnifferStore.h"
#include "TCivetweb.h"
#include "TFastCgi.h"

#include <string>
#include <cstdlib>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <chrono>

////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// THttpTimer                                                           //
//                                                                      //
// Specialized timer for THttpServer                                    //
// Provides regular calls of THttpServer::ProcessRequests() method      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class THttpTimer : public TTimer {
public:
   THttpServer &fServer; ///!< server processing requests

   /// constructor
   THttpTimer(Long_t milliSec, Bool_t mode, THttpServer &serv) : TTimer(milliSec, mode), fServer(serv) {}

   /// timeout handler
   /// used to process http requests in main ROOT thread
   virtual void Timeout() { fServer.ProcessRequests(); }
};

//////////////////////////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// THttpServer                                                          //
//                                                                      //
// Online http server for arbitrary ROOT application                    //
//                                                                      //
// Idea of THttpServer - provide remote http access to running          //
// ROOT application and enable HTML/JavaScript user interface.          //
// Any registered object can be requested and displayed in the browser. //
// There are many benefits of such approach:                            //
//     * standard http interface to ROOT application                    //
//     * no any temporary ROOT files when access data                   //
//     * user interface running in all browsers                         //
//                                                                      //
// Starting HTTP server                                                 //
//                                                                      //
// To start http server, at any time  create instance                   //
// of the THttpServer class like:                                       //
//    serv = new THttpServer("http:8080");                              //
//                                                                      //
// This will starts civetweb-based http server with http port 8080.     //
// Than one should be able to open address "http://localhost:8080"      //
// in any modern browser (IE, Firefox, Chrome) and browse objects,      //
// created in application. By default, server can access files,         //
// canvases and histograms via gROOT pointer. All such objects          //
// can be displayed with JSROOT graphics.                               //
//                                                                      //
// At any time one could register other objects with the command:       //
//                                                                      //
// TGraph* gr = new TGraph(10);                                         //
// gr->SetName("gr1");                                                  //
// serv->Register("graphs/subfolder", gr);                              //
//                                                                      //
// If objects content is changing in the application, one could         //
// enable monitoring flag in the browser - than objects view            //
// will be regularly updated.                                           //
//                                                                      //
// More information: https://root.cern/root/htmldoc/guides/HttpServer/HttpServer.html  //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

ClassImp(THttpServer);

////////////////////////////////////////////////////////////////////////////////
/// constructor
///
/// As argument, one specifies engine kind which should be
/// created like "http:8080". One could specify several engines
/// at once, separating them with semicolon (";"). Following engines are supported:
///
///       http - TCivetweb, civetweb-based implementation of http protocol
///       fastcgi - TFastCgi, special protocol for communicating with web servers
///
/// For each created engine one should provide socket port number like "http:8080" or "fastcgi:9000".
/// Additional engine-specific options can be supplied with URL syntax like "http:8080?thrds=10".
/// Full list of supported options should be checked in engines docu.
///
/// One also can configure following options, separated by semicolon:
///
///     readonly, ro   - set read-only mode (default)
///     readwrite, rw  - allows methods execution of registered objects
///     global         - scans global ROOT lists for existing objects (default)
///     noglobal       - disable scan of global lists
///     cors           - enable CORS header with origin="*"
///     cors=domain    - enable CORS header with origin="domain"
///     basic_sniffer  - use basic sniffer without support of hist, gpad, graph classes
///
/// For example, create http server, which allows cors headers and disable scan of global lists,
/// one should provide "http:8080;cors;noglobal" as parameter
///
/// THttpServer uses JavaScript ROOT (https://root.cern/js) to implement web clients UI.
/// Normally JSROOT sources are used from $ROOTSYS/js directory,
/// but one could set JSROOTSYS shell variable to specify alternative location

THttpServer::THttpServer(const char *engine) : TNamed("http", "ROOT http server")
{
   const char *jsrootsys = gSystem->Getenv("JSROOTSYS");
   if (!jsrootsys)
      jsrootsys = gEnv->GetValue("HttpServ.JSRootPath", jsrootsys);

   if (jsrootsys && *jsrootsys) {
      if ((strncmp(jsrootsys, "http://", 7)==0) || (strncmp(jsrootsys, "https://", 8)==0))
         fJSROOT = jsrootsys;
      else
         fJSROOTSYS = jsrootsys;
   }

   if (fJSROOTSYS.Length() == 0) {
      TString jsdir = TString::Format("%s/js", TROOT::GetDataDir().Data());
      if (gSystem->ExpandPathName(jsdir)) {
         ::Warning("THttpServer::THttpServer", "problems resolving '%s', set JSROOTSYS to proper JavaScript ROOT location",
                 jsdir.Data());
         fJSROOTSYS = ".";
      } else {
         fJSROOTSYS = jsdir;
      }
   }

   AddLocation("currentdir/", ".");
   AddLocation("jsrootsys/", fJSROOTSYS.Data());
   AddLocation("rootsys/", TROOT::GetRootSys());

   fDefaultPage = fJSROOTSYS + "/files/online.htm";
   fDrawPage = fJSROOTSYS + "/files/draw.htm";

   TRootSniffer *sniff = nullptr;
   if (strstr(engine, "basic_sniffer")) {
      sniff = new TRootSniffer("sniff");
      sniff->SetScanGlobalDir(kFALSE);
      sniff->CreateOwnTopFolder(); // use dedicated folder
   } else {
      sniff = (TRootSniffer *)gROOT->ProcessLineSync("new TRootSnifferFull(\"sniff\");");
   }
{'fraction_non_alphanumeric': 0.18261852358574743, 'fraction_numerical': 0.006900243887930522, 'mean_word_length': 1.1985092193016869, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 37, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 120, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5497755', 'n_tokens_mistral': 3805, 'n_tokens_neox': 3672, 'n_words': 1162}