Logo ROOT  
Reference Guide
TCivetweb.cxx
Go to the documentation of this file.
1// Author: Sergey Linev 21/12/2013
2
3/*************************************************************************
4 * Copyright (C) 1995-2022, Rene Brun and Fons Rademakers. *
5 * All rights reserved. *
6 * *
7 * For the licensing terms see $ROOTSYS/LICENSE. *
8 * For the list of contributors see $ROOTSYS/README/CREDITS. *
9 *************************************************************************/
10
11#include "TCivetweb.h"
12
13#include <cstdlib>
14#include <cstring>
15
16#ifdef _MSC_VER
17#include <windows.h>
18#include <tchar.h>
19#endif
20
21#include "THttpServer.h"
22#include "THttpWSEngine.h"
23#include "TUrl.h"
24
25//////////////////////////////////////////////////////////////////////////
26/// TCivetwebWSEngine
27///
28/// Implementation of THttpWSEngine for Civetweb
29
31protected:
33
34 /// True websocket requires extra thread to parallelize sending
35 Bool_t SupportSendThrd() const override { return kTRUE; }
36
37public:
39
40 virtual ~TCivetwebWSEngine() = default;
41
42 UInt_t GetId() const override { return TString::Hash((void *)&fWSconn, sizeof(void *)); }
43
44 void ClearHandle(Bool_t terminate) override
45 {
46 if (fWSconn && terminate)
48 fWSconn = nullptr;
49 }
50
51 void Send(const void *buf, int len) override
52 {
53 if (fWSconn)
55 }
56
57 /////////////////////////////////////////////////////////
58 /// Special method to send binary data with text header
59 /// For normal websocket it is two separated operation, for other engines could be combined together,
60 /// but emulates as two messages on client side
61 void SendHeader(const char *hdr, const void *buf, int len) override
62 {
63 if (fWSconn) {
66 }
67 }
68
69 void SendCharStar(const char *str) override
70 {
71 if (fWSconn)
73 }
74};
75
76//////////////////////////////////////////////////////////////////////////
77
78int websocket_connect_handler(const struct mg_connection *conn, void *)
79{
80 const struct mg_request_info *request_info = mg_get_request_info(conn);
81 if (!request_info)
82 return 1;
83
84 TCivetweb *engine = (TCivetweb *)request_info->user_data;
85 if (!engine || engine->IsTerminating())
86 return 1;
87 THttpServer *serv = engine->GetServer();
88 if (!serv)
89 return 1;
90
91 auto arg = std::make_shared<THttpCallArg>();
92 arg->SetPathAndFileName(request_info->local_uri); // path and file name
93 arg->SetQuery(request_info->query_string); // query arguments
94 arg->SetWSId(TString::Hash((void *)&conn, sizeof(void *)));
95 arg->SetMethod("WS_CONNECT");
96
97 Bool_t execres = serv->ExecuteWS(arg, kTRUE, kTRUE);
98
99 return execres && !arg->Is404() ? 0 : 1;
100}
101
102//////////////////////////////////////////////////////////////////////////
103
104void websocket_ready_handler(struct mg_connection *conn, void *)
105{
106 const struct mg_request_info *request_info = mg_get_request_info(conn);
107
108 TCivetweb *engine = (TCivetweb *)request_info->user_data;
109 if (!engine || engine->IsTerminating())
110 return;
111 THttpServer *serv = engine->GetServer();
112 if (!serv)
113 return;
114
115 auto arg = std::make_shared<THttpCallArg>();
116 arg->SetPathAndFileName(request_info->local_uri); // path and file name
117 arg->SetQuery(request_info->query_string); // query arguments
118 arg->SetMethod("WS_READY");
119
120 // delegate ownership to the arg, id will be automatically set
121 arg->CreateWSEngine<TCivetwebWSEngine>(conn);
122
123 serv->ExecuteWS(arg, kTRUE, kTRUE);
124}
125
126
127//////////////////////////////////////////////////////////////////////////
128
129void websocket_close_handler(const struct mg_connection *conn, void *)
130{
131 const struct mg_request_info *request_info = mg_get_request_info(conn);
132
133 // check if connection was already closed
134 if (mg_get_user_connection_data(conn) == (void *) conn)
135 return;
136
137 TCivetweb *engine = (TCivetweb *)request_info->user_data;
138 if (!engine || engine->IsTerminating())
139 return;
140 THttpServer *serv = engine->GetServer();
141 if (!serv)
142 return;
143
144 auto arg = std::make_shared<THttpCallArg>();
145 arg->SetPathAndFileName(request_info->local_uri); // path and file name
146 arg->SetQuery(request_info->query_string); // query arguments
147 arg->SetWSId(TString::Hash((void *)&conn, sizeof(void *)));
148 arg->SetMethod("WS_CLOSE");
149
150 serv->ExecuteWS(arg, kTRUE, kFALSE); // do not wait for result of execution
151}
152
153//////////////////////////////////////////////////////////////////////////
154
155int websocket_data_handler(struct mg_connection *conn, int code, char *data, size_t len, void *)
156{
157 const struct mg_request_info *request_info = mg_get_request_info(conn);
158
159 // check if connection data set to connection itself - means connection was closed already
160 std::string *conn_data = (std::string *) mg_get_user_connection_data(conn);
161 if ((void *) conn_data == (void *) conn)
162 return 1;
163
164 // see https://datatracker.ietf.org/doc/html/rfc6455#section-5.2
165 int fin = code & 0x80, opcode = code & 0x0F;
166
167 // recognized operation codes, all other should fails
168 enum { OP_CONTINUE = 0, OP_TEXT = 1, OP_BINARY = 2, OP_CLOSE = 8 };
169
170 // close when normal close is detected
171 if (fin && (opcode == OP_CLOSE)) {
172 if (conn_data) delete conn_data;
173 websocket_close_handler(conn, nullptr);
174 mg_set_user_connection_data(conn, conn); // mark connection as closed
175 return 1;
176 }
177
178 // ignore empty data
179 if (len == 0)
180 return 1;
181
182 // close connection when unrecognized opcode is detected
183 if ((opcode != OP_CONTINUE) && (opcode != OP_TEXT) && (opcode != OP_BINARY)) {
184 if (conn_data) delete conn_data;
185 websocket_close_handler(conn, nullptr);
186 mg_set_user_connection_data(conn, conn); // mark connection as closed
187 return 1;
188 }
189
190 TCivetweb *engine = (TCivetweb *)request_info->user_data;
191 if (!engine || engine->IsTerminating())
192 return 1;
193 THttpServer *serv = engine->GetServer();
194 if (!serv)
195 return 1;
196
197 // this is continuation of the request
198 if (!fin) {
199 if (!conn_data) {
200 conn_data = new std::string(data,len);
202 } else {
203 conn_data->append(data,len);
204 }
205 return 1;
206 }
207
208 auto arg = std::make_shared<THttpCallArg>();
209 arg->SetPathAndFileName(request_info->local_uri); // path and file name
210 arg->SetQuery(request_info->query_string); // query arguments
211 arg->SetWSId(TString::Hash((void *)&conn, sizeof(void *)));
212 arg->SetMethod("WS_DATA");
213
214 if (conn_data) {
215 mg_set_user_connection_data(conn, nullptr);
216 conn_data->append(data,len);
217 arg->SetPostData(std::move(*conn_data));
218 delete conn_data;
219 } else {
220 arg->SetPostData(std::string(data,len));
221 }
222
223 serv->ExecuteWS(arg, kTRUE, kTRUE);
224
225 return 1;
226}
227
228
229//////////////////////////////////////////////////////////////////////////
230
231static int log_message_handler(const struct mg_connection *conn, const char *message)
232{
233 const struct mg_context *ctx = mg_get_context(conn);
234
235 TCivetweb *engine = (TCivetweb *)mg_get_user_data(ctx);
236
237 if (engine)
238 return engine->ProcessLog(message);
239
240 // provide debug output
241 if ((gDebug > 0) || (strstr(message, "cannot bind to") != 0))
242 fprintf(stderr, "Error in <TCivetweb::Log> %s\n", message);
243
244 return 0;
245}
246
247//////////////////////////////////////////////////////////////////////////
248
249static int begin_request_handler(struct mg_connection *conn, void *)
250{
251 const struct mg_request_info *request_info = mg_get_request_info(conn);
252
253 TCivetweb *engine = (TCivetweb *)request_info->user_data;
254 if (!engine || engine->IsTerminating())
255 return 0;
256 THttpServer *serv = engine->GetServer();
257 if (!serv)
258 return 0;
259
260 auto arg = std::make_shared<THttpCallArg>();
261
263
264 Bool_t execres = kTRUE, debug = engine->IsDebugMode();
265
266 if (!debug && serv->IsFileRequested(request_info->local_uri, filename)) {
267 if ((filename.Length() > 3) && ((filename.Index(".js") != kNPOS) || (filename.Index(".css") != kNPOS))) {
268 std::string buf = THttpServer::ReadFileContent(filename.Data());
269 if (buf.empty()) {
270 arg->Set404();
271 } else {
272 arg->SetContentType(THttpServer::GetMimeType(filename.Data()));
273 arg->SetContent(std::move(buf));
274 if (engine->GetMaxAge() > 0)
275 arg->AddHeader("Cache-Control", TString::Format("max-age=%d", engine->GetMaxAge()));
276 else
277 arg->AddNoCacheHeader();
278 arg->SetZipping();
279 }
280 } else {
281 arg->SetFile(filename.Data());
282 }
283 } else {
284 arg->SetPathAndFileName(request_info->local_uri); // path and file name
285 arg->SetQuery(request_info->query_string); // query arguments
286 arg->SetTopName(engine->GetTopName());
287 arg->SetMethod(request_info->request_method); // method like GET or POST
288 if (request_info->remote_user)
289 arg->SetUserName(request_info->remote_user);
290
291 TString header;
292 for (int n = 0; n < request_info->num_headers; n++)
293 header.Append(
294 TString::Format("%s: %s\r\n", request_info->http_headers[n].name, request_info->http_headers[n].value));
295 arg->SetRequestHeader(header);
296
297 const char *len = mg_get_header(conn, "Content-Length");
298 Int_t ilen = len ? TString(len).Atoi() : 0;
299
300 if (ilen > 0) {
301 std::string buf;
302 buf.resize(ilen);
303 Int_t iread = mg_read(conn, (void *) buf.data(), ilen);
304 if (iread == ilen)
305 arg->SetPostData(std::move(buf));
306 }
307
308 if (debug) {
309 TString cont;
310 cont.Append("<title>Civetweb echo</title>");
311 cont.Append("<h1>Civetweb echo</h1>\n");
312
313 static int count = 0;
314
315 cont.Append(TString::Format("Request %d:<br/>\n<pre>\n", ++count));
316 cont.Append(TString::Format(" Method : %s\n", arg->GetMethod()));
317 cont.Append(TString::Format(" PathName : %s\n", arg->GetPathName()));
318 cont.Append(TString::Format(" FileName : %s\n", arg->GetFileName()));
319 cont.Append(TString::Format(" Query : %s\n", arg->GetQuery()));
320 cont.Append(TString::Format(" PostData : %ld\n", arg->GetPostDataLength()));
321 if (arg->GetUserName())
322 cont.Append(TString::Format(" User : %s\n", arg->GetUserName()));
323
324 cont.Append("</pre><p>\n");
325
326 cont.Append("Environment:<br/>\n<pre>\n");
327 for (int n = 0; n < request_info->num_headers; n++)
328 cont.Append(
329 TString::Format(" %s = %s\n", request_info->http_headers[n].name, request_info->http_headers[n].value));
330 cont.Append("</pre><p>\n");
331
332 arg->SetContentType("text/html");
333
334 arg->SetContent(cont);
335
336 } else {
337 execres = serv->ExecuteHttp(arg);
338 }
339 }
340
341 if (!execres || arg->Is404()) {
342 std::string hdr = arg->FillHttpHeader("HTTP/1.1");
343 mg_printf(conn, "%s", hdr.c_str());
344 } else if (arg->IsFile()) {
345 filename = (const char *)arg->GetContent();
346#ifdef _MSC_VER
347 if (engine->IsWinSymLinks()) {
348 // resolve Windows links which are not supported by civetweb
349 auto hFile = CreateFile(filename.Data(), // file to open
350 GENERIC_READ, // open for reading
351 FILE_SHARE_READ, // share for reading
352 NULL, // default security
353 OPEN_EXISTING, // existing file only
354 FILE_ATTRIBUTE_NORMAL, // normal file
355 NULL); // no attr. template
356
357 if( hFile != INVALID_HANDLE_VALUE) {
358 const int BUFSIZE = 2048;
359 TCHAR Path[BUFSIZE];
360 auto dwRet = GetFinalPathNameByHandle( hFile, Path, BUFSIZE, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS );
361 // produced file name may include \\?\ symbols, which are indicating long file name
362 if(dwRet < BUFSIZE) {
363 if (dwRet > 4 && Path[0] == '\\' && Path[1] == '\\' && Path[2] == '?' && Path[3] == '\\')
364 filename = Path + 4;
365 else
366 filename = Path;
367 }
368 CloseHandle(hFile);
369 }
370 }
371#endif
372 const char *mime_type = THttpServer::GetMimeType(filename.Data());
373 if (mime_type)
374 mg_send_mime_file(conn, filename.Data(), mime_type);
375 else
376 mg_send_file(conn, filename.Data());
377 } else {
378
379 Bool_t dozip = kFALSE;
380 switch (arg->GetZipping()) {
381 case THttpCallArg::kNoZip: dozip = kFALSE; break;
383 if (arg->GetContentLength() < 10000) break;
385 // check if request header has Accept-Encoding
386 for (int n = 0; n < request_info->num_headers; n++) {
387 TString name = request_info->http_headers[n].name;
388 if (name.Index("Accept-Encoding", 0, TString::kIgnoreCase) != 0)
389 continue;
390 TString value = request_info->http_headers[n].value;
391 dozip = (value.Index("gzip", 0, TString::kIgnoreCase) != kNPOS);
392 break;
393 }
394
395 break;
396 case THttpCallArg::kZipAlways: dozip = kTRUE; break;
397 }
398
399 if (dozip)
400 arg->CompressWithGzip();
401
402 std::string hdr = arg->FillHttpHeader("HTTP/1.1");
403 mg_printf(conn, "%s", hdr.c_str());
404
405 if (arg->GetContentLength() > 0)
406 mg_write(conn, arg->GetContent(), (size_t)arg->GetContentLength());
407 }
408
409 // Returning non-zero tells civetweb that our function has replied to
410 // the client, and civetweb should not send client any more data.
411 return 1;
412}
413
414//////////////////////////////////////////////////////////////////////////
415///
416/// TCivetweb
417///
418/// http server implementation, based on civetweb embedded server
419/// It is default kind of engine, created for THttpServer
420/// Currently v1.15 from https://github.com/civetweb/civetweb is used
421///
422/// Additional options can be specified:
423///
424/// top=foldername - name of top folder, seen in the browser
425/// thrds=N - use N threads to run civetweb server (default 5)
426/// auth_file - global authentication file
427/// auth_domain - domain name, used for authentication
428///
429/// Example:
430///
431/// new THttpServer("http:8080?top=MyApp&thrds=3");
432///
433/// For the full list of supported options see TCivetweb::Create() documentation
434///
435/// When `auth_file` and `auth_domain` parameters are specified, access
436/// to running http server will be possible only after user
437/// authentication, using so-call digest method. To generate
438/// authentication file, htdigest routine should be used:
439///
440/// [shell] htdigest -c .htdigest domain_name user
441///
442/// When creating server, parameters should be:
443///
444/// new THttpServer("http:8080?auth_file=.htdigets&auth_domain=domain_name");
445
446////////////////////////////////////////////////////////////////////////////////
447/// constructor
448
450 : THttpEngine("civetweb", "compact embedded http server"),
451 fOnlySecured(only_secured)
452{
453}
454
455////////////////////////////////////////////////////////////////////////////////
456/// destructor
457
459{
460 if (fCtx && !fTerminating)
461 mg_stop(fCtx);
462}
463
464////////////////////////////////////////////////////////////////////////////////
465/// process civetweb log message, can be used to detect critical errors
466
467Int_t TCivetweb::ProcessLog(const char *message)
468{
469 if ((gDebug > 0) || (strstr(message, "cannot bind to") != 0))
470 Error("Log", "%s", message);
471
472 return 0;
473}
474
475////////////////////////////////////////////////////////////////////////////////
476/// Creates embedded civetweb server
477///
478/// \param args string with civetweb server configuration
479///
480/// As main argument, http port should be specified like "8090".
481/// Or one can provide combination of ipaddress and portnumber like 127.0.0.1:8090
482/// Extra parameters like in URL string could be specified after '?' mark:
483///
484/// thrds=N - there N is number of threads used by the civetweb (default is 10)
485/// top=name - configure top name, visible in the web browser
486/// ssl_certificate=filename - SSL certificate, see docs/OpenSSL.md from civetweb
487/// auth_file=filename - authentication file name, created with htdigets utility
488/// auth_domain=domain - authentication domain
489/// websocket_timeout=tm - set web sockets timeout in seconds (default 300)
490/// websocket_disable - disable web sockets handling (default enabled)
491/// bind - ip address to bind server socket
492/// loopback - bind specified port to loopback 127.0.0.1 address
493/// debug - enable debug mode, server always returns html page with request info
494/// log=filename - configure civetweb log file
495/// max_age=value - configures "Cache-Control: max_age=value" http header for all file-related requests, default 3600
496/// nocache - try to fully disable cache control for file requests
497/// winsymlinks=no - do not resolve symbolic links on file system (Windows only), default true
498/// dirlisting=no - enable/disable directory listing for browsing filesystem (default no)
499///
500/// Examples of valid args values:
501///
502/// http:8080?websocket_disable
503/// http:7546?thrds=30&websocket_timeout=20
504
505Bool_t TCivetweb::Create(const char *args)
506{
507 memset(&fCallbacks, 0, sizeof(struct mg_callbacks));
508 // fCallbacks.begin_request = begin_request_handler;
510 TString sport = IsSecured() ? "8480s" : "8080",
511 num_threads = "10",
512 websocket_timeout = "300000",
513 dir_listening = "no",
514 auth_file,
515 auth_domain,
516 log_file,
517 ssl_cert,
518 max_age;
519 Bool_t use_ws = kTRUE;
520
521 // extract arguments
522 if (args && (strlen(args) > 0)) {
523
524 // first extract port number
525 sport = "";
526 while ((*args != 0) && (*args != '?') && (*args != '/'))
527 sport.Append(*args++);
528 if (IsSecured() && (sport.Index("s")==kNPOS)) sport.Append("s");
529
530 // than search for extra parameters
531 while ((*args != 0) && (*args != '?'))
532 args++;
533
534 if (*args == '?') {
535 TUrl url(TString::Format("http://localhost/folder%s", args));
536
537 if (url.IsValid()) {
538 url.ParseOptions();
539
540 const char *top = url.GetValueFromOptions("top");
541 if (top)
542 fTopName = top;
543
544 const char *log = url.GetValueFromOptions("log");
545 if (log)
546 log_file = log;
547
548 Int_t thrds = url.GetIntValueFromOptions("thrds");
549 if (thrds > 0)
550 num_threads.Form("%d", thrds);
551
552 const char *afile = url.GetValueFromOptions("auth_file");
553 if (afile)
554 auth_file = afile;
555
556 const char *adomain = url.GetValueFromOptions("auth_domain");
557 if (adomain)
558 auth_domain = adomain;
559
560 const char *sslc = url.GetValueFromOptions("ssl_cert");
561 if (sslc)
562 ssl_cert = sslc;
563
564 Int_t wtmout = url.GetIntValueFromOptions("websocket_timeout");
565 if (wtmout > 0) {
566 websocket_timeout.Format("%d", wtmout * 1000);
567 use_ws = kTRUE;
568 }
569
570 if (url.HasOption("websocket_disable"))
571 use_ws = kFALSE;
572
573 if (url.HasOption("debug"))
574 fDebug = kTRUE;
575
576 const char *winsymlinks = url.GetValueFromOptions("winsymlinks");
577 if (winsymlinks)
578 fWinSymLinks = strcmp(winsymlinks,"no") != 0;
579
580 const char *dls = url.GetValueFromOptions("dirlisting");
581 if (dls && (!strcmp(dls,"no") || !strcmp(dls,"yes")))
582 dir_listening = dls;
583
584 if (url.HasOption("loopback") && (sport.Index(":") == kNPOS))
585 sport = TString("127.0.0.1:") + sport;
586
587 if (url.HasOption("bind") && (sport.Index(":") == kNPOS)) {
588 const char *addr = url.GetValueFromOptions("bind");
589 if (addr && strlen(addr))
590 sport = TString(addr) + ":" + sport;
591 }
592
593 if (GetServer() && url.HasOption("cors")) {
594 const char *cors = url.GetValueFromOptions("cors");
595 GetServer()->SetCors(cors && *cors ? cors : "*");
596 }
597
598 if (url.HasOption("nocache"))
599 fMaxAge = 0;
600
601 if (url.HasOption("max_age"))
602 fMaxAge = url.GetIntValueFromOptions("max_age");
603
604 max_age.Form("%d", fMaxAge);
605 }
606 }
607 }
608
609 const char *options[25];
610 int op(0);
611
612 Info("Create", "Starting HTTP server on port %s", sport.Data());
613
614 options[op++] = "listening_ports";
615 options[op++] = sport.Data();
616 options[op++] = "num_threads";
617 options[op++] = num_threads.Data();
618
619 if (use_ws) {
620 options[op++] = "websocket_timeout_ms";
621 options[op++] = websocket_timeout.Data();
622 }
623
624 if ((auth_file.Length() > 0) && (auth_domain.Length() > 0)) {
625 options[op++] = "global_auth_file";
626 options[op++] = auth_file.Data();
627 options[op++] = "authentication_domain";
628 options[op++] = auth_domain.Data();
629 } else {
630 options[op++] = "enable_auth_domain_check";
631 options[op++] = "no";
632 }
633
634 if (log_file.Length() > 0) {
635 options[op++] = "error_log_file";
636 options[op++] = log_file.Data();
637 }
638
639 if (ssl_cert.Length() > 0) {
640 options[op++] = "ssl_certificate";
641 options[op++] = ssl_cert.Data();
642 } else if (IsSecured()) {
643 Error("Create", "No SSL certificate file configured");
644 }
645
646 if (max_age.Length() > 0) {
647 options[op++] = "static_file_max_age";
648 options[op++] = max_age.Data();
649 }
650
651 options[op++] = "enable_directory_listing";
652 options[op++] = dir_listening.Data();
653
654 options[op++] = nullptr;
655
656 // Start the web server.
657 fCtx = mg_start(&fCallbacks, this, options);
658
659 if (!fCtx)
660 return kFALSE;
661
663
664 if (use_ws)
667
668 return kTRUE;
669}
bool Bool_t
Definition: RtypesCore.h:63
const Ssiz_t kNPOS
Definition: RtypesCore.h:124
int Int_t
Definition: RtypesCore.h:45
const Bool_t kFALSE
Definition: RtypesCore.h:101
const Bool_t kTRUE
Definition: RtypesCore.h:100
int websocket_connect_handler(const struct mg_connection *conn, void *)
Definition: TCivetweb.cxx:78
static int begin_request_handler(struct mg_connection *conn, void *)
Definition: TCivetweb.cxx:249
static int log_message_handler(const struct mg_connection *conn, const char *message)
Definition: TCivetweb.cxx:231
int websocket_data_handler(struct mg_connection *conn, int code, char *data, size_t len, void *)
Definition: TCivetweb.cxx:155
void websocket_close_handler(const struct mg_connection *conn, void *)
Definition: TCivetweb.cxx:129
void websocket_ready_handler(struct mg_connection *conn, void *)
Definition: TCivetweb.cxx:104
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 filename
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
char name[80]
Definition: TGX11.cxx:110
#define INVALID_HANDLE_VALUE
Definition: TMapFile.cxx:84
Int_t gDebug
Definition: TROOT.cxx:585
#define BUFSIZE
const char * mime_type
Definition: civetweb.c:8026
int mg_printf(struct mg_connection *conn, const char *fmt,...)
Definition: civetweb.c:6935
void mg_send_file(struct mg_connection *conn, const char *path)
Definition: civetweb.c:10192
struct mg_context * mg_start(const struct mg_callbacks *callbacks, void *user_data, const char **options)
Definition: civetweb.c:20242
void mg_set_websocket_handler(struct mg_context *ctx, const char *uri, mg_websocket_connect_handler connect_handler, mg_websocket_ready_handler ready_handler, mg_websocket_data_handler data_handler, mg_websocket_close_handler close_handler, void *cbdata)
Definition: civetweb.c:13762
void mg_send_mime_file(struct mg_connection *conn, const char *path, const char *mime_type)
Definition: civetweb.c:10199
const char * mg_get_header(const struct mg_connection *conn, const char *name)
Definition: civetweb.c:3800
int mg_write(struct mg_connection *conn, const void *buf, size_t len)
Definition: civetweb.c:6694
const struct mg_request_info * mg_get_request_info(const struct mg_connection *conn)
Definition: civetweb.c:3486
void mg_set_user_connection_data(const struct mg_connection *const_conn, void *data)
Definition: civetweb.c:3188
void * mg_get_user_connection_data(const struct mg_connection *conn)
Definition: civetweb.c:3201
int mg_read(struct mg_connection *conn, void *buf, size_t len)
Definition: civetweb.c:6586
void mg_set_request_handler(struct mg_context *ctx, const char *uri, mg_request_handler handler, void *cbdata)
Definition: civetweb.c:13740
struct mg_context * mg_get_context(const struct mg_connection *conn)
Definition: civetweb.c:3151
void mg_stop(struct mg_context *ctx)
Definition: civetweb.c:19451
void * mg_get_user_data(const struct mg_context *ctx)
Definition: civetweb.c:3158
int mg_websocket_write(struct mg_connection *conn, int opcode, const char *data, size_t data_len)
@ MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE
Definition: civetweb.h:861
@ MG_WEBSOCKET_OPCODE_BINARY
Definition: civetweb.h:860
@ MG_WEBSOCKET_OPCODE_TEXT
Definition: civetweb.h:859
TCivetwebWSEngine.
Definition: TCivetweb.cxx:30
struct mg_connection * fWSconn
Definition: TCivetweb.cxx:32
UInt_t GetId() const override
Definition: TCivetweb.cxx:42
void SendCharStar(const char *str) override
Envelope for sending string via the websocket.
Definition: TCivetweb.cxx:69
void ClearHandle(Bool_t terminate) override
Definition: TCivetweb.cxx:44
Bool_t SupportSendThrd() const override
True websocket requires extra thread to parallelize sending.
Definition: TCivetweb.cxx:35
void SendHeader(const char *hdr, const void *buf, int len) override
Special method to send binary data with text header For normal websocket it is two separated operatio...
Definition: TCivetweb.cxx:61
void Send(const void *buf, int len) override
Definition: TCivetweb.cxx:51
virtual ~TCivetwebWSEngine()=default
TCivetwebWSEngine(struct mg_connection *conn)
Definition: TCivetweb.cxx:38
struct mg_context * fCtx
! civetweb context
Definition: TCivetweb.h:21
Bool_t fWinSymLinks
! resolve symbolic links on Windows
Definition: TCivetweb.h:28
Bool_t IsTerminating() const
Definition: TCivetweb.h:44
Int_t GetMaxAge() const
Definition: TCivetweb.h:50
const char * GetTopName() const
Definition: TCivetweb.h:40
TCivetweb(Bool_t only_secured=kFALSE)
TCivetweb.
Definition: TCivetweb.cxx:449
Int_t fMaxAge
! max-age parameter
Definition: TCivetweb.h:27
Int_t ProcessLog(const char *message)
process civetweb log message, can be used to detect critical errors
Definition: TCivetweb.cxx:467
TString fTopName
! name of top item
Definition: TCivetweb.h:23
Bool_t fTerminating
! server doing shutdown and not react on requests
Definition: TCivetweb.h:25
Bool_t Create(const char *args) override
Creates embedded civetweb server.
Definition: TCivetweb.cxx:505
Bool_t IsSecured() const
Definition: TCivetweb.h:32
Bool_t IsDebugMode() const
Definition: TCivetweb.h:42
virtual ~TCivetweb()
destructor
Definition: TCivetweb.cxx:458
Bool_t IsWinSymLinks() const
Definition: TCivetweb.h:46
Bool_t fDebug
! debug mode
Definition: TCivetweb.h:24
struct mg_callbacks fCallbacks
! call-back table for civetweb webserver
Definition: TCivetweb.h:22
THttpServer * GetServer() const
Returns pointer to THttpServer associated with engine.
Definition: THttpEngine.h:40
Bool_t IsFileRequested(const char *uri, TString &res) const
Check if file is requested, thread safe.
Bool_t ExecuteWS(std::shared_ptr< THttpCallArg > &arg, Bool_t external_thrd=kFALSE, Bool_t wait_process=kFALSE)
Execute WS request.
Bool_t ExecuteHttp(std::shared_ptr< THttpCallArg > arg)
Execute HTTP request.
void SetCors(const std::string &domain="*")
Enable CORS header to ProcessRequests() responses Specified location (typically "*") add as "Access-C...
Definition: THttpServer.h:107
static char * ReadFileContent(const char *filename, Int_t &len)
Reads content of file from the disk.
static const char * GetMimeType(const char *path)
Guess mime type base on file extension.
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:893
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:867
Basic string class.
Definition: TString.h:136
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1946
const char * Data() const
Definition: TString.h:369
@ kIgnoreCase
Definition: TString.h:268
UInt_t Hash(ECaseCompare cmp=kExact) const
Return hash value.
Definition: TString.cxx:662
TString & Append(const char *cs)
Definition: TString.h:564
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition: TString.cxx:2336
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:639
This class represents a WWW compatible URL.
Definition: TUrl.h:33
const char * GetValueFromOptions(const char *key) const
Return a value for a given key from the URL options.
Definition: TUrl.cxx:659
Bool_t IsValid() const
Definition: TUrl.h:79
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.
Definition: TUrl.cxx:671
void ParseOptions() const
Parse URL options into a key/value map.
Definition: TUrl.cxx:625
Bool_t HasOption(const char *key) const
Returns true if the given key appears in the URL options list.
Definition: TUrl.cxx:682
RVec< PromoteType< T > > log(const RVec< T > &v)
Definition: RVec.hxx:1748
const Int_t n
Definition: legend1.C:16
int(* log_message)(const struct mg_connection *, const char *message)
Definition: civetweb.h:240
char * buf
Definition: civetweb.c:2494
const char * value
Definition: civetweb.h:145
const char * name
Definition: civetweb.h:144
struct mg_header http_headers[(64)]
Definition: civetweb.h:179
const char * local_uri
Definition: civetweb.h:157
void * user_data
Definition: civetweb.h:175
const char * request_method
Definition: civetweb.h:151
const char * query_string
Definition: civetweb.h:162
void * conn_data
Definition: civetweb.h:176
const char * remote_user
Definition: civetweb.h:164