13 #include "RConfigure.h" 38 class THttpTimer :
public TTimer {
44 TTimer(milliSec, mode), fServer(serv)
136 fLocations.SetOwner(
kTRUE);
140 #ifdef COMPILED_WITH_DABC 147 if (jsrootsys != 0) fJSROOTSYS = jsrootsys;
149 if (fJSROOTSYS.Length() == 0) {
152 Warning(
"THttpServer",
"problems resolving '%s', use JSROOTSYS to specify $ROOTSYS/etc/http location", jsdir.
Data());
159 AddLocation(
"currentdir/",
".");
160 AddLocation(
"jsrootsys/", fJSROOTSYS);
163 fDefaultPage = fJSROOTSYS +
"/files/online.htm";
164 fDrawPage = fJSROOTSYS +
"/files/draw.htm";
171 if (strchr(engine,
';') == 0) {
172 CreateEngine(engine);
178 if ((strcmp(opt,
"readonly") == 0) || (strcmp(opt,
"ro") == 0)) {
179 GetSniffer()->SetReadOnly(
kTRUE);
180 }
else if ((strcmp(opt,
"readwrite") == 0) || (strcmp(opt,
"rw") == 0)) {
181 GetSniffer()->SetReadOnly(
kFALSE);
209 if (fSniffer)
delete fSniffer;
218 return fSniffer ? fSniffer->IsReadOnly() :
kTRUE;
228 if (fSniffer) fSniffer->SetReadOnly(readonly);
239 if ((prefix==0) || (*prefix==0))
return;
241 TNamed *obj =
dynamic_cast<TNamed*
> (fLocations.FindObject(prefix));
245 fLocations.Add(
new TNamed(prefix, path));
260 fJSROOT = location ? location :
"";
271 if ((filename!=0) && (*filename!=0))
274 fDefaultPage = fJSROOTSYS +
"/files/online.htm";
277 fDefaultPageCont.Clear();
288 if ((filename!=0) && (*filename!=0))
291 fDrawPage = fJSROOTSYS +
"/files/draw.htm";
294 fDrawPageCont.Clear();
309 if (engine == 0)
return kFALSE;
311 const char *arg = strchr(engine,
':');
312 if (arg == 0)
return kFALSE;
315 if (arg != engine) clname.
Append(engine, arg - engine);
317 if ((clname.
Length() == 0) || (clname ==
"http") || (clname ==
"civetweb"))
318 clname =
"TCivetweb";
319 else if (clname ==
"fastcgi")
321 else if (clname ==
"dabc")
322 clname =
"TDabcEngine";
326 if (engine_class == 0)
return kFALSE;
329 if (eng == 0)
return kFALSE;
333 if (!eng->
Create(arg + 1)) {
360 fTimer =
new THttpTimer(milliSec, mode,
this);
371 if ((fname == 0) || (*fname == 0))
return kFALSE;
375 while (*fname != 0) {
378 const char *next = strpbrk(fname,
"/\\");
379 if (next == 0)
return kTRUE;
382 if ((next == fname + 2) && (*fname ==
'.') && (*(fname + 1) ==
'.')) {
385 if (level < 0)
return kFALSE;
390 if ((next == fname + 1) && (*fname ==
'.')) {
417 if ((uri == 0) || (strlen(uri) == 0))
return kFALSE;
421 TIter iter(&fLocations);
423 while ((obj=iter()) != 0) {
425 if (pos ==
kNPOS)
continue;
427 if (!VerifyFilePath(fname.
Data()))
return kFALSE;
474 Error(
"ProcessRequests",
"Should be called only from main ROOT thread");
482 if (fCallArgs.GetSize() > 0) {
484 fCallArgs.RemoveFirst();
490 fSniffer->SetCurrentCallArg(arg);
494 fSniffer->SetCurrentCallArg(0);
496 fSniffer->SetCurrentCallArg(0);
503 TIter iter(&fEngines);
519 if (fDefaultPageCont.Length() == 0) {
521 char *buf = ReadFileContent(fDefaultPage.Data(), len);
522 if (len > 0) fDefaultPageCont.Append(buf, len);
526 if (fDefaultPageCont.Length() == 0) {
532 if (fJSROOT.Length() > 0) {
538 const char *hjsontag =
"\"$$$h.json$$$\"";
544 const char *topname = fTopName.Data();
546 fSniffer->ScanHierarchy(topname, arg->
fPathName.
Data(), &store);
550 arg->
AddHeader(
"Cache-Control",
"private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0");
559 if (fDrawPageCont.Length() == 0) {
561 char *buf = ReadFileContent(fDrawPage.Data(), len);
562 if (len > 0) fDrawPageCont.Append(buf, len);
566 if (fDrawPageCont.Length() == 0) {
569 const char *rootjsontag =
"\"$$$root.json$$$\"";
570 const char *hjsontag =
"\"$$$h.json$$$\"";
575 if (fJSROOT.Length() > 0) {
584 const char *topname = fTopName.Data();
595 if (fSniffer->Produce(arg->
fPathName.
Data(),
"root.json",
"compact=3", bindata, bindatalen, str)) {
599 arg->
AddHeader(
"Cache-Control",
"private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0");
622 if ((filename ==
"h.xml") || (filename ==
"get.xml")) {
626 arg->
fContent.
Form(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
633 const char *topname = fTopName.Data();
635 fSniffer->ScanHierarchy(topname, arg->
fPathName.
Data(), &store, filename ==
"get.xml");
644 if (filename ==
"h.json") {
646 const char *topname = fTopName.Data();
648 fSniffer->ScanHierarchy(topname, arg->
fPathName.
Data(), &store);
653 if (bindata != 0) arg->
SetBinData(bindata, bindatalen);
662 if (arg->
Is404())
return;
666 if (filename ==
"root.bin") {
669 const char *parname = fSniffer->IsStreamerInfoItem(arg->
fPathName.
Data()) ?
"BVersion" :
"MVersion";
670 arg->
AddHeader(parname,
Form(
"%u", (
unsigned) fSniffer->GetStreamerInfoHash()));
674 arg->
AddHeader(
"Cache-Control",
"private, no-cache, no-store, must-revalidate, max-age=0, proxy-revalidate, s-maxage=0");
684 return fSniffer->RegisterObject(subfolder, obj);
694 return fSniffer->UnregisterObject(obj);
704 fSniffer->Restrict(path, options);
737 return fSniffer->RegisterCommand(cmdname, method, icon);
745 return SetItemField(foldername,
"_hidden", hide ?
"true" : (
const char *) 0);
756 return SetItemField(fullname,
"_icon", iconname);
763 return fSniffer->CreateItem(fullname, title);
770 return fSniffer->SetItemField(fullname, name, value);
777 return fSniffer->GetItemField(fullname, name);
785 static const struct {
790 {
".xml", 4,
"text/xml"},
791 {
".json", 5,
"application/json"},
792 {
".bin", 4,
"application/x-binary"},
793 {
".gif", 4,
"image/gif"},
794 {
".jpg", 4,
"image/jpeg"},
795 {
".png", 4,
"image/png"},
796 {
".html", 5,
"text/html"},
797 {
".htm", 4,
"text/html"},
798 {
".shtm", 5,
"text/html"},
799 {
".shtml", 6,
"text/html"},
800 {
".css", 4,
"text/css"},
801 {
".js", 3,
"application/x-javascript"},
802 {
".ico", 4,
"image/x-icon"},
803 {
".jpeg", 5,
"image/jpeg"},
804 {
".svg", 4,
"image/svg+xml"},
805 {
".txt", 4,
"text/plain"},
806 {
".torrent", 8,
"application/x-bittorrent"},
807 {
".wav", 4,
"audio/x-wav"},
808 {
".mp3", 4,
"audio/x-mp3"},
809 {
".mid", 4,
"audio/mid"},
810 {
".m3u", 4,
"audio/x-mpegurl"},
811 {
".ogg", 4,
"application/ogg"},
812 {
".ram", 4,
"audio/x-pn-realaudio"},
813 {
".xslt", 5,
"application/xml"},
814 {
".xsl", 4,
"application/xml"},
815 {
".ra", 3,
"audio/x-pn-realaudio"},
816 {
".doc", 4,
"application/msword"},
817 {
".exe", 4,
"application/octet-stream"},
818 {
".zip", 4,
"application/x-zip-compressed"},
819 {
".xls", 4,
"application/excel"},
820 {
".tgz", 4,
"application/x-tar-gz"},
821 {
".tar", 4,
"application/x-tar"},
822 {
".gz", 3,
"application/x-gunzip"},
823 {
".arj", 4,
"application/x-arj-compressed"},
824 {
".rar", 4,
"application/x-arj-compressed"},
825 {
".rtf", 4,
"application/rtf"},
826 {
".pdf", 4,
"application/pdf"},
827 {
".swf", 4,
"application/x-shockwave-flash"},
828 {
".mpg", 4,
"video/mpeg"},
829 {
".webm", 5,
"video/webm"},
830 {
".mpeg", 5,
"video/mpeg"},
831 {
".mov", 4,
"video/quicktime"},
832 {
".mp4", 4,
"video/mp4"},
833 {
".m4v", 4,
"video/x-m4v"},
834 {
".asf", 4,
"video/x-ms-asf"},
835 {
".avi", 4,
"video/x-msvideo"},
836 {
".bmp", 4,
"image/bmp"},
837 {
".ttf", 4,
"application/x-font-ttf"},
841 int path_len = strlen(path);
861 std::ifstream is(filename);
868 char *buf = (
char *)
malloc(len);
void SetZipping(Int_t kind)
virtual void Process()
Method regularly called in main ROOT context.
Namespace for new ROOT classes and functions.
Storage of hierarchy scan in TRootSniffer in JSON format.
TString & ReplaceAll(const TString &s1, const TString &s2)
const char * GetItemField(const char *fullname, const char *name)
Bool_t IsReadOnly() const
returns read-only mode
static const char * filename()
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
TString fQuery
authenticated user name (if any)
static const TString & GetRootSys()
Get the rootsys directory in the installation. Static utility function.
TObject * At(Int_t idx) const
void SetServer(THttpServer *serv)
void SetContentType(const char *typ)
void ProcessRequests()
Process submitted requests, must be called from main thread.
Bool_t CreateItem(const char *fullname, const char *title)
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Vc_ALWAYS_INLINE void free(T *p)
Frees memory that was allocated with Vc::malloc.
The TNamed class is the base class for all named ROOT classes.
virtual const char * Getenv(const char *env)
Get environment variable.
TString fPathName
request method like GET or POST
TString & Append(const char *cs)
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
std::vector< std::vector< double > > Data
static Long_t SelfId()
Static method returning the id for the current thread.
void SetTimer(Long_t milliSec=100, Bool_t mode=kTRUE)
create timer which will invoke ProcessRequests() function periodically Timer is required to perform a...
Storage of hierarchy scan in TRootSniffer in XML format.
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 ...
Int_t Wait()
Wait to be signaled.
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
Bool_t CreateEngine(const char *engine)
factory method to create different http engines At the moment two engine kinds are supported: civetwe...
R__EXTERN TSystem * gSystem
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
virtual ~THttpServer()
destructor delete all http engines and sniffer
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
char * Form(const char *fmt,...)
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.
Bool_t ExecuteHttp(THttpCallArg *arg)
Execute HTTP request.
TString & Remove(Ssiz_t pos)
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
virtual void ProcessRequest(THttpCallArg *arg)
submitted arguments
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Bool_t RegisterCommand(const char *cmdname, const char *method, const char *icon=0)
Register command which can be executed from web interface.
TCondition fCond
length of binary data
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
response header like ContentEncoding, Cache-Control and so on
virtual const char * GetTitle() const
Returns title of object.
void AddHeader(const char *name, const char *value)
Set name: value pair to reply header Content-Type field handled separately - one should use SetConten...
static char * ReadFileContent(const char *filename, Int_t &len)
Reads content of file from the disk.
static const struct @201 builtin_mime_types[]
void SetFile(const char *filename=0)
Bool_t SetIcon(const char *fullname, const char *iconname)
set name of icon, used in browser together with the item
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 ~.
virtual const char * GetName() const
Returns name of object.
virtual void SetTitle(const char *title="")
Change (i.e. set) the title of the TNamed.
Vc_ALWAYS_INLINE_L T *Vc_ALWAYS_INLINE_R malloc(size_t n)
Allocates memory on the Heap with alignment and padding suitable for vectorized access.
void SetDrawPage(const char *filename)
Set file name of HTML page, delivered by the server when objects drawing page is requested from the b...
TString fFileName
item path
Bool_t SetItemField(const char *fullname, const char *name, const char *value)
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.
void SetDefaultPage(const char *filename)
Set file name of HTML page, delivered by the server when http address is opened in the browser...
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