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