33#include "../../../core/foundation/res/ROOT/RSha256.hxx"
36using namespace std::string_literals;
45 fHold->SetTextContent(
"console.log('execute holder script'); if (window) setTimeout (window.close, 1000); if (window) window.close();");
46 fHold->NotifyCondition();
90 std::vector<MasterConn> lst;
96 for (
auto &entry : lst)
97 fMaster->RemoveEmbedWindow(entry.connid, entry.channel);
116 for (
auto &conn : lst) {
117 conn->fActive =
false;
118 for (
auto &elem: conn->fEmbed)
119 elem.second->RemoveMasterConnection();
120 conn->fEmbed.clear();
123 fMgr->Unregister(*
this);
136 if (!
fConn.empty()) {
151std::shared_ptr<RWebWindowWSHandler>
175 return fMgr->GetUrl(*
this, remote);
183 return fMgr->GetServer();
193 return fMgr->ShowWindow(*
this, args);
210 connid =
fMgr->ShowWindow(*
this, args);
226 if (entry->fHeadlessMode)
227 return entry->fConnId;
230 for (
auto &conn :
fConn) {
231 if (conn->fHeadlessMode)
232 return conn->fConnId;
249 if (!entry->fHeadlessMode)
250 return entry->fConnId;
253 for (
auto &conn :
fConn) {
254 if (!conn->fHeadlessMode)
255 return conn->fConnId;
268 for (
auto &conn :
fConn) {
269 if (conn->fWSId == wsid)
282 std::shared_ptr<WebConn> res;
287 for (
size_t n = 0;
n <
fConn.size(); ++
n)
288 if (
fConn[
n]->fWSId == wsid) {
289 res = std::move(
fConn[
n]);
291 res->fActive =
false;
292 res->fWasFirst = (
n == 0);
298 for (
auto &elem: res->fEmbed)
299 elem.second->RemoveMasterConnection(res->fConnId);
328 std::vector<MasterConn> lst;
335 if (!connid || entry.connid == connid)
336 lst.emplace_back(entry);
357 if (iter->connid == connid) {
377 std::string query = arg->GetQuery();
379 if (query.compare(0, 4,
"key=") != 0)
382 std::string key = query.substr(4);
384 std::shared_ptr<THttpCallArg> prev;
386 bool found_key =
false;
392 if (entry->fKey == key) {
395 prev = std::move(entry->fHold);
400 for (
auto &conn :
fConn) {
401 if (conn->fKey == key) {
403 prev = std::move(conn->fHold);
411 prev->SetTextContent(
"console.log('execute holder script'); if (window) window.close();");
412 prev->NotifyCondition();
454 connid = entry.fConnId;
456 arg = std::move(entry.fData);
488 if (entry->fKey == key) {
489 entry->fHeadlessMode = headless_mode;
490 std::swap(entry->fDisplayHandle, handle);
491 return entry->fConnId;
495 auto conn = std::make_shared<WebConn>(++
fConnCnt, headless_mode, key);
497 std::swap(conn->fDisplayHandle, handle);
514bool RWebWindow::_CanTrustIn(std::shared_ptr<WebConn> &conn,
const std::string &hash,
const std::string &ntry,
bool remote,
bool test_first_time)
519 int intry = ntry.empty() ? -1 : std::stoi(ntry);
522 auto expected =
HMAC(conn->fKey,
fMgr->fUseSessionKey && remote ?
fMgr->fSessionKey :
""s, msg.Data(), msg.Length());
525 return (conn->fKey.empty() && hash.empty()) || (hash == conn->fKey) || (hash == expected);
528 if (!remote && ((hash == conn->fKey) || (hash == expected)))
531 if (hash == expected) {
532 if (test_first_time) {
533 if (conn->fKeyUsed >= intry) {
540 conn->fKeyUsed = intry;
542 if (conn->fKeyUsed != intry) {
567 if (entry->fKey == key)
571 for (
auto &conn :
fConn) {
572 if (conn->fKey == key)
574 if (also_newkey && (conn->fNewKey == key))
591 auto pred = [&](std::shared_ptr<WebConn> &
e) {
592 if (
e->fKey == key) {
603 for (
auto &conn : lst)
631 float tmout =
fMgr->GetLaunchTmout();
638 auto pred = [&](std::shared_ptr<WebConn> &
e) {
639 std::chrono::duration<double> diff =
stamp -
e->fSendStamp;
641 if (diff.count() > tmout) {
642 R__LOG_DEBUG(0,
WebGUILog()) <<
"Remove pending connection " <<
e->fKey <<
" after " << diff.count() <<
" sec";
643 selected.emplace_back(
e);
663 double batch_tmout = 20.;
665 std::vector<std::shared_ptr<WebConn>> clr;
670 auto pred = [&](std::shared_ptr<WebConn> &conn) {
671 std::chrono::duration<double> diff =
stamp - conn->fSendStamp;
673 if ((diff.count() > batch_tmout) && conn->fHeadlessMode) {
674 conn->fActive =
false;
675 clr.emplace_back(conn);
684 for (
auto &entry : clr)
758 std::string key, ntry;
766 if (is_longpoll && !is_remote && ntry ==
"1"s) {
770 for (
unsigned indx = 0; indx <
fConn.size(); indx++) {
771 if (!
fConn[indx]->fNewKey.empty() && (key ==
HMAC(
fConn[indx]->fNewKey,
""s,
"attempt_1", 9))) {
772 auto conn = std::move(
fConn[indx]);
775 conn->fKey = conn->fNewKey;
776 conn->fNewKey.clear();
778 conn->fWasFirst = indx == 0;
808 if (
_CanTrustIn(conn, key, ntry, is_remote,
true ))
821 std::shared_ptr<WebConn> conn;
822 std::string key, ntry;
843 conn->fActive =
true;
852 fConn.emplace_back(conn);
872 std::string key, ntry;
878 if (!
_CanTrustIn(conn, key, ntry, is_remote,
true ))
889 bool do_clear_on_close =
false;
890 if (!conn->fNewKey.empty()) {
894 conn->fKey = conn->fNewKey;
895 conn->fNewKey.clear();
905 if (do_clear_on_close)
929 const char *buf0 = (
const char *) arg.
GetPostData();
932 const char *buf = strchr(buf0,
':');
938 Int_t code_len = buf - buf0;
939 data_len -= code_len + 1;
947 bool is_none = strncmp(buf0,
"none:", 5) == 0, is_match =
false;
950 std::string hmac =
HMAC(conn->fKey,
fMgr->fSessionKey, buf, data_len);
952 is_match = (code_len == (
Int_t) hmac.length()) && (strncmp(buf0, hmac.c_str(), code_len) == 0);
953 }
else if (!
fMgr->fUseSessionKey) {
972 char *str_end =
nullptr;
974 unsigned long oper_seq = std::strtoul(buf, &str_end, 10);
975 if (!str_end || *str_end !=
':') {
980 if (is_remote && (oper_seq <= conn->fRecvSeq)) {
985 conn->fRecvSeq = oper_seq;
987 unsigned long ackn_oper = std::strtoul(str_end + 1, &str_end, 10);
988 if (!str_end || *str_end !=
':') {
993 unsigned long can_send = std::strtoul(str_end + 1, &str_end, 10);
994 if (!str_end || *str_end !=
':') {
999 unsigned long nchannel = std::strtoul(str_end + 1, &str_end, 10);
1000 if (!str_end || *str_end !=
':') {
1005 Long_t processed_len = (str_end + 1 - buf);
1007 if (processed_len > data_len) {
1012 std::string cdata(str_end + 1, data_len - processed_len);
1017 std::lock_guard<std::mutex> grd(conn->fMutex);
1019 conn->fSendCredits += ackn_oper;
1021 conn->fClientCredits = (
int)can_send;
1022 conn->fRecvStamp =
stamp;
1030 if ((nchannel != 0) || (cdata.find(
"READY=") == 0)) {
1041 if (nchannel == 0) {
1043 if ((cdata.compare(0, 6,
"READY=") == 0) && !conn->fReady) {
1045 std::string key = cdata.substr(6);
1046 bool new_key =
false;
1047 if (key.find(
"generate_key;") == 0) {
1049 key = key.substr(13);
1057 if (!key.empty() && !conn->fKey.empty() && (conn->fKey != key)) {
1058 R__LOG_ERROR(
WebGUILog()) <<
"Key mismatch after established connection " << key <<
" != " << conn->fKey;
1073 if(!conn->fNewKey.empty())
1074 SubmitData(conn->fConnId,
true,
"NEW_KEY="s + conn->fNewKey, 0);
1076 }
else if (cdata.compare(0, 8,
"CLOSECH=") == 0) {
1077 int channel = std::stoi(cdata.substr(8));
1078 auto iter = conn->fEmbed.find(channel);
1079 if (iter != conn->fEmbed.end()) {
1081 conn->fEmbed.erase(iter);
1083 }
else if (cdata.compare(0, 7,
"RESIZE=") == 0) {
1084 auto p = cdata.find(
",");
1085 if (
p != std::string::npos) {
1086 auto width = std::stoi(cdata.substr(7,
p - 7));
1087 auto height = std::stoi(cdata.substr(
p + 1));
1088 if ((
width > 0) && (
height > 0) && conn->fDisplayHandle)
1091 }
else if (cdata ==
"GENERATE_KEY") {
1096 if(!conn->fNewKey.empty())
1097 SubmitData(conn->fConnId,
true,
"NEW_KEY="s + conn->fNewKey, -1);
1100 }
else if (
fPanelName.length() && (conn->fReady < 10)) {
1101 if (cdata ==
"PANEL_READY") {
1109 }
else if (nchannel == 1) {
1111 }
else if (nchannel > 1) {
1113 auto embed_window = conn->fEmbed[nchannel];
1115 embed_window->ProvideQueueEntry(conn->fConnId,
kind_Data, std::move(cdata));
1135 std::lock_guard<std::mutex> grd(conn->fMutex);
1136 conn->fDoingSend =
false;
1155 if (conn->fSendCredits <= 0) {
1160 if (conn->fDoingSend) {
1166 buf.reserve(
data.length() + 100);
1168 buf.append(std::to_string(conn->fSendSeq++));
1170 buf.append(std::to_string(conn->fRecvCount));
1172 buf.append(std::to_string(conn->fSendCredits));
1174 conn->fRecvCount = 0;
1175 conn->fSendCredits--;
1177 buf.append(std::to_string(chid));
1182 }
else if (
data.length()==0) {
1183 buf.append(
"$$nullbinary$$");
1185 buf.append(
"$$binary$$");
1186 if (!conn->fKey.empty() && !
fMgr->fSessionKey.empty() &&
fMgr->fUseSessionKey)
1187 buf.append(
HMAC(conn->fKey,
fMgr->fSessionKey,
data.data(),
data.length()));
1199 std::string hdr,
data, prefix;
1202 std::lock_guard<std::mutex> grd(conn->fMutex);
1204 if (!conn->fActive || (conn->fSendCredits <= 0) || conn->fDoingSend)
return false;
1206 if (!conn->fQueue.empty()) {
1209 if (!hdr.empty() && !item.
fText)
1212 }
else if ((conn->fClientCredits < 3) && (conn->fRecvCount > 1)) {
1217 if (hdr.empty())
return false;
1219 conn->fDoingSend =
true;
1223 if (!conn->fKey.empty() && !
fMgr->fSessionKey.empty() &&
fMgr->fUseSessionKey) {
1224 prefix =
HMAC(conn->fKey,
fMgr->fSessionKey, hdr.c_str(), hdr.length());
1230 hdr.insert(0, prefix);
1235 res =
fWSHandler->SendCharStarWS(conn->fWSId, hdr.c_str());
1237 res =
fWSHandler->SendHeaderWS(conn->fWSId, hdr.c_str(),
data.data(),
data.length());
1241 if (res >=0)
return true;
1244 std::lock_guard<std::mutex> grd(conn->fMutex);
1245 conn->fDoingSend =
false;
1263 for (
auto &conn : arr)
1269 }
while (!only_once);
1300std::string RWebWindow::GetRelativeAddr(
const std::shared_ptr<RWebWindow> &
win)
const
1307 std::string res(
"../");
1308 res.append(
win->GetAddr());
1318std::string RWebWindow::GetRelativeAddr(
const RWebWindow &
win)
const
1325 std::string res(
"../");
1326 res.append(
win.GetAddr());
1387 auto sz =
fConn.size();
1427 return ((num >= 0) && (num < (
int)
fConn.size()) &&
fConn[num]->fActive) ?
fConn[num]->fConnId : 0;
1437 std::vector<unsigned> res;
1445 if (entry.connid != excludeid)
1446 res.emplace_back(entry.connid);
1448 for (
auto & entry :
fConn)
1449 if (entry->fActive && (entry->fConnId != excludeid))
1450 res.emplace_back(entry->fConnId);
1465 for (
auto &conn :
fConn) {
1466 if (connid && (conn->fConnId != connid))
1468 if (conn->fActive || !only_active)
1474 if (!connid || (conn->fConnId == connid))
1513 for (
auto &conn :
fConn) {
1514 if ((conn->fActive || !only_active) && (!connid || (conn->fConnId == connid)))
1515 arr.push_back(conn);
1520 if (!connid || (conn->fConnId == connid))
1521 arr.push_back(conn);
1538 for (
auto &conn : arr) {
1540 std::lock_guard<std::mutex> grd(conn->fMutex);
1542 if (
direct && (!conn->fQueue.empty() || (conn->fSendCredits == 0) || conn->fDoingSend))
1545 if (conn->fQueue.size() >= maxqlen)
1562 std::lock_guard<std::mutex> grd(conn->fMutex);
1563 int len = conn->fQueue.size();
1564 if (
len > maxq) maxq =
len;
1581 auto cnt = lst.size();
1582 for (
auto & entry : lst)
1584 fMaster->SubmitData(entry.connid, txt, std::string(
data), entry.channel);
1586 fMaster->SubmitData(entry.connid, txt, std::move(
data), entry.channel);
1591 auto cnt = arr.size();
1594 bool clear_queue =
false;
1603 for (
auto &conn : arr) {
1609 fname.append(
"msg");
1612 fname.append(
"_ch");
1613 fname.append(std::to_string(chid));
1615 fname.append(txt ?
".txt" :
".bin");
1617 std::ofstream ofs(fname);
1618 ofs.write(
data.c_str(),
data.length());
1630 conn->fSendStamp =
stamp;
1632 std::lock_guard<std::mutex> grd(conn->fMutex);
1635 while (!conn->fQueue.empty())
1639 if (conn->fQueue.size() < maxqlen) {
1641 conn->fQueue.emplace(chid, txt, std::string(
data));
1643 conn->fQueue.emplace(chid, txt, std::move(
data));
1682 std::copy((
const char *)
data, (
const char *)
data +
len, buf.begin());
1683 SubmitData(connid,
false, std::move(buf), 1);
1702 }
else if (
fMgr->IsUseHttpThread()) {
1704 R__LOG_ERROR(
WebGUILog()) <<
"create web window from main thread when THttpServer created with special thread - not supported";
1737 std::thread thrd([
this] {
1839 return fMgr->WaitFor(*
this, check);
1867 return fMgr->WaitFor(*
this, check,
true, duration);
1900 if (arr.size() == 0)
1904 if (arr[0]->fEmbed.find(channel) != arr[0]->fEmbed.end())
1907 arr[0]->fEmbed[channel] = window;
1909 return arr[0]->fConnId;
1919 for (
auto &conn : arr) {
1920 auto iter = conn->fEmbed.find(channel);
1921 if (iter != conn->fEmbed.end())
1922 conn->fEmbed.erase(iter);
1951 std::swap(arr1,
fConn);
1969 if (args.
fMaster && window->fMaster && window->fMaster != args.
fMaster) {
1978 window->RemoveMasterConnection(connid);
1992 return window->Show(args);
2013 return msg.compare(0, 11,
"FILEDIALOG:") == 0;
2040std::string
RWebWindow::HMAC(
const std::string &key,
const std::string &sessionKey,
const char *msg,
int msglen)
2044 auto get_digest = [](
sha256_t &hash,
bool as_hex =
false) -> std::string {
2048 sha256_final(&hash,
reinterpret_cast<unsigned char *
>(digest.data()));
2050 if (!as_hex)
return digest;
2052 static const char* digits =
"0123456789abcdef";
2054 for (
int n = 0;
n < 32;
n++) {
2055 unsigned char code = (
unsigned char) digest[
n];
2056 hex += digits[code / 16];
2057 hex += digits[code % 16];
2064 sha256_init(&hash1);
2065 sha256_update(&hash1, (
const unsigned char *) sessionKey.data(), sessionKey.length());
2066 sha256_update(&hash1, (
const unsigned char *) key.data(), key.length());
2067 std::string kbis = get_digest(hash1);
2071 std::string ki = kbis, ko = kbis;
2072 const int opad = 0x5c;
2073 const int ipad = 0x36;
2074 for (
size_t i = 0; i < kbis.length(); ++i) {
2075 ko[i] = kbis[i] ^ opad;
2076 ki[i] = kbis[i] ^ ipad;
2081 sha256_init(&hash2);
2082 sha256_update(&hash2, (
const unsigned char *) ki.data(), ki.length());
2083 sha256_update(&hash2, (
const unsigned char *) msg, msglen);
2084 std::string m2digest = get_digest(hash2);
2088 sha256_init(&hash3);
2089 sha256_update(&hash3, (
const unsigned char *) ko.data(), ko.length());
2090 sha256_update(&hash3, (
const unsigned char *) m2digest.data(), m2digest.length());
2092 return get_digest(hash3,
true);
#define R__LOG_WARNING(...)
#define R__LOG_ERROR(...)
#define R__LOG_DEBUG(DEBUGLEVEL,...)
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void data
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 stamp
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize id
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 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 win
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t height
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
R__EXTERN TSystem * gSystem
Holds different arguments for starting browser with RWebDisplayHandle::Display() method.
EBrowserKind GetBrowserKind() const
returns configured browser kind, see EBrowserKind for supported values
unsigned fMasterConnection
! used master connection
int fMasterChannel
! used master channel
std::shared_ptr< RWebWindow > fMaster
! master window
@ kEmbedded
window will be embedded into other, no extra browser need to be started
void SetHeadless(bool on=true)
set headless mode
static int GetBoolEnv(const std::string &name, int dfl=-1)
Parse boolean gEnv variable which should be "yes" or "no".
Represents web window, which can be shown in web browser or any other supported environment.
bool CheckDataToSend(std::shared_ptr< WebConn > &conn)
Checks if one should send data for specified connection Returns true when send operation was performe...
int WaitFor(WebWindowWaitFunc_t check)
Waits until provided check function or lambdas returns non-zero value Check function has following si...
unsigned GetId() const
Returns ID for the window - unique inside window manager.
std::vector< MasterConn > GetMasterConnections(unsigned connid=0) const
Get list of master connections.
void AddMasterConnection(std::shared_ptr< RWebWindow > window, unsigned connid, int channel)
Add new master connection If there are many connections - only same master is allowed.
std::mutex fConnMutex
! mutex used to protect connection list
WebWindowDataCallback_t fDataCallback
! main callback when data over channel 1 is arrived
void CheckInactiveConnections()
Check if there are connection which are inactive for longer time For instance, batch browser will be ...
unsigned fId
! unique identifier
bool fHasWindowThrd
! indicate if special window thread was started
std::vector< MasterConn > fMasterConns
! master connections
void SetClearOnClose(const std::shared_ptr< void > &handle=nullptr)
Set handle which is cleared when last active connection is closed Typically can be used to destroy we...
void StartThread()
Start special thread which will be used by the window to handle all callbacks One has to be sure,...
unsigned fConnCnt
! counter of new connections to assign ids
unsigned fProtocolConnId
! connection id, which is used for writing protocol
ConnectionsList_t GetWindowConnections(unsigned connid=0, bool only_active=false) const
returns connection list (or all active connections)
bool fSendMT
! true is special threads should be used for sending data
std::thread::id fCallbacksThrdId
! thread id where callbacks should be invoked
void RemoveKey(const std::string &key)
Removes all connections with the key.
std::queue< QueueEntry > fInputQueue
! input queue for all callbacks
bool _CanTrustIn(std::shared_ptr< WebConn > &conn, const std::string &key, const std::string &ntry, bool remote, bool test_first_time)
Check if provided hash, ntry parameters from the connection request could be accepted.
void SetConnToken(const std::string &token="")
Configures connection token (default none) When specified, in URL of webpage such token should be pro...
unsigned MakeHeadless(bool create_new=false)
Start headless browser for specified window Normally only single instance is used,...
std::string GetUrl(bool remote=true)
Return URL string to connect web window URL typically includes extra parameters required for connecti...
void CloseConnections()
Closes all connection to clients Normally leads to closing of all correspondent browser windows Some ...
std::shared_ptr< RWebWindow > fMaster
! master window where this window is embedded
int NumConnections(bool with_pending=false) const
Returns current number of active clients connections.
bool fCallbacksThrdIdSet
! flag indicating that thread id is assigned
std::string fUserArgs
! arbitrary JSON code, which is accessible via conn.getUserArgs() method
void SetDefaultPage(const std::string &page)
Set content of default window HTML page This page returns when URL address of the window will be requ...
unsigned fConnLimit
! number of allowed active connections
void InvokeCallbacks(bool force=false)
Invoke callbacks with existing data Must be called from appropriate thread.
std::shared_ptr< WebConn > FindConnection(unsigned wsid)
Find connection with specified websocket id.
std::string GetClientVersion() const
Returns current client version.
void SetConnectCallBack(WebWindowConnectCallback_t func)
Set call-back function for new connection.
void Sync()
Special method to process all internal activity when window runs in separate thread.
void UseServerThreads()
Let use THttpServer threads to process requests WARNING!!! only for expert use Should be only used wh...
void TerminateROOT()
Terminate ROOT session Tries to correctly close THttpServer, associated with RWebWindowsManager After...
void Send(unsigned connid, const std::string &data)
Sends data to specified connection.
unsigned Show(const RWebDisplayArgs &args="")
Show window in specified location.
THttpServer * GetServer()
Return THttpServer instance serving requests to the window.
unsigned AddDisplayHandle(bool headless_mode, const std::string &key, std::unique_ptr< RWebDisplayHandle > &handle)
Add display handle and associated key Key is large random string generated when starting new window W...
std::vector< std::shared_ptr< WebConn > > ConnectionsList_t
void AssignThreadId()
Assign thread id which has to be used for callbacks WARNING!!! only for expert use Automatically done...
bool IsNativeOnlyConn() const
returns true if only native (own-created) connections are allowed
void SendBinary(unsigned connid, const void *data, std::size_t len)
Send binary data to specified connection.
static std::shared_ptr< RWebWindow > Create()
Create new RWebWindow Using default RWebWindowsManager.
std::string fClientVersion
! configured client version, used as prefix in scripts URL
bool ProcessBatchHolder(std::shared_ptr< THttpCallArg > &arg)
Process special http request, used to hold headless browser running Such requests should not be repli...
unsigned AddEmbedWindow(std::shared_ptr< RWebWindow > window, unsigned connid, int channel)
Add embed window.
void SetDisconnectCallBack(WebWindowConnectCallback_t func)
Set call-back function for disconnecting.
std::vector< unsigned > GetConnections(unsigned excludeid=0) const
returns vector with all existing connections ids One also can exclude specified connection from retur...
void SetDataCallBack(WebWindowDataCallback_t func)
Set call-back function for data, received from the clients via websocket.
float fOperationTmout
! timeout in seconds to perform synchronous operation, default 50s
bool fRequireAuthKey
! defines if authentication key always required when connect to the widget
static std::function< bool(const std::shared_ptr< RWebWindow > &, unsigned, const std::string &)> gStartDialogFunc
void SetUserArgs(const std::string &args)
Set arbitrary JSON data, which is accessible via conn.getUserArgs() method in JavaScript This JSON co...
std::string fConnToken
! value of "token" URL parameter which should be provided for connecting window
static unsigned ShowWindow(std::shared_ptr< RWebWindow > window, const RWebDisplayArgs &args="")
Static method to show web window Has to be used instead of RWebWindow::Show() when window potentially...
std::shared_ptr< RWebWindowWSHandler > fWSHandler
! specialize websocket handler for all incoming connections
void StopThread()
Stop special thread.
void SubmitData(unsigned connid, bool txt, std::string &&data, int chid=1)
Internal method to send data.
static std::string HMAC(const std::string &key, const std::string &sessionKey, const char *msg, int msglen)
Calculate HMAC checksum for provided key and message Key combained from connection key and session ke...
~RWebWindow()
RWebWindow destructor Closes all connections and remove window from manager.
static bool EmbedFileDialog(const std::shared_ptr< RWebWindow > &window, unsigned connid, const std::string &args)
Create dialog instance to use as embedded dialog inside provided widget Loads libROOTBrowserv7 and tr...
void CloseConnection(unsigned connid)
Close specified connection.
ConnectionsList_t fPendingConn
! list of pending connection with pre-assigned keys
unsigned GetConnectionId(int num=0) const
Returns connection id for specified connection sequence number Only active connections are returned -...
std::string GetConnToken() const
Returns configured connection token.
float GetOperationTmout() const
Returns timeout for synchronous WebWindow operations.
void SetConnLimit(unsigned lmt=0)
Configure maximal number of allowed connections - 0 is unlimited Will not affect already existing con...
void SetPanelName(const std::string &name)
Configure window to show some of existing JSROOT panels It uses "file:rootui5sys/panel/panel....
bool IsRequireAuthKey() const
returns true if authentication string is required
RWebWindow()
RWebWindow constructor Should be defined here because of std::unique_ptr<RWebWindowWSHandler>
std::string fProtocolPrefix
! prefix for created files names
int GetSendQueueLength(unsigned connid) const
Returns send queue length for specified connection.
std::shared_ptr< WebConn > RemoveConnection(unsigned wsid)
Remove connection with given websocket id.
std::shared_ptr< RWebWindowWSHandler > CreateWSHandler(std::shared_ptr< RWebWindowsManager > mgr, unsigned id, double tmout)
Assigns manager reference, window id and creates websocket handler, used for communication with the c...
std::string fProtocol
! protocol
bool CanSend(unsigned connid, bool direct=true) const
Returns true if sending via specified connection can be performed.
std::string GetUserArgs() const
Returns configured user arguments for web window See SetUserArgs method for more details.
void RecordData(const std::string &fname="protocol.json", const std::string &fprefix="")
Configures recording of communication data in protocol file Provided filename will be used to store J...
bool fUseProcessEvents
! all window functionality will run through process events
unsigned GetDisplayConnection() const
Returns first connection id where window is displayed It could be that connection(s) not yet fully es...
unsigned GetConnLimit() const
returns configured connections limit (0 - default)
static void SetStartDialogFunc(std::function< bool(const std::shared_ptr< RWebWindow > &, unsigned, const std::string &)>)
Configure func which has to be used for starting dialog.
std::string fPanelName
! panel name which should be shown in the window
void Run(double tm=0.)
Run window functionality for specified time If no action can be performed - just sleep specified time...
std::string GetAddr() const
Returns window address which is used in URL.
std::shared_ptr< RWebWindowsManager > fMgr
! display manager
std::string fProtocolFileName
! local file where communication protocol will be written
ConnectionsList_t fConn
! list of all accepted connections
WebWindowConnectCallback_t fConnCallback
! callback for connect event
void CheckPendingConnections()
Check if started process(es) establish connection.
std::shared_ptr< void > fClearOnClose
! entry which is cleared when last connection is closed
std::mutex fInputQueueMutex
! mutex to protect input queue
std::string _MakeSendHeader(std::shared_ptr< WebConn > &conn, bool txt, const std::string &data, int chid)
Internal method to prepare text part of send data Should be called under locked connection mutex.
std::chrono::time_point< std::chrono::system_clock > timestamp_t
bool ProcessWS(THttpCallArg &arg)
Processing of websockets call-backs, invoked from RWebWindowWSHandler Method invoked from http server...
bool HasConnection(unsigned connid=0, bool only_active=true) const
returns true if specified connection id exists
std::thread fWindowThrd
! special thread for that window
void ProvideQueueEntry(unsigned connid, EQueueEntryKind kind, std::string &&arg)
Provide data to user callback User callback must be executed in the window thread.
bool HasKey(const std::string &key, bool also_newkey=false) const
Returns true if provided key value already exists (in processes map or in existing connections) In sp...
void CompleteWSSend(unsigned wsid)
Complete websocket send operation Clear "doing send" flag and check if next operation has to be start...
bool fUseServerThreads
! indicates that server thread is using, no special window thread
unsigned FindHeadlessConnection()
Returns connection id of window running in headless mode This can be special connection which may run...
int WaitForTimed(WebWindowWaitFunc_t check)
Waits until provided check function or lambdas returns non-zero value Check function has following si...
bool fProcessMT
! if window event processing performed in dedicated thread
int fProtocolCnt
! counter for protocol recording
void SetClientVersion(const std::string &vers)
Set client version, used as prefix in scripts URL When changed, web browser will reload all related J...
void RemoveMasterConnection(unsigned connid=0)
Remove master connection - if any.
void RemoveEmbedWindow(unsigned connid, int channel)
Remove RWebWindow associated with the channelfEmbed.
_R__DEPRECATED_LATER("Use GetUrl() to get valid connection URL") std _R__DEPRECATED_LATER("Use GetAddr() to get valid connection URL") std void SetCallBacks(WebWindowConnectCallback_t conn, WebWindowDataCallback_t data, WebWindowConnectCallback_t disconn=nullptr)
Set call-backs function for connect, data and disconnect events.
std::string GenerateKey() const
Generate new unique key for the window.
void SetUseCurrentDir(bool on=true)
Configure if window can access local files via currentdir/ path of http server.
WebWindowConnectCallback_t fDisconnCallback
! callback for disconnect event
unsigned GetMaxQueueLength() const
Return maximal queue length of data which can be held by window.
static bool IsFileDialogMessage(const std::string &msg)
Check if this could be the message send by client to start new file dialog If returns true,...
static std::string GenerateKey(int keylen=32)
Static method to generate cryptographic key Parameter keylen defines length of cryptographic key in b...
static bool IsMainThrd()
Returns true when called from main process Main process recognized at the moment when library is load...
static std::shared_ptr< RWebWindowsManager > & Instance()
Returns default window manager Used to display all standard ROOT elements like TCanvas or TFitPanel.
static bool IsLoopbackMode()
Returns true if loopback mode used by THttpServer for web widgets.
Contains arguments for single HTTP call.
UInt_t GetWSId() const
get web-socket id
const char * GetTopName() const
returns engine-specific top-name
const void * GetPostData() const
return pointer on posted with request data
const char * GetQuery() const
returns request query (string after ? in request URL)
Long_t GetPostDataLength() const
return length of posted with request data
Bool_t IsMethod(const char *name) const
returns kTRUE if post method is used
const char * GetFileName() const
returns file name from request URL
Online http server for arbitrary ROOT application.
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
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)
Bool_t HasOption(const char *key) const
Returns true if the given key appears in the URL options list.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
std::function< void(unsigned, const std::string &)> WebWindowDataCallback_t
function signature for call-backs from the window clients first argument is connection id,...
ROOT::Experimental::RLogChannel & WebGUILog()
Log channel for WebGUI diagnostics.
std::function< void(unsigned)> WebWindowConnectCallback_t
function signature for connect/disconnect call-backs argument is connection id
std::function< int(double)> WebWindowWaitFunc_t
function signature for waiting call-backs Such callback used when calling thread need to waits for so...
std::string fData
! text or binary data
std::shared_ptr< THttpCallArg > fHold
! request used to hold headless browser
~WebConn()
Destructor for WebConn Notify special HTTP request which blocks headless browser from exit.