24 #include "RConfigure.h" 50 class THttpTimer :
public TTimer {
91 TLongPollEngine(
const char *
name,
const char *title) :
THttpWSEngine(name, title), fPoll(0), fBuf() {}
93 virtual ~TLongPollEngine() {}
95 virtual UInt_t GetId()
const 97 const void *ptr = (
const void *)
this;
101 virtual void ClearHandle()
110 virtual void Send(
const void * ,
int )
112 Error(
"TLongPollEngine::Send",
"Should never be called, only text is supported");
115 virtual void SendCharStar(
const char *buf)
122 }
else if (fBuf.
Length() == 0) {
125 Error(
"TLongPollEngine::SendCharStar",
"Too many send operations, use TList object instead");
135 if (!strstr(arg->
GetQuery(),
"&dummy"))
139 Error(
"PreviewData",
"NEVER SHOULD HAPPEN");
144 Info(
"PreviewData",
"Get dummy request when previous not completed");
242 :
TNamed(
"http",
"ROOT http server"), fEngines(), fTimer(0), fSniffer(0), fMainThrdId(0), fJSROOTSYS(),
243 fTopName(
"ROOT"), fJSROOT(), fLocations(), fDefaultPage(), fDefaultPageCont(), fDrawPage(), fDrawPageCont(),
248 #ifdef COMPILED_WITH_DABC 261 Warning(
"THttpServer",
"problems resolving '%s', use JSROOTSYS to specify $ROOTSYS/etc/http location",
281 if (strchr(engine,
';') == 0) {
288 if ((strcmp(opt,
"readonly") == 0) || (strcmp(opt,
"ro") == 0)) {
290 }
else if ((strcmp(opt,
"readwrite") == 0) || (strcmp(opt,
"rw") == 0)) {
292 }
else if (strcmp(opt,
"global") == 0) {
294 }
else if (strcmp(opt,
"noglobal") == 0) {
296 }
else if (strncmp(opt,
"cors=", 5) == 0) {
298 }
else if (strcmp(opt,
"cors") == 0) {
359 if ((prefix == 0) || (*prefix == 0))
381 fJSROOT = location ? location :
"";
392 if ((filename != 0) && (*filename != 0))
409 if ((filename != 0) && (*filename != 0))
433 const char *arg = strchr(engine,
':');
439 clname.
Append(engine, arg - engine);
441 if ((clname.
Length() == 0) || (clname ==
"http") || (clname ==
"civetweb"))
442 clname =
"TCivetweb";
443 else if (clname ==
"fastcgi")
445 else if (clname ==
"dabc")
446 clname =
"TDabcEngine";
450 if (engine_class == 0)
459 if (!eng->
Create(arg + 1)) {
493 fTimer =
new THttpTimer(milliSec, mode,
this);
504 if ((fname == 0) || (*fname == 0))
509 while (*fname != 0) {
512 const char *next = strpbrk(fname,
"/\\");
517 if ((next == fname + 2) && (*fname ==
'.') && (*(fname + 1) ==
'.')) {
526 if ((next == fname + 1) && (*fname ==
'.')) {
553 if ((uri == 0) || (strlen(uri) == 0))
559 while ((obj = iter()) != 0) {
567 if ((fname[0] ==
'/') && (res[res.
Length() - 1] ==
'/'))
592 std::unique_lock<std::mutex> lk(
fMutex);
618 std::unique_lock<std::mutex> lk(
fMutex);
635 Error(
"ProcessRequests",
"Should be called only from main ROOT thread");
639 std::unique_lock<std::mutex> lk(
fMutex, std::defer_lock);
730 const char *hjsontag =
"\"$$$h.json$$$\"";
744 "private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0");
765 const char *rootjsontag =
"\"$$$root.json$$$\"";
766 const char *hjsontag =
"\"$$$h.json$$$\"";
800 "private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0");
829 if ((filename ==
"h.xml") || (filename ==
"get.xml")) {
833 arg->
fContent.
Form(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
853 }
else if (filename ==
"h.json") {
860 }
else if (filename ==
"root.websocket") {
865 if (!handler || !handler->
HandleWS(arg))
869 }
else if (filename ==
"root.longpoll") {
876 }
else if (arg->
fQuery ==
"connect") {
881 if (handler && handler->
HandleWS(arg)) {
884 TLongPollEngine *handle =
new TLongPollEngine(
"longpoll", arg->
fPathName.
Data());
912 Int_t len = strlen(post);
913 void *buf =
malloc(len / 2 + 1);
914 char *sbuf = (
char *)buf;
915 for (
int n = 0;
n < len;
n += 2)
921 if (handler && !handler->
HandleWS(arg))
926 }
else if (filename ==
"root.ws_emulation") {
930 if (!handler || !handler->
HandleWS(arg))
962 if (filename ==
"root.bin") {
971 "private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0");
1046 return SetItemField(foldername,
"_hidden", hide ?
"true" : (
const char *)0);
1086 static const struct {
1091 {
".json", 5,
"application/json"},
1092 {
".bin", 4,
"application/x-binary"},
1093 {
".gif", 4,
"image/gif"},
1094 {
".jpg", 4,
"image/jpeg"},
1095 {
".png", 4,
"image/png"},
1096 {
".html", 5,
"text/html"},
1097 {
".htm", 4,
"text/html"},
1098 {
".shtm", 5,
"text/html"},
1099 {
".shtml", 6,
"text/html"},
1100 {
".css", 4,
"text/css"},
1101 {
".js", 3,
"application/x-javascript"},
1102 {
".ico", 4,
"image/x-icon"},
1103 {
".jpeg", 5,
"image/jpeg"},
1104 {
".svg", 4,
"image/svg+xml"},
1105 {
".txt", 4,
"text/plain"},
1106 {
".torrent", 8,
"application/x-bittorrent"},
1107 {
".wav", 4,
"audio/x-wav"},
1108 {
".mp3", 4,
"audio/x-mp3"},
1109 {
".mid", 4,
"audio/mid"},
1110 {
".m3u", 4,
"audio/x-mpegurl"},
1111 {
".ogg", 4,
"application/ogg"},
1112 {
".ram", 4,
"audio/x-pn-realaudio"},
1113 {
".xslt", 5,
"application/xml"},
1114 {
".xsl", 4,
"application/xml"},
1115 {
".ra", 3,
"audio/x-pn-realaudio"},
1116 {
".doc", 4,
"application/msword"},
1117 {
".exe", 4,
"application/octet-stream"},
1118 {
".zip", 4,
"application/x-zip-compressed"},
1119 {
".xls", 4,
"application/excel"},
1120 {
".tgz", 4,
"application/x-tar-gz"},
1121 {
".tar", 4,
"application/x-tar"},
1122 {
".gz", 3,
"application/x-gunzip"},
1123 {
".arj", 4,
"application/x-arj-compressed"},
1124 {
".rar", 4,
"application/x-arj-compressed"},
1125 {
".rtf", 4,
"application/rtf"},
1126 {
".pdf", 4,
"application/pdf"},
1127 {
".swf", 4,
"application/x-shockwave-flash"},
1128 {
".mpg", 4,
"video/mpeg"},
1129 {
".webm", 5,
"video/webm"},
1130 {
".mpeg", 5,
"video/mpeg"},
1131 {
".mov", 4,
"video/quicktime"},
1132 {
".mp4", 4,
"video/mp4"},
1133 {
".m4v", 4,
"video/x-m4v"},
1134 {
".asf", 4,
"video/x-ms-asf"},
1135 {
".avi", 4,
"video/x-msvideo"},
1136 {
".bmp", 4,
"image/bmp"},
1137 {
".ttf", 4,
"application/x-font-ttf"},
1140 int path_len = strlen(path);
1151 return "text/plain";
1161 std::ifstream is(filename);
1165 is.seekg(0, is.end);
1167 is.seekg(0, is.beg);
1169 char *buf = (
char *)
malloc(len);
void SetZipping(Int_t kind)
Set kind of content zipping 0 - none 1 - only when supported in request header 2 - if supported and c...
Bool_t RegisterObject(const char *subfolder, TObject *obj)
Register object in subfolder structure subfolder parameter can have many levels like: ...
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
void SetCors(const char *domain="*")
Enable CORS header to ProcessRequests() responses Specified location (typically "*") add as "Access-C...
Bool_t Produce(const char *path, const char *file, const char *options, void *&ptr, Long_t &length, TString &str)
Method produce different kind of data out of object Parameter 'path' specifies object or object membe...
Bool_t IsStreamerInfoItem(const char *itemname)
Return true if it is streamer info item name.
virtual void Process()
Method regularly called in main ROOT context.
Bool_t IsReadOnly() const
Returns readonly mode.
UInt_t GetWSId() const
get web-socket id
void SetWSHandle(TNamed *handle)
assign websocket handle with HTTP call
Storage of hierarchy scan in TRootSniffer in JSON format.
This class represents a WWW compatible URL.
TString & ReplaceAll(const TString &s1, const TString &s2)
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
const char * GetItemField(const char *fullname, const char *name)
Bool_t IsReadOnly() const
returns read-only mode
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Bool_t IsCors() const
Returns kTRUE if CORS was configured.
TString fQuery
! additional arguments
TString fTopName
! name of top folder, default - "ROOT"
static const TString & GetRootSys()
Get the rootsys directory in the installation. Static utility function.
void Restrict(const char *path, const char *options)
Restrict access to the specified location.
static const struct @128 builtin_mime_types[]
Bool_t UnregisterObject(TObject *obj)
unregister (remove) object from folders structures folder itself will remain even when it will be emp...
TList fEngines
! engines which runs http server
TObject * At(Int_t idx) const
void SetServer(THttpServer *serv)
const char * GetQuery() const
returns request query (string after ? in request URL)
void SetContentType(const char *typ)
set content type like "text/xml" or "application/json"
Bool_t CreateItem(const char *fullname, const char *title)
create item element
void SetPostponed()
mark reply as postponed - submitting thread will not be inform
void ProcessRequests()
Process submitted requests, must be called from main thread.
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
virtual TObject * FindObject(const char *name) const
Delete a TObjLink object.
Bool_t CreateItem(const char *fullname, const char *title)
void SetContent(const char *c)
Set content directly.
void SetPostData(void *data, Long_t length, Bool_t make_copy=kFALSE)
set data, posted with the request buffer should be allocated with malloc(length+1) call...
TRootSniffer * fSniffer
! sniffer provides access to ROOT objects hierarchy
THttpServer(const char *engine="civetweb:8080")
constructor
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Bool_t SetItemField(const char *fullname, const char *name, const char *value)
set field for specified item
The TNamed class is the base class for all named ROOT classes.
void Clear()
Clear string without changing its capacity.
THttpTimer * fTimer
! timer used to access main thread
virtual const char * Getenv(const char *env)
Get environment variable.
TString fPathName
! item path
void Set404()
mark reply as 404 error - page/request not exists or refused
void Info(const char *location, const char *msgfmt,...)
TString & Append(const char *cs)
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
static Long_t SelfId()
Static method returning the id for the current thread.
TNamed * fWSHandle
! web-socket handle, derived from TNamed class
void SetTimer(Long_t milliSec=100, Bool_t mode=kTRUE)
create timer which will invoke ProcessRequests() function periodically Timer is required to perform a...
const char * GetValueFromOptions(const char *key) const
Return a value for a given key from the URL options.
TList fLocations
! list of local directories, which could be accessed via server
TString fJSROOTSYS
! location of local JSROOT files
void Error(const char *location, const char *msgfmt,...)
Storage of hierarchy scan in TRootSniffer in XML format.
Bool_t SubmitHttp(THttpCallArg *arg, Bool_t can_run_immediately=kFALSE)
Submit HTTP request.
Bool_t Register(const char *subfolder, TObject *obj)
Register object in subfolder.
void SetReadOnly(Bool_t readonly)
Set read-only mode for the server (default on) In read-only server is not allowed to change any ROOT ...
TString fTopName
! top item name
Int_t GetLast() const
Return index of last object in array.
void SetBinData(void *data, Long_t length)
set binary data, which will be returned as reply body
void SetJson()
set content type as JSON
Bool_t CreateEngine(const char *engine)
factory method to create different http engines At the moment two engine kinds are supported: civetwe...
Bool_t fNotifyFlag
! indicate that notification called
virtual TObject * First() const
Return the first object in the list. Returns 0 when list is empty.
Bool_t HandleWS(THttpCallArg *arg)
R__EXTERN TSystem * gSystem
virtual TString GetDefaultPageContent()
Provides content of default web page for registered web-socket handler Can be content of HTML page or...
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
virtual ~THttpServer()
destructor delete all http engines and sniffer
Bool_t RegisterCommand(const char *cmdname, const char *method, const char *icon)
Register command which can be executed from web interface.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
char * Form(const char *fmt,...)
TString fDefaultPage
! file name for default page name
virtual Bool_t Create(const char *)
Method to create all components of engine.
Handles synchronous and a-synchronous timer events.
The ROOT global object gROOT contains a list of all defined classes.
void SetSniffer(TRootSniffer *sniff)
Set TRootSniffer to the server Server takes ownership over sniffer.
void ScanHierarchy(const char *topname, const char *path, TRootSnifferStore *store, Bool_t only_fields=kFALSE)
Method scans normal objects, registered in ROOT.
Bool_t ExecuteHttp(THttpCallArg *arg)
Execute HTTP request.
TString fDrawPage
! file name for drawing of single element
TString & Remove(Ssiz_t pos)
std::condition_variable fCond
! condition used to wait for processing
void AddLocation(const char *prefix, const char *path)
add files location, which could be used in the server one could map some system folder to the server ...
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Bool_t Hide(const char *fullname, Bool_t hide=kTRUE)
hides folder or element from web gui
std::mutex fMutex
! mutex to protect list with arguments
void SetWSId(UInt_t id)
set web-socket id
virtual void ProcessRequest(THttpCallArg *arg)
Function called for every processed request.
TString fDrawPageCont
! content of draw page
void SetMethod(const char *method)
set request method kind like GET or POST
void SetXml()
set content type as XML
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
static TString BaseConvert(const TString &s_in, Int_t base_in, Int_t base_out)
Converts string from base base_in to base base_out.
void NotifyCondition()
method used to notify condition which waiting when operation will complete Condition notified only if...
TString fDefaultPageCont
! content of the file content
void ParseOptions() const
Parse URL options into a key/value map.
Bool_t RegisterCommand(const char *cmdname, const char *method, const char *icon=0)
Register command which can be executed from web interface.
Mother of all ROOT objects.
static const char * GetMimeType(const char *path)
Guess mime type base on file extension.
Bool_t Unregister(TObject *obj)
Unregister object.
TString fContent
! text content (if any)
virtual const char * GetTitle() const
Returns title of object.
Long_t fMainThrdId
! id of the main ROOT process
void AddHeader(const char *name, const char *value)
Set name: value pair to reply header Content-Type field handled separately - one should use SetConten...
TString fMethod
! request method like GET or POST
static char * ReadFileContent(const char *filename, Int_t &len)
Reads content of file from the disk.
void SetReadOnly(Bool_t on=kTRUE)
When readonly on (default), sniffer is not allowed to change ROOT structures For instance, it is not allowed to read new objects from files.
const char * GetCors() const
Returns specified CORS domain.
virtual void Add(TObject *obj)
void SetFile(const char *filename=0)
indicate that http request should response with file content
Bool_t SetIcon(const char *fullname, const char *iconname)
set name of icon, used in browser together with the item
void SetOptions(const char *opt)
Bool_t IsContentType(const char *typ) const
TList fCallArgs
! submitted arguments
static Bool_t VerifyFilePath(const char *fname)
Checked that filename does not contains relative path below current directory Used to prevent access ...
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Int_t GetIntValueFromOptions(const char *key) const
Return a value for a given key from the URL options as an Int_t, a missing key returns -1...
TString fJSROOT
! location of external JSROOT files
virtual const char * GetName() const
Returns name of object.
virtual Int_t GetSize() const
void SetCurrentCallArg(THttpCallArg *arg)
set current http arguments, which then used in different process methods For instance, if user authorized with some user name, depending from restrictions some objects will be invisible or user get full access to the element
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
void SetDrawPage(const char *filename)
Set file name of HTML page, delivered by the server when objects drawing page is requested from the b...
void SetScanGlobalDir(Bool_t on=kTRUE)
When enabled (default), sniffer scans gROOT for files, canvases, histograms.
Bool_t HasOption(const char *key) const
Returns true if the given key appears in the URL options list.
TRootSniffer * GetSniffer() const
returns pointer on objects sniffer
TString fFileName
! file name
Bool_t SetItemField(const char *fullname, const char *name, const char *value)
const char * GetItemField(TFolder *parent, TObject *item, const char *name)
return field for specified item
Bool_t IsFileRequested(const char *uri, TString &res) const
Check if file is requested, thread safe.
void Restrict(const char *path, const char *options)
Restrict access to specified object.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
void Resize(Ssiz_t n)
Resize the string. Truncate or add blanks as necessary.
ULong_t GetStreamerInfoHash()
Returns hash value for streamer infos At the moment - just number of items in streamer infos list...
void SetDefaultPage(const char *filename)
Set file name of HTML page, delivered by the server when http address is opened in the browser...
TObject * FindTObjectInHierarchy(const char *path)
Search element in hierarchy, derived from TObject.
virtual void RemoveFirst()
void SetJSROOT(const char *location)
Set location of JSROOT to use with the server One could specify address like: https://root.cern.ch/js/3.3/ http://web-docs.gsi.de/~linev/js/3.3/ This allows to get new JSROOT features with old server, reduce load on THttpServer instance, also startup time can be improved When empty string specified (default), local copy of JSROOT is used (distributed with ROOT)
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
const char * Data() const