22#include "RConfigure.h"
130 jsrootsys =
gEnv->
GetValue(
"HttpServ.JSRootPath", jsrootsys);
132 if (jsrootsys && *jsrootsys) {
133 if ((strncmp(jsrootsys,
"http://", 7)==0) || (strncmp(jsrootsys,
"https://", 8)==0))
142 ::Warning(
"THttpServer::THttpServer",
"problems resolving '%s', set JSROOTSYS to proper JavaScript ROOT location",
150 Bool_t basic_sniffer = strstr(engine,
"basic_sniffer") !=
nullptr;
154 if (!basic_sniffer) {
168 sniff = (
TRootSniffer *)
gROOT->ProcessLineSync(
"new TRootSnifferFull(\"sniff\");");
176 if (strchr(engine,
';') == 0) {
183 if ((strcmp(opt,
"readonly") == 0) || (strcmp(opt,
"ro") == 0)) {
185 }
else if ((strcmp(opt,
"readwrite") == 0) || (strcmp(opt,
"rw") == 0)) {
187 }
else if (strcmp(opt,
"global") == 0) {
189 }
else if (strcmp(opt,
"noglobal") == 0) {
191 }
else if (strncmp(opt,
"cors=", 5) == 0) {
193 }
else if (strcmp(opt,
"cors") == 0) {
214 while (
auto engine =
dynamic_cast<THttpEngine *
>(iter()))
297 if (!prefix || (*prefix == 0))
320 fJSROOT = location ? location :
"";
387 const char *arg = strchr(engine,
':');
393 clname.
Append(engine, arg - engine);
398 if ((clname.
Length() == 0) || (clname ==
"http") || (clname ==
"civetweb")) {
401 }
else if (clname ==
"socket") {
407 }
else if (clname ==
"https") {
409 }
else if (clname ==
"fastcgi") {
461 Error(
"SetTimer",
"Server runs already in special thread, therefore no any timer can be created");
463 fTimer = std::make_unique<THttpTimer>(milliSec,
mode, *
this);
487 std::thread thrd([
this] {
497 std::this_thread::sleep_for(std::chrono::milliseconds(1));
502 fThrd = std::move(thrd);
527 if (!fname || (*fname == 0))
532 while (*fname != 0) {
535 const char *next = strpbrk(fname,
"/\");
540 if ((next == fname + 2) && (*fname ==
'.') && (*(fname + 1) ==
'.')) {
549 if ((next == fname + 1) && (*fname ==
'.')) {
577 if (!uri || (*uri == 0))
586 fname.
Remove(0, pos + (entry.first.length() - 1));
589 res = entry.second.c_str();
590 if ((fname[0] ==
'/') && (res[res.
Length() - 1] ==
'/'))
619 std::unique_lock<std::mutex> lk(
fMutex);
648 arg->NotifyCondition();
653 std::unique_lock<std::mutex> lk(
fMutex);
674 Error(
"ProcessRequests",
"Should be called only from main ROOT thread");
680 std::unique_lock<std::mutex> lk(
fMutex, std::defer_lock);
684 std::shared_ptr<THttpCallArg> arg;
687 if (!
fArgs.empty()) {
696 if (arg->fFileName ==
"root_batch_holder.js") {
701 fSniffer->SetCurrentCallArg(arg.get());
706 fSniffer->SetCurrentCallArg(
nullptr);
708 fSniffer->SetCurrentCallArg(
nullptr);
711 arg->NotifyCondition();
717 while ((engine = (
THttpEngine *)iter()) !=
nullptr) {
745 auto wsptr =
FindWS(arg->GetPathName());
747 if (!wsptr || !wsptr->ProcessBatchHolder(arg)) {
749 arg->NotifyCondition();
759 std::string arr =
"[";
762 std::lock_guard<std::mutex> grd(
fWSMutex);
764 if (arr.length() > 1)
767 arr.append(
Form(
"{ name: \"%s\", title: \"%s\" }", ws->GetName(), ws->GetTitle()));
775 std::string arg =
"\"$\"";
777 auto pos = res.find(arg);
778 if (pos != std::string::npos)
779 res.replace(pos, arg.length(), arr);
797 if (repl.back() !=
'/')
801 if (arg->fPathName.Length() > 0) cnt++;
802 for (
Int_t n = 1;
n < arg->fPathName.Length()-1; ++
n)
803 if (arg->fPathName[
n] ==
'/') {
804 if (arg->fPathName[
n-1] !=
'/') {
814 while (cnt-- >0) repl.append(
"../");
815 repl.append(
"jsrootsys/");
820 arg->ReplaceAllinContent(
"=\"jsrootsys/", repl);
821 arg->ReplaceAllinContent(
"from './jsrootsys/",
TString::Format(
"from '%s", repl.substr(2).c_str()).
Data());
838 if ((arg->fFileName ==
"root.websocket") || (arg->fFileName ==
"root.longpoll")) {
843 if (arg->fFileName.IsNull() || (arg->fFileName ==
"index.htm") || (arg->fFileName ==
"default.htm")) {
845 if (arg->fFileName ==
"default.htm") {
851 auto wsptr =
FindWS(arg->GetPathName());
853 auto handler = wsptr.get();
862 if (arg->fContent.find(
"file:") == 0) {
863 const char *fname = arg->fContent.c_str() + 5;
869 handler->VerifyDefaultPageContent(arg);
873 if (arg->fContent.empty() && arg->fFileName.IsNull() && arg->fPathName.IsNull() &&
IsWSOnly()) {
874 arg->SetContent(
"refused");
878 if (arg->fContent.empty() && !
IsWSOnly()) {
886 if (arg->fContent.empty()) {
889 }
else if (!arg->Is404()) {
893 const char *hjsontag =
"\"$\"";
896 if (arg->fContent.find(hjsontag) != std::string::npos) {
900 if (arg->fTopName.Length() > 0)
901 topname = arg->fTopName.Data();
902 fSniffer->ScanHierarchy(topname, arg->fPathName.Data(), &store);
904 arg->ReplaceAllinContent(hjsontag, h_json.
Data());
906 arg->AddNoCacheHeader();
908 if (arg->fQuery.Index(
"nozip") ==
kNPOS)
911 arg->SetContentType(
"text/html");
916 if ((arg->fFileName ==
"draw.htm") && !
IsWSOnly()) {
923 const char *rootjsontag =
"\"$\"";
924 const char *hjsontag =
"\"$\"";
930 if ((arg->fQuery.Index(
"no_h_json") ==
kNPOS) && (arg->fQuery.Index(
"webcanvas") ==
kNPOS) &&
931 (arg->fContent.find(hjsontag) != std::string::npos)) {
935 if (arg->fTopName.Length() > 0)
936 topname = arg->fTopName.Data();
937 fSniffer->ScanHierarchy(topname, arg->fPathName.Data(), &store,
kTRUE);
939 arg->ReplaceAllinContent(hjsontag, h_json.
Data());
942 if ((arg->fQuery.Index(
"no_root_json") ==
kNPOS) && (arg->fQuery.Index(
"webcanvas") ==
kNPOS) &&
943 (arg->fContent.find(rootjsontag) != std::string::npos)) {
945 if (
fSniffer->Produce(arg->fPathName.Data(),
"root.json",
"compact=23", str))
946 arg->ReplaceAllinContent(rootjsontag, str);
948 arg->AddNoCacheHeader();
949 if (arg->fQuery.Index(
"nozip") ==
kNPOS)
951 arg->SetContentType(
"text/html");
956 if ((arg->fFileName ==
"favicon.ico") && arg->fPathName.IsNull()) {
957 arg->SetFile(
fJSROOTSYS +
"/img/RootIcon.ico");
968 if (!arg->fPathName.IsNull() && !arg->fFileName.IsNull()) {
969 TString wsname = arg->fPathName, fname;
970 auto pos = wsname.
First(
'/');
972 wsname = arg->fPathName;
974 wsname = arg->fPathName(0, pos);
975 fname = arg->fPathName(pos + 1, arg->fPathName.Length() - pos);
979 fname.
Append(arg->fFileName);
985 if (ws && ws->CanServeFiles()) {
986 TString fdir = ws->GetDefaultPageContent();
988 if (fdir.
Index(
"file:") == 0) {
990 auto separ = fdir.
Last(
'/');
1013 if (arg->fContent.empty())
1017 Bool_t compact = arg->fQuery.Index(
"compact") !=
kNPOS;
1021 res.
Form(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
1031 if (arg->fTopName.Length() > 0)
1032 topname = arg->fTopName.Data();
1033 fSniffer->ScanHierarchy(topname, arg->fPathName.Data(), &store,
filename ==
"get.xml");
1040 arg->SetContent(std::string(res.
Data()));
1047 if (arg->fTopName.Length() > 0)
1048 topname = arg->fTopName.Data();
1049 fSniffer->ScanHierarchy(topname, arg->fPathName.Data(), &store);
1050 arg->SetContent(std::string(res.
Data()));
1052 }
else if (
fSniffer->Produce(arg->fPathName.Data(),
filename.Data(), arg->fQuery.Data(), arg->fContent)) {
1069 const char *parname =
fSniffer->IsStreamerInfoItem(arg->fPathName.Data()) ?
"BVersion" :
"MVersion";
1070 arg->AddHeader(parname,
Form(
"%u", (
unsigned)
fSniffer->GetStreamerInfoHash()));
1074 arg->AddNoCacheHeader();
1078 arg->AddHeader(
"Access-Control-Allow-Origin",
GetCors());
1088 return fSniffer->RegisterObject(subfolder, obj);
1098 return fSniffer->UnregisterObject(obj);
1108 std::lock_guard<std::mutex> grd(
fWSMutex);
1117 std::lock_guard<std::mutex> grd(
fWSMutex);
1130 std::lock_guard<std::mutex> grd(
fWSMutex);
1132 if (strcmp(
name, ws->GetName()) == 0)
1149 auto wsptr =
FindWS(arg->GetPathName());
1151 auto handler = wsptr.get();
1153 if (!handler && !external_thrd)
1156 if (external_thrd && (!handler || !handler->AllowMTProcess())) {
1157 std::unique_lock<std::mutex> lk(
fMutex);
1161 arg->fCond.wait(lk);
1171 if (arg->fFileName ==
"root.websocket") {
1173 process = handler->HandleWS(arg);
1174 }
else if (arg->fFileName ==
"root.longpoll") {
1176 if (arg->fQuery.BeginsWith(
"raw_connect") || arg->fQuery.BeginsWith(
"txt_connect")) {
1179 arg->SetMethod(
"WS_CONNECT");
1181 bool israw = arg->fQuery.BeginsWith(
"raw_connect");
1186 if (handler->HandleWS(arg)) {
1187 arg->SetMethod(
"WS_READY");
1189 if (handler->HandleWS(arg))
1190 arg->SetTextContent(std::string(israw ?
"txt:" :
"") + std::to_string(arg->GetWSId()));
1192 arg->TakeWSEngine();
1195 process = arg->IsText();
1202 arg->SetWSId(std::stoul(connid));
1204 arg->SetMethod(
"WS_CLOSE");
1205 arg->SetTextContent(
"OK");
1207 arg->SetMethod(
"WS_DATA");
1210 process = handler->HandleWS(arg);
1269 return fSniffer->RegisterCommand(cmdname, method, icon);
1277 return SetItemField(foldername,
"_hidden", hide ?
"true" : (
const char *)0);
1296 return fSniffer->CreateItem(fullname, title);
1320 static const struct {
1325 {
".json", 5,
"application/json"},
1326 {
".bin", 4,
"application/x-binary"},
1327 {
".gif", 4,
"image/gif"},
1328 {
".jpg", 4,
"image/jpeg"},
1329 {
".png", 4,
"image/png"},
1330 {
".html", 5,
"text/html"},
1331 {
".htm", 4,
"text/html"},
1332 {
".shtm", 5,
"text/html"},
1333 {
".shtml", 6,
"text/html"},
1334 {
".css", 4,
"text/css"},
1335 {
".js", 3,
"application/x-javascript"},
1336 {
".mjs", 4,
"text/javascript"},
1337 {
".ico", 4,
"image/x-icon"},
1338 {
".jpeg", 5,
"image/jpeg"},
1339 {
".svg", 4,
"image/svg+xml"},
1340 {
".txt", 4,
"text/plain"},
1341 {
".torrent", 8,
"application/x-bittorrent"},
1342 {
".wav", 4,
"audio/x-wav"},
1343 {
".mp3", 4,
"audio/x-mp3"},
1344 {
".mid", 4,
"audio/mid"},
1345 {
".m3u", 4,
"audio/x-mpegurl"},
1346 {
".ogg", 4,
"application/ogg"},
1347 {
".ram", 4,
"audio/x-pn-realaudio"},
1348 {
".xslt", 5,
"application/xml"},
1349 {
".xsl", 4,
"application/xml"},
1350 {
".ra", 3,
"audio/x-pn-realaudio"},
1351 {
".doc", 4,
"application/msword"},
1352 {
".exe", 4,
"application/octet-stream"},
1353 {
".zip", 4,
"application/x-zip-compressed"},
1354 {
".xls", 4,
"application/excel"},
1355 {
".tgz", 4,
"application/x-tar-gz"},
1356 {
".tar", 4,
"application/x-tar"},
1357 {
".gz", 3,
"application/x-gunzip"},
1358 {
".arj", 4,
"application/x-arj-compressed"},
1359 {
".rar", 4,
"application/x-arj-compressed"},
1360 {
".rtf", 4,
"application/rtf"},
1361 {
".pdf", 4,
"application/pdf"},
1362 {
".swf", 4,
"application/x-shockwave-flash"},
1363 {
".mpg", 4,
"video/mpeg"},
1364 {
".webm", 5,
"video/webm"},
1365 {
".mpeg", 5,
"video/mpeg"},
1366 {
".mov", 4,
"video/quicktime"},
1367 {
".mp4", 4,
"video/mp4"},
1368 {
".m4v", 4,
"video/x-m4v"},
1369 {
".asf", 4,
"video/x-ms-asf"},
1370 {
".avi", 4,
"video/x-msvideo"},
1371 {
".bmp", 4,
"image/bmp"},
1372 {
".ttf", 4,
"application/x-font-ttf"},
1373 {
".woff", 5,
"font/woff"},
1374 {
".woff2", 6,
"font/woff2"},
1377 int path_len = strlen(path);
1388 return "text/plain";
1400 std::ifstream is(
filename, std::ios::in | std::ios::binary);
1404 is.seekg(0, is.end);
1406 is.seekg(0, is.beg);
1424 std::ifstream is(
filename, std::ios::in | std::ios::binary);
1427 is.seekg(0, std::ios::end);
1428 res.resize(is.tellg());
1429 is.seekg(0, std::ios::beg);
1430 is.read((
char *)res.data(), res.length());
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void on
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char mode
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
R__EXTERN TSystem * gSystem
static const struct @144 builtin_mime_types[]
THttpEngine implementation, based on civetweb embedded server.
TClass instances represent classes, structs and namespaces in the ROOT type system.
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
static TClass * LoadClass(const char *requestedname, Bool_t silent)
Helper function used by TClass::GetClass().
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
THttpEngine implementation, based on fastcgi package.
Contains arguments for single HTTP call.
void Set404()
mark reply as 404 error - page/request not exists or refused
Abstract class for implementing http protocol for THttpServer.
void SetServer(THttpServer *serv)
virtual Bool_t Create(const char *)
Method to create all components of engine.
virtual void Process()
Method regularly called in main ROOT context.
virtual void Terminate()
Method called when server want to be terminated.
Emulation of websocket with long poll requests.
Online http server for arbitrary ROOT application.
Bool_t IsReadOnly() const
returns read-only mode
Bool_t RegisterCommand(const char *cmdname, const char *method, const char *icon=nullptr)
Register command which can be executed from web interface.
TString fJSROOT
! location of external JSROOT files
virtual void ProcessRequest(std::shared_ptr< THttpCallArg > arg)
Process single http request.
std::shared_ptr< THttpWSHandler > FindWS(const char *name)
Find web-socket handler with given name.
std::unique_ptr< TRootSniffer > fSniffer
! sniffer provides access to ROOT objects hierarchy
void SetTimer(Long_t milliSec=100, Bool_t mode=kTRUE)
Create timer which will invoke ProcessRequests() function periodically.
virtual void ProcessBatchHolder(std::shared_ptr< THttpCallArg > &arg)
Process special http request for root_batch_holder.js script.
std::vector< std::shared_ptr< THttpWSHandler > > fWSHandlers
! list of WS handlers
virtual ~THttpServer()
destructor
void SetTerminate()
set termination flag, no any further requests will be processed
virtual void MissedRequest(THttpCallArg *arg)
Method called when THttpServer cannot process request.
Bool_t fOwnThread
! true when specialized thread allocated for processing requests
void SetSniffer(TRootSniffer *sniff)
Set TRootSniffer to the server.
Bool_t IsFileRequested(const char *uri, TString &res) const
Check if file is requested, thread safe.
void SetReadOnly(Bool_t readonly=kTRUE)
Set read-only mode for the server (default on)
const char * GetItemField(const char *fullname, const char *name)
Get item field from sniffer.
const char * GetCors() const
Returns specified CORS domain.
std::thread fThrd
! own thread
void StopServerThread()
Stop server thread.
Int_t ProcessRequests()
Process submitted requests, must be called from appropriate thread.
Bool_t ExecuteWS(std::shared_ptr< THttpCallArg > &arg, Bool_t external_thrd=kFALSE, Bool_t wait_process=kFALSE)
Execute WS request.
void RegisterWS(std::shared_ptr< THttpWSHandler > ws)
Register WS handler.
TString fTopName
! name of top folder, default - "ROOT"
void SetDrawPage(const std::string &filename="")
Set drawing HTML page.
Bool_t CreateItem(const char *fullname, const char *title)
Create item in sniffer.
Bool_t ExecuteHttp(std::shared_ptr< THttpCallArg > arg)
Execute HTTP request.
Bool_t Hide(const char *fullname, Bool_t hide=kTRUE)
Hides folder or element from web gui.
void AddLocation(const char *prefix, const char *path)
Add files location, which could be used in the server.
std::map< std::string, std::string > fLocations
! list of local directories, which could be accessed via server
Bool_t SubmitHttp(std::shared_ptr< THttpCallArg > arg, Bool_t can_run_immediately=kFALSE)
Submit HTTP request.
Long_t fMainThrdId
! id of the thread for processing requests
TString fJSROOTSYS
! location of local JSROOT files
std::unique_ptr< THttpTimer > fTimer
! timer used to access main thread
Bool_t fWSOnly
! when true, handle only websockets / longpoll engine
Bool_t Register(const char *subfolder, TObject *obj)
Register object in subfolder.
TList fEngines
! engines which runs http server
void SetCors(const std::string &domain="*")
Enable CORS header to ProcessRequests() responses Specified location (typically "*") add as "Access-C...
Bool_t IsCors() const
Returns kTRUE if CORS was configured.
std::queue< std::shared_ptr< THttpCallArg > > fArgs
! submitted arguments
void SetDefaultPage(const std::string &filename="")
Set default HTML page.
THttpServer(const THttpServer &)=delete
static char * ReadFileContent(const char *filename, Int_t &len)
Reads content of file from the disk.
void CreateServerThread()
Creates special thread to process all requests, directed to http server.
std::string fDrawPageCont
! content of draw html page
Bool_t Unregister(TObject *obj)
Unregister object.
void SetWSOnly(Bool_t on=kTRUE)
Set websocket-only mode.
void ReplaceJSROOTLinks(std::shared_ptr< THttpCallArg > &arg)
Replaces all references like "jsrootsys/...".
std::string BuildWSEntryPage()
Create summary page with active WS handlers.
Bool_t IsWSOnly() const
returns true if only websockets are handled by the server
std::mutex fWSMutex
! mutex to protect WS handler lists
Bool_t CreateEngine(const char *engine)
Factory method to create different http engines.
Bool_t SetIcon(const char *fullname, const char *iconname)
Set name of icon, used in browser together with the item.
std::string fDrawPage
! file name for drawing of single element
std::string fDefaultPageCont
! content of default html page
static Bool_t VerifyFilePath(const char *fname)
Checked that filename does not contains relative path below current directory.
Bool_t SetItemField(const char *fullname, const char *name, const char *value)
Set item field in sniffer.
void SetJSROOT(const char *location)
Set location of JSROOT to use with the server.
std::mutex fMutex
! mutex to protect list with arguments
std::string fDefaultPage
! file name for default page name
void UnregisterWS(std::shared_ptr< THttpWSHandler > ws)
Unregister WS handler.
static const char * GetMimeType(const char *path)
Guess mime type base on file extension.
TRootSniffer * GetSniffer() const
returns pointer on objects sniffer
Bool_t fTerminated
! termination flag, disables all requests processing
void Restrict(const char *path, const char *options)
Restrict access to specified object.
void Timeout() override
timeout handler used to process http requests in main ROOT thread
THttpTimer(Long_t milliSec, Bool_t mode, THttpServer &serv)
!< server processing requests
Class for user-side handling of websocket with THttpServer.
virtual TString GetDefaultPageContent()
Provides content of default web page for registered web-socket handler Can be content of HTML page or...
void Add(TObject *obj) override
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
The TNamed class is the base class for all named ROOT classes.
TObject * At(Int_t idx) const override
Int_t GetLast() const override
Return index of last object in array.
Mother of all ROOT objects.
virtual const char * GetName() const
Returns name of object.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
static const TString & GetRootSys()
Get the rootsys directory in the installation. Static utility function.
static const TString & GetDataDir()
Get the data directory in the installation. Static utility function.
Storage of hierarchy scan in TRootSniffer in JSON format.
Storage of hierarchy scan in TRootSniffer in XML format.
Sniffer of ROOT objects, data provider for THttpServer.
void CreateOwnTopFolder()
Create own TFolder structures independent from gROOT This allows to have many independent TRootSniffe...
void SetReadOnly(Bool_t on=kTRUE)
When readonly on (default), sniffer is not allowed to change ROOT structures For instance,...
void SetScanGlobalDir(Bool_t on=kTRUE)
When enabled (default), sniffer scans gROOT for files, canvases, histograms.
Ssiz_t First(char c) const
Find first occurrence of a character c.
const char * Data() const
void Resize(Ssiz_t n)
Resize the string. Truncate or add blanks as necessary.
Ssiz_t Last(char c) const
Find last occurrence of a character c.
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
TString & Remove(Ssiz_t pos)
TString & Append(const char *cs)
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
virtual const char * Getenv(const char *env)
Get environment variable.
static Long_t SelfId()
Static method returning the id for the current thread.
Handles synchronous and a-synchronous timer events.
This class represents a WWW compatible URL.
const char * GetValueFromOptions(const char *key) const
Return a value for a given key from the URL options.
void SetOptions(const char *opt)
void ParseOptions() const
Parse URL options into a key/value map.
Bool_t HasOption(const char *key) const
Returns true if the given key appears in the URL options list.